assembly instruction을 machine instruction으로 바꾸기 위해서 machine language는 32비트를 가진 instruction format을 가진다
arithmetic operation에 쓰인다 (add, sub)
op : operation code (op code)
rs : register source 첫번째
rt : register source 두번째
rd : register destination
shamt : shift amount
funct : function code (op code랑 1:1 매칭)
fied size 5 bit : register number가 들어가야 하니깐 2^5해서 5bit
$s0 - $s7은 register 16 - 23
$t0 - $t7은 register 8 - 15
$t8 - $t9는 register 24 - 25
0 1 2 ... 8 9 ... 16 17 ... 23 24 24
$zero $t0 $t1 $s0 $s1 $s7 $t8 $t9
각 register에 해당하는 번호를 맞는 위치에 넣어준다
immediate과 데이터 이동할 때 쓰인다 (addi, lw, sw, 상수값)
뒤에 3개 합쳐서 (5+5+6=16) 상수 또는 주소를 넣을 수 있게 만듦
constant or address : 필드 사이즈가 16으로 정해져있으니 최대 2^15의 주소값을 나타낼 수 있음
(맨 앞은 부호비트이니깐 16-1=15 해서 15승 만큼)
I-format에서는 3개가 합쳐지므로 값이 없음 (n.a.)
constant or address에 offset인 32가 들어감
📍 sll (Shift Left Logical)
sll은 이동시키는만큼 제곱하여 곱해주는 것과 같다
$s0을 4bit만큼 옆으로 이동시켜서 $t2에 저장해라
= $s0에 2^4만큼 곱해라
sll $t2,$s0,4
이때 shamt에 4가 들어가게 됨!
op와 funct는 1:1 매핑이 됨
shamt : 얼마만큼 sll할 건지 값이 들어감
2진수에서 4비트 만큼 왼쪽으로 이동시키는 것은 10진수에서 2^4만큼 곱해주는 것과 같음
📍 srl (Shift Right Logical)
srl은 이동시키는 만큼 제곱하여 나눠주는 것과 같다
(단, 음수에서는 안됨! 양수에만 적용 가능)
$s0을 오른쪽으로 4비트만큼 이동시키고 $t2에 저장해라
= $s0을 2^4만큼 나눠라
srl $t2,$s0,4
📍 AND
1 & 1 = 1
1 & 0 = 0
0 & 1 = 0
0 & 0 = 0
$t1 and $t2를 해서 나온 값 (1 또는 0)을 $t0에 저장해라
and $t0,$t1,$t2
📍 OR
0 or 0 = 0
0 or 1 = 1
1 or 0 = 1
1 or 1 = 1
📍 NOR (=Not Or)
0 nor 0 = 1
1 nor 0 = 0
0 nor 1 = 0
1 nor 1 = 0
Decision Making Instructions - for, while, if 등 조건문
📍 beq (branch if equal)
register1과 register2의 값이 같으면 L1 레이블로 가라
beq register1, register2, L1
📍 bne (branch if not equal)
register1과 register2의 값이 같지 않으면 L1 레이블로 가라
bne register1, register2, L1
예제 1)
save[i]의 메모리상의 주소 구하기
sll $t1,$s3,2 # $t1 = i x 4
sll은 2^2만큼 곱해주는 것과 같음. 메모리에서 한 칸은 4byte니깐 4만큼 이동
add $t1,$t1,$s6 # $t1 = save + (ix4)
base address $s6에 계산해둔 i 만큼의 offset을 더해서 save[i] 주소 계산
$t1 = $t1 + save[] base address
계산해둔 메모리의 save[i]값 register로 불러오기
lw $t0,0,$t1
이때 offset은 1번 과정에서 미리 계산해두었으니 0이된다.
...
📍 slt (set on less than)
A < B 해서 A가 더 작으면 1로 setting하고, 아니면 0으로 setting
$s3 < $s4면 $t0 = 1 / 아니면 $t0 = 0
slt $t0,$s3,$s4
📍 slti (set on less than immediate)
i가 나왔으니, operand중 하나는 상수값이 나올 것임. 상수값과 비교!
$s2 < 10이면 $t0 = 1 / 아니면 $t0 = 0
slti $t0,$s2,10
✅ slt
, slti
는 beq
, bne
와 함께 쓰임
slt $t0,$s1,$s2 #$s1 < $s2면 $t0 = 1
bne $t0,$zero,L #1과 0이 같지 않으니 L 레이블로 이동!
✅ unsigned
와 signed
에 따라 결과값이 달라질 수 있음
📍slt : signed (부호 있는 버전)에서 비교할 경우와
📍sltu : unsigned (부호 없는 버전)에서 비교할 때의 결과가 다름
$a0 - $a3
argument register로 함수의 입력으로 사용할 수 있음
$v0 - $v1
return value를 저장
$ra
procedure(함수)에서 수행을 완료하고 jump해서 return하러 올 때 return 주솟값을 알아야 돌아올 수 있다. procedure을 부르자마자 불려진 위치를 $ra
에 저장하고, 함수를 수행하는 공간으로 넘어간다.
📍 jal (jump and link)
procedure를 부를 때 사용하는 명령어
return address
를 저장한다📍 jr (jump register)
procedure에서 나올 때 사용하는 명령어 (return하여 돌아갈 때 사용)
$ra에 저장된 위치로 return하겠다!
jr $ra