지난 포스팅에서는 RV32I를 하드웨어와 소프트웨어라는 두 가지 관점에서 분류해 보았습니다. 이전 내용이 궁금하시다면 아래 글을 참고해주세요.
https://idkihg.tistory.com/143
[RISC-V] RV32I ISA
RV32I ISA(Instruction Set Architecture)는 최소한의 명령어로 모든 계산을 수행한다는 RISC-V의 철학을 보여줍니다. 전체 명령어는 총 47개 뿐이며, 모든 명령어 길이는 32비트로 고정되어 있습니다. 1. 하드
idkihg.tistory.com
2) ISA Loads & Stores
https://idkihg.tistory.com/147
[RISC-V] RV32I ISA - Loads & Stores
지난 포스팅에서는 RV32I를 하드웨어와 소프트웨어라는 두 가지 관점에서 분류해 보았습니다. 이전 내용이 궁금하시다면 아래 글을 참고해주세요.https://idkihg.tistory.com/143 [RISC-V] RV32I ISARV32I ISA(Inst
idkihg.tistory.com
3) ISA Control Transfer
[RISC-V] RV32I ISA - Control Transfer
지난 포스팅에서는 RV32I를 하드웨어와 소프트웨어라는 두 가지 관점에서 분류해 보았습니다. 이전 내용이 궁금하시다면 아래 글을 참고해주세요.https://idkihg.tistory.com/143 [RISC-V] RV32I ISARV32I ISA(Inst
idkihg.tistory.com
4) ISA Miscellaneous Instructions
https://idkihg.tistory.com/149
[RISC-V] RV32I ISA - Miscellaneous Instructions
지난 포스팅에서는 RV32I를 하드웨어와 소프트웨어라는 두 가지 관점에서 분류해 보았습니다. 이전 내용이 궁금하시다면 아래 글을 참고해주세요. 아울러 소프트웨어적 분류를 바탕으로 연재 중
idkihg.tistory.com
이번 글에서는 CPU의 두뇌인 ALU가 실제로 데이터를 처리하는 핵심, Computation 명령어들을 하나씩 파헤쳐 보겠습니다.
1. Computation 연산의 분류
RV32I의 연산 명령어는 데이터(Operand)를 어디서 가져오느냐에 따라 크게 세 가지 타입으로 나뉩니다. 32비트라는 한정된 공간 안에 정보를 효율적으로 담기 위한 RISC-V의 설계 철학이 돋보이는 부분입니다.

✔ R-type (Register-Register): 두 개의 소스 레지스터(rs1, rs2) 값을 연산하여 목적지 레지스터(rd)에 저장합니다.
- add, sub, and, or, xor, sll, srl, sra, slt, sltu
✔ I-type (Register-Immediate): 레지스터 하나와 명령어에 포함된 12비트 상수(Immediate)를 연산합니다.
- addi, andi, ori, xori, slli, srli, srai, slti, sltiu
✔ U-type (Upper Immediate): 32비트 전체 값을 다루기 위해 상위 20비트를 처리하는 특수 명령어입니다.
- lui, auipc
2. 산술 연산 명령어 (Arithmetic)
산술 연산은 가장 기본이 되는 더하기와 빼기입니다. 하드웨어 설계를 단순하게 유지하기 위해 RV32I는 오버플로우(Overflow)를 하드웨어적으로 트랩하지 않고 소프트웨어가 판단하도록 맡깁니다. 종류는 add, sub, addi 총 3가지 입니다. 아래는 산술 연산 명령어의 하드웨어 비트 필드 구조입니다.

- add rd, rs1, rs2 => x[rd] = x[rs1] + x[rs2]
- sub* rd, rs1, rs2 => x[rd] = x[rs1] - x[rs2]
- addi rd, rs1, imm[11:0] => x[rd] = x[rs1] + imm[11:0]
*subi가 없는 이유는 addi에 음수 상수를 넣으면 뺄셈이 되기 때문입니다.
3. 논리연산 명령어(Logical)
논리 연산은 비트 단위(Bitwise)로 데이터를 가공할 때 사용합니다. 특정 비트를 추출하거나, 0 또는 1로 세팅할 때 필수적입니다. 종류는 and, or, xor, andi, ori, xori 총 6가지 입니다. 아래는 논리 연산 명령어의 하드웨어 비트 필드 구조입니다.

- and rd, rs1, rs2 => x[rd] = x[rs1] & x[rs2]
- or rd, rs1, rs2 => x[rd] = x[rs1] | x[rs2]
- xor rd, rs1, rs2 => x[rd] = x[rs1] ^ x[rs2]
- andi rd, rs1, imm[11:0] => x[rd] = x[rs1] & sign-extended(imm[11:0])**
- ori rd, rs1, imm[11:0] => x[rd] = x[rs1] | sign-extended(imm[11:0])
- xori rd, rs1, imm[11:0] => x[rd] = x[rs1] ^ sign-extended(imm[11:0])
**I-Type 논리 연산의 경우 sign-extended를 반영하여 연산이 이루어집니다.
ex1) 양수 확장
rs1 = 0x1234_5678, imm[11:0] 0x00F
- andi rd, rs1, imm[11:0]
=> rd = 0x1234_5678 & 0x0000_000F
=> rd = 0x0000_0008
ex2) 음수 확장
rs1 = 0x1234_5678, imm[11:0] 0xFFF
- andi rd, rs1, imm[11:0]
=> rd = 0x1234_5678 & 0xFFFF_FFFF
=> rd = 0x1234_5678
4. 이동 연산 명령어(Shift)
Shift 연산은 비트를 왼쪽이나 오른쪽으로 밀어내는 연산입니다. RV32I에서는 논리 이동(Logical)과 산술 이동(Arithmetic)을 모두 지원합니다.
- sll / slli (Shift Left Logical): 비트를 왼쪽으로 밀고, 빈 자리는 0으로 채웁니다.
- srl / srli (Shift Right Logical): 비트를 오른쪽으로 밀고, 빈 자리는 0으로 채웁니다.
- sra / srai (Shift Right Arithmetic): 비트를 오른쪽으로 밀되, 최상위 비트(MSB, 부호 비트)를 유지하며 채웁니다.
종류는 위와 같이 총 6개 입니다. 아래는 이동 연산 명령어의 하드웨어 비트 필드 구조입니다.

