본문 바로가기
지식/컴퓨터아키텍쳐

Instruction(2)

by 칙칙폭폭 땡땡 2025. 10. 7.
반응형

Generating 32-Bit Constants

여기서는 RISC-V에서 32비트 상수를 레지스터에 저장할 때 사용하는 방법을 다룬다.

여기서 핵심은 한 번의 addi 로는 12비트까지만 표현 가능하다는 제약 때문에 lui 명령과 addi를 조합해서 32비트 상수를 표현한다.

addi 12비트의는 즉시값(immediate)를 사용할 수 있다. 범위는 -2048 ~ 2047

그래서 addi 로는 32비트는 표현할 수 없고 lui를 활용한다.

lui  s0, 0xFEDC8 
addi s0, s0, 0x765

lui는 상위 20비트를 즉시값으로 채우고 하위 12비트를 0으로 채운다.

lui s0, 0xFEDC8  → s0 = 0xFEDC8000

addi 는 지정한 레지스터 값에 12비트 즉시값을 더한다.

이때 즉시값은 부호가 확장되어서 계산된다.

addi s0, s0, 0x765  → s0 = 0xFEDC8000 + 0x765 = 0xFEDC8765

만약 10진수로 -341을 addi로 더한다면??

⇒ -341_10 = 1110 1010 1011_2 = 0xEAB_16 =<부호확장>⇒ 0xFFFFFEAB_16

(cf. 맨 마지막에 생긴 캐리는 오버플로우로 버린다.)

Logical Instructions

이 부분은 RISC-V에서 비트 단위로 데이터를 조작하는 명령어들을 다루는 부분이다.

각 비트를 따로 조작해서 마스크하고 합치고 반전한다.

명령어
의미
동작
and
논리곱 (bitwise AND)
두 비트가 모두 1이면 1
or
논리합 (bitwise OR)
둘 중 하나라도 1이면 1
xor
배타적 논리합 (bitwise XOR)
둘 중 하나만 1이면 1

AND(masking)

s1 = 0xFFFF0000
s2 = 0x46A1F1B7

and s3, s1, s2
    0xFFFF0000
AND 0x46A1F1B7
--------------
=   0x46A10000

F는 1111이라 마스킹이 되는 것

OR(combine)

or s4, s1, s2

 

    0xFFFF0000
OR  0x46A1F1B7
--------------
=   0xFFFFF1B7​

XOR(exclusive OR)

xor s5, s1, s2
    0xFFFF0000
XOR 0x46A1F1B7
--------------
=   0xB95EF1B7

완전 반전

Shift Instructions

비트를 왼쪽이나 오른쪽으로 밀어서 shift하는 것, 값을 2배, 1/2배, 혹은 부호 보존 상태를 조정하는 명령어

명령어
의미
부호 처리
예시
sll
Shift Left Logical
부호 무시 (0 채움)
sll t0, t1, t2 → t0 = t1 << t2
srl
Shift Right Logical
0 채움
srl t0, t1, t2 → t0 = t1 >> t2
sra
Shift Right Arithmetic
부호비트 유지(1 채움)
sra t0, t1, t2 → t0 = t1 >>> t2

Left shift(sll)

       0000 0011 (3)
<< 1 → 0000 0110 (6)
<< 2 → 0000 1100 (12)

왼쪽으로 한 칸 밀 때마다 2배씩 커짐

Right shift(srl)

       0000 1100 (12)
>> 1 → 0000 0110 (6)
>> 2 → 0000 0011 (3)

오른쪽으로 한 칸 밀면 2로 나눈 것과 같음

Right shift Arithmetic(sra)

t1 = 0xFFFFFFF0 = -16 (32비트)
sra t0, t1, 2  → 0xFFFFFFFC = -4

부호비트(1)가 유지돼서 결과도 음수 cf. 반면 srl은 부호비트 무시

srl t0, t1, 2  → 0x3FFFFFFC  (양수!)

Immediate Shift Instructions

이건 앞에서 배운 sli, srl, sra랑 거의 똑같은데, 시프트 양(얼마나 밀지)을 레지스터가 아니라 즉시값으로 직접 주는 버전

명령어
방향
채움
즉값 범위
예시
결과
slli
왼쪽
0
0~31
slli t0, t1, 3
t1 × 8
srli
오른쪽
0
0~31
srli t0, t1, 2
t1 ÷ 4
srai
오른쪽
부호비트(1)
0~31
srai t0, t1, 2
t1 ÷ 4 (부호 유지)

Multiplication

RISC-V에서는 정수끼리의 곱셉은 64비트 결과를 반환한다.

32비트 X 32비트 = 64비트가 나오는데, 이때 상위랑 하위 결과를 나누어서 저장하는 방법이다.

