- beq register1, register2, L1 // register1 = register2 이면 L1으로 간다.
- bne register1, register2, L1 // register1 != register2 이면 L1으로 간다.
예제1. If-then-else를 조건부 분기로 변역
if(i = j) f = g + h;
else f = g - h;
1. 내생각
beq $s3, $s4, Else // s3 = s4, go to Else
sub $s0, $s3, $s4 // s3 - s4 = s0
j Exit // go to Exit
Else : add $s0, $s3, $s4 // s3 + s4 = s0
Exit :
2. 교재 답안
bne $s3, $s4, Else // s3 != s4, go to Else
add $s0, $s3, $s4 // s3 + s4 = s0
j Exit // go to Exit
Else : sub $s0, $s3, $s4 // s3 - s4 = s0
Exit :
2번이 then 부분을 건너뛰게 하기때문에 더 효율적이라고 한다. 모르겠다.
while (save[i] == k)
i += 1;
i, k가 각각 $s3, $s5에 할당되었고
배열 save의 시작 주소가 $s6에 할당되어있다고 할 때
위의 C문장에 해당하는 MIPS의 어셈블리 코드를 작성하여라.
sol)
첫번째로 save[i]를 임시 레지스터에 가져와야한다.
따라서 save[i]의 주소를 지정한 후 lw명령어를 사용한다.
0($s6) = save[0], 4($s6) = save[1] 이므로
i*4($s6)을 해주면 된다.
따라서 i*4를 위해 sll명령어를 사용한다.
두번째로 i*4($s6)을 위해 add명령어를 사용한다.
그 후 lw명령어로 주소에 해당하는 data를 불러온 후
bne명령어로 조건문을 해결하고 i에 1을 더하는 addi연산을 진행한다.
Loop: sll $t1, $s3, 2 // $s3 * 4 = $t1
add $t1, $t1, $s6 // $t1 = $s6($t1)?
lw $t0, 0($t1) // reg $t0 = save[i]
bne $t0, $s5, Exit // i != k, go to Exit
addi $s3, $s3, 1 // i += 1
j Loop // go to Loop
Exit:
분기 명령을 포함하지 않으며 (위 예제처럼 맨 마지막 에는 있을 수 있다.)
분기 목적지나 분기 레이블도 없는(맨 앞에 있는 것은 허용된다) 시퀀스이다.
왜 중요하냐?
Instruction의 순서를 바꿔도 결과가 변하지않을때가 있는데 만약 순서를 바꾸는것이 instruction level parallelism을 향상시킨다고 판단이 되면 HW에서 자체적으로 순서를 바꾼다.