Illustrates use of assembly instructions for a C bubble sort function
C 프로그램을 어셈블리 프로그램으로 바꿀 때는 다음 절차에 따라 번역한다
1. 프로그램 변수에 레지스터를 할당한다
2. 프로시저 본체에 해당하는 코드를 생성한다
3. 프로시저 호출 후의 레지스터 내용을 호출 전과 같도록 만든다
void swap(int v[], int k) {
int temp;
temp = v[k];
v[k] = v[k+1];
v[k+1] = temp;
}
레지스터 할당
본체 프로그램
temp = v[k];
v[k] = v[k+1];
v[k+1] = temp;
MIPS code :
swap :
sll $t1, $a1, 2 // t1 = k * 4
add $t1, $a0, $t1 // t1 = v + (k*4) (address of v[k])
lw $t0, 0($t1) // t0 (temp) = v[k]
lw $t2, 4($t1) // t2 = v[k+1]
sw $t2, 0($t1) // t1 (v[k]) = t2 (v[k+1])
sw $t0, 4($t1) // t2 (v[k+1]) = t0 (temp)
jr $ra // return to calling routine
void sort(int v[], int n) {
int i, j;
for (i = 0; < n; i+= 1) {
for (j = i-1; j >= 0 && v[j] > v[j+1]; j -= 1) {
swap(v, j);
}
}
}
양이 너무 많아서 나눠서 작성한다
// sort의 인수를 다른 레지스터에 복사해서 swap을 호출할 때 레지스터 $a0와 $a1을 사용할 수 있게 한다.
move $s2, $a0 // save $a0 into $s2
move $s3, $a1 // save $a1 into $s3
move $s0, $zero // i = 0
for1tst :
// i가 n보다 크면 순환이 종료된다.
slt $t0, $s0, $s3 // if s0 (i) >= s3 (n), t0 = 0
beq $t0, $zero, exit1
addi $s1, $s0, -1 // j = i-1
for2tst :
// 두 조건 (j >= 0, v[j] > v[j+1]) 중 하나라도 거짓이면 순환문에서 나온다.
// 첫 번째 조건에서 탈락(j < 0)이면 바로 순환문에서 나온다
slti $t0, $s1, 0 // if s1 (j) < 0, t0 = 1
bne $t0, $zero, exit2
// 두 번째 조건을 검사한다
sll $t1, $s1, 2 // t1 = j * 4
add $t2, $s2, $t1 // t2 = v + (j * 4) (address of v[j])
lw $t3, 0($t2) // t3 = v[j]
lw $t4, 4($t2) // t4 = v[j+1]
slt $t0, $t4, $t3 // if t4 >= t3, t0 = 0
beq $t0, zero, exit2
// 인수를 전달한다
move $a0, $s2 // 1st param of swap is v (old $a0)
move $a1, $s1 // 2st param of swap is j
// call swap
jal swap
// inner loop
addi $s1, $s1, -1 // j -= 1
j for1st // jump to test of inner loop
exit2 :
//outer loop
addi $s0, $s0, 1 // i += 1
j for1tst // jump to test of outer loop
sort :
addi $sp, $sp, -10 // make room on stack for 5 registers
sw $ra, 16($sp) // save ra on stack
sw $s3, 12($sp) // save s3 on stack
sw $s2, 8($sp)
sw $s1, 4($sp)
sw $s0, 0($sp)
#procedure body
exit1 :
lw $s0, 0($sp) // restore s0 from stack
lw $s1, 4($sp)
lw $s2, 8($sp)
lw $s3, 12($sp)
lw $ra, 16($sp)
addi $sp, $sp, 20 // restore stack poinger
jr $ra // return to calling routine
(Keeping a pointer to an automatic variable after procedure returns)