32-Bit Immediate Operands
- 프로그램에서 사용하는 상수는 대체로 크기가 작다.
-> 대부분 16비트 필드면 충분하지만 때에 따라서는 더 큰 상수가 필요한 경우도 있다. - MIPS는 레지스터의 상위 16비트에 상수를 넣는 lui(load upper immediate) 명령어를 제공한다.
-> Copies 16-bit constant to left 16 bits of rt
-> Clears right 16 bits of rt to 0
lui를 이용해서 상위 16비트를 채운다.
ori를 이용해서 하위 16비트를 채운다.
Addressing in Branches and Jumps
Jump Addressing
- jump 명령어는 가장 간단한 주소 지정 방식
- 6비트의 op 코드와 26비트의 주소 필드로 구성되는 J타입 명령어 형식.
j 10000 # go to location 10000
위를 어셈블하면 다음과 같다.
Branch Addressing
점프와 달리 조건부 분기(conditional branch) 명령에는 branch 주소 외에 2개의 operand가 더 있다.
bne $s0, $s1, Exit # go to Exit if $s0 != $s1
위를 어셈블하면 다음과 같다.
만약 프로그램에서 사용하는 모든 주소가 16비트 필드에 들어가야 한다면 모든 프로그램은 2^16보다 작을 것이다. 그러나 이것은 너무 작은 크기이기 때문에, 해결할 수 있는 대안이 필요하다. 레지스터를 지정해서 그 값을 branch 주소와 더하도록 하면 분기 주소는 다음과 같이 구해진다.
PC = Register + Branch Address
이 방식을 프로그램 크기가 2^32까지 커지는 것을 허용하면서 conditional branch도 지원함으로써 branch 주소의 크기 제한을 해결한다.
PC-relative addressing
PC(pragram counter)는 현재 명령어의 주소를 가지고 있으므로 Branch 주소를 더할 레지스터로 PC를 선택하면 현 위치에서 -2^15 ~ 2^15 워드 이내 떨어진 곳은 어디든지 분기할 수 있다. 거의 모든 반복문과 조건문의 분기 범위가 2^16워드 이내이다.
이런 분기 주소 지정 방식을 PC-relative addresing 방식이라 한다. 하드웨어 입장에서 PC를 일찍 증가시켜 다음 명령어를 가리키게 하는 것이 편리하다. 그러므로 실제 MIPS 주소는 현재 명령어 주소(PC)를 기준으로 하는 것이 아니라 다음 명령어 주소(PC + 4)를 기준으로 하게 된다. PC-relative addresing 방식은 자주 생기는 일을 빠르게라는 원칙의 또 다른 예인데, 이 경우 자주 생기는 일을 가까이 있는 명령어들의 주소 지정이다.
Showing Branch Offset in Machine Language
while (save[i] == k)
i += 1;
위 C 코드를 MIPS 어셈블리 코드로 변환하면 아래와 같다.
Loop: sll $t1, $s3, 2 # Temp reg $t1 = 4 * i
add $t1, $t1, $s6 # $t1 = address of save[i]
lw $t0, 0($t1) # Temp reg $t0 = save[i]
bne $t0, $s5, Exit # go to Exit if save[i] ≠ k
addi $s3, $s3, 1 # i = i + 1
j Loop # go to Loop
Exit:
Loop의 주소가 80000이라고 할 때 위 프로그램에 해당하는 MIPS 기계어 코드는?
Assemble된 명령어와 주소는 다음과 같다.
MIPS 명령어는 바이트 주소를 사용하므로 이웃한 워드의 주소는 4씩 차이가 난다.
네 번째 줄의 bne 명령은 다음 명령어 주소(80016)에 8을 더해서 목적지 주소를 구한다.
현재 명령어 기준의 상대적 위치(12 + 80012)나 목적지 주소 전체(80024)가 아니라 다음 명령어를 기준으로 한 상대적 위치(8 + 80016)로 분기 주소를 나타내기 때문이다. 마지막 줄의 점프 명령어는 Loop에 해당하는 주소 전체(20000 * 4)를 사용한다.
Branching Far Away
beq $s0, $s1, L1
레지스터 $s0가 레지스터 $s1과 같으면 부기하는 코드를 L1이 멀어도 분기가 가능하도록 바꾸되 명령어 2개를 사용하라.
bne $s0, $s1, L2
j L1
L2:
MIPS Addressing Mode Summary
MIPS에서 사용되는 Addressing mode는 다음과 같다.
- immediate addressing: operand는 명령어 내에 있는 상수이다.
- Register addressing: operand는 register다.
- Base or displacement addressing: operand가 레지스터의 합과 명령의 상수인 메모리 위치인 경우
- PC-relative addressing: PC 값과 명령어 내 상수의 합을 더해서 주소를 구한다.
- Pseudodirect addressing: 명령어 내의 26비트를 PC의 상위 비트들과 덧붙여서 점프 주소를 구한다.