명령어
의미
결과 저장
설명
mul
Multiply
하위 32비트
보통 우리가 쓰는 일반 곱셈
mulh
Multiply High (signed)
상위 32비트
피연산자 2개 모두 signed로 취급
mul s3, s1, s2     # s3 = (s1 × s2)의 하위 32비트
s1 = 0x40000000
s2 = 0x80000000

s1 × s2 = −2⁶¹ = 0xE0000000_00000000

상위 32비트 = 0xE0000000
하위 32비트 = 0x00000000

mul  s3, s1, s2   # s3 = 0x00000000
mulh s4, s1, s2   # s4 = 0xE0000000

{s4, s3} = s1 × s2 = 0xE0000000_00000000

Division

division은 multiplication과는 반대로 피제수를 제수로 나눠서 몫과 나머지로 나눈다

명령어
부호
결과
예시
결과
div
signed
-13 / 5
-2
rem
signed
나머지
-13 % 5
-3
addi s1, zero, 13  # 피제수
addi s2, zero, 5   # 제수
div  s3, s1, s2    # 몫
rem  s4, s1, s2    # 나머지
13 ÷ 5 = 2 (몫)
13 - (2×5) = 3 (나머지)

Branching

Branching은 flow control을 담당하는 부분이다

조건에 따라서 코드를 건너뛰거나 루프나 조건문 같은 특정 주소로 점프할 수도 있다.

명령어
의미
조건
beq
Branch if Equal
rs1 == rs2
bne
Branch if Not Equal
rs1 != rs2
blt
Branch if Less Than (signed)
rs1 < rs2
bge
Branch if Greater or Equal (signed)
rs1 ≥ rs2

예시 - beq

addi s1, zero, 5
addi s2, zero, 5
beq  s1, s2, LABEL
addi s3, zero, 100    # 실행 안 됨 (분기)
LABEL:
	addi s3, zero, 999    # 실행됨

실행 순서

  1. s1 == s2 → 참
  2. beq → LABEL 위치로 이동
  3. 다음 줄의 addi s3, 100 건너뜀
  4. 결과 s3 = 999

예시 - bne

addi s1, zero, 3
addi s2, zero, 4
bne  s1, s2, NOT_EQUAL
addi s3, zero, 0
NOT_EQUAL:
	addi s3, zero, 1

s1 ≠ s2 → 조건 참 → 분기 발생 → s3 = 1

예시 - blt, bge

addi s1, zero, -5
addi s2, zero, 2
blt  s1, s2, LESS
addi s3, zero, 0
LESS:
	addi s3, zero, 1

s1 < s2 → 조건 참 → 분기 발생 → s3 = 1

Conditional Statements

RISC-V에는 if나 else 같은 명령어가 없어서 Branch랑 Jump 적절하게 조합해서 조건문을 표현할 수 있다.

예시 - if only

addi s1, zero, 5
addi s2, zero, 10
blt s1, s2, SMALLER
addi s3, zero, 99       # s1 >= s2 이면 실행됨
j EXIT
SMALLER:
		addi s3, zero, 1        # s1 < s2 이면 실행됨
EXIT:

예시 - if else

addi s1, zero, 4
addi s2, zero, 4
bne s1, s2, ELSE        # if (s1 != s2) → ELSE로
addi s3, zero, 111      # 참일 때 실행
j EXIT
ELSE:
		addi s3, zero, 222      # 거짓일 때 실행
EXIT:

Loops

반복문은 브랜치를 이용해서 되돌아가는 구조로 만든다.

RISC-V에서는 j, blt, bne 로 만들 수 있다.

예시 - while, for

addi t0, zero, 0     # i = 0
addi t1, zero, 5     # N = 5
LOOP:
    bge t0, t1, EXIT
    addi t0, t0, 1
    j LOOP
EXIT:

예시 - do while

DO:
    ...
    blt x, y, DO   # 조건 참이면 되돌아감

Arrays

주소 계산이랑 load랑 store 계념 잘 알면 쉽다.

# s0 = array base address

lw   t1, 0(s0)      # t1 = array[0]
slli t1, t1, 1      # t1 = t1 * 2
sw   t1, 0(s0)      # array[0] = t1

lw   t1, 4(s0)      # t1 = array[1]
slli t1, t1, 1      # t1 = t1 * 2
sw   t1, 4(s0)      # array[1] = t1

 

반응형

'지식 > 컴퓨터아키텍쳐' 카테고리의 다른 글

Machine Language  (0) 2025.10.16
Instructions(3)  (0) 2025.10.07
Instructions(1)  (0) 2025.10.07
Computer Abstractions and Technology(2)  (0) 2025.10.07
Computer Abstractions and Technology(1)  (0) 2025.10.07