- sll rd, rs1, rs2 => x[rd] = x[rs1] << x[rs2]
- srl rd, rs1, rs2 => x[rd] = x[rs1] << x[rs2]
- sra rd, rs1, rs2 => x[rd] = x[rs1] >> x[rs2]
- slli rd, rs1, shamt => x[rd] = x[rs1] << shamt***
- srli rd, rs1, shamt => x[rd] = x[rs1] << shamt
- srai rd, rs1, shamt => x[rd] = x[rs1] >> shamt
***I-Type shift에서 shamt(shift amount)는 5bit(0~31)만 사용합니다. 32bit 레지스터에서 32번 이상 미는 것은 의미가 없기 때문입니다.
5. 비교 연산 명령어(Set Less Than)
비교 연산은 두 값을 비교하여 조건이 참이면 1, 거짓이면 0을 목적지 레지스터(rd)에 저장합니다. 주로 조건문이나 루프의 기초가 됩니다.
- slt / slti: 부호가 있는 정수(Signed)로 비교합니다.
- sltu / sltiu: 부호가 없는 정수(Unsigned)로 비교합니다.
종류는 위와 같이 총 4개 입니다. 아래는 비교 연산 명령어의 하드웨어 비트 필드 구조입니다.

- slt rd, rs1, rs2 => x[rd] = x[rs1] < x[rs2] (signed)
- sltu rd, rs1, rs2 => x[rd] = x[rs1] < x[rs2] (Unsigned)
- slti rd, rs1, imm[11:0] => x[rd] = x[rs1] < sign-extended(imm[11:0])) (Signed)
- sltiu rd, rs1, imm[11:0] => x[rd] = x[rs1] < sign-extended(imm[11:0])) (Unsigned)****
****sltiu에서 imm은 부호 확장이 먼저 일어난 후, 비교 자체는 Unsigned로 수행됩니다. 이 특성은 특정 값이 0인지 확인하거나, 범위를 체크하는 최적화에 자주 사용됩니다.
6. U-type 연산 명령어 (Upper Immediate)
RV32I는 모든 명령어 길이가 32비트로 고정되어 있습니다. 따라서 32비트 크기의 상수를 한 번에 레지스터에 넣을 수 없죠. (Opcode 등이 자리를 차지하니까요!) 이를 해결하기 위해 상위 20비트를 먼저 다루는 U-type 명령어가 존재합니다.
- lui (Load Upper Immediate):
- 전달받은 20비트 상수를 레지스터의 **[31:12]**에 넣고, 하위 12비트는 0으로 채웁니다.
- 보통 addi와 조합하여 32비트 전체 상수를 완성할 때 사용합니다.
- auipc (Add Upper Immediate to PC):
- 20비트 상수를 상위 비트에 두고, 현재의 PC(Program Counter) 값을 더해 rd에 저장합니다.
- 현재 위치를 기준으로 멀리 떨어진 데이터나 함수에 접근할 때(Relative Addressing) 필수적입니다.
종류는 위와 같이 총 2개 입니다. 아래는 U-Type 연산 명령어의 하드웨어 비트 필드 구조입니다.

- lui rd, imm[31:12] => rd = {imm[31:12], 12'b0}
- auipc rd, imm[31:12] => rd = PC + {imm[31:12], 12'b0}
7. 요약 및 마무리
지금까지 RV32I의 핵심 연산 그룹인 Computation 명령어들을 살펴보았습니다.
- Arithmetic: 더하고 빼기 (add, sub)
- Logical: 비트 단위 연산 (and, or, xor)
- Shift: 비트 밀기 (sll, srl, sra)
- Compare: 크기 비교 (slt)
- Upper: 큰 숫자 다루기 (lui, auipc)
이 명령어들만 있으면 세상의 거의 모든 복잡한 계산을 수행할 수 있습니다. 이것이 바로 RISC(Reduced Instruction Set Computer)가 추구하는 단순함의 미학입니다.
'RISC-V > RISC-V 개념' 카테고리의 다른 글
| [RISC-V] RV32I ISA - Control Transfer (0) | 2026.03.10 |
|---|---|
| [RISC-V] RV32I ISA - Loads & Stores (0) | 2026.03.09 |
| [RISC-V] RV32I ISA (0) | 2026.03.05 |
| [RISC-V] RV32I 레지스터 (0) | 2026.03.05 |
| [RISC-V] 5편 RISC-V의 미래: 기회와 도전 — ISA 생태계 전환기의 기술·시장 분석 (1) | 2026.03.04 |