在过去的3天里,我正在完成一项任务,要求我们在MIPS中实现Quicksort算法。我们得到了这段C代码:
void swap(int v[], int k, int l) {
int temp = v[k];
v[k] = v[l];
v[l] = temp;
}
int partition(int v[], int n) {
int pivot = v[n-1];
int i = 0;
for (int j = 0; j < n - 1; j++)
if (v[j] < pivot)
swap(v,i++,j);
swap(v, i, n - 1);
return (i);
}
void qsort(int v[], int n) {
if (n > 1) {
int p = partition(v, n);
qsort(v,p);
qsort(&v[p+1],n-p-1);
}
}
我们被要求翻译&#39;它在MIPS中。我在MIPS中提供了partition()
函数,我们必须实现其他两个函数(qsort()
和swap()
)。好吧,swap()
已经过测试并正常运行,因此我尝试实施qsort()
并且我需要在堆栈中存储qsort()
将在其后返回的地址。完成(用于递归)。问题是,无论我做什么,无论是使用堆栈和帧指针还是明确尝试设置空单元格,执行partition()
时,替换我的数组它的一些拥有的数据。关于解决这个问题的任何想法?
我的代码在这里(任何没有评论的东西都不是我的,忽略了printArray的跳转,因为它与代码的其余部分没有关系,所以我把它留下来了):
.globl v
.data
.align 2
v:
.word 3
.word 10
.word 8
.word 2
.word 7
.word 1
.word 5
.word 9
.word 6
.word 4
.text
main:
addiu $sp,$sp,-40
sw $ra,36($sp)
sw $fp,32($sp)
move $fp,$sp
li $v0,10 # 0xa
move $s0, $v0
sw $v0,28($fp)
lw $a1,28($fp)
la $a0, v
jal printArray
lw $a1,28($fp)
la $a0, v
jal qsort
la $a0, v
move $a1, $s0
jal printArray
move $v0,$0
move $sp,$fp
lw $ra,36($sp)
lw $fp,32($sp)
addiu $sp,$sp,40
jr $ra
swap:
move $t0, $a0 #store the address of the first cell of the array (we need this for finding v[k]'s address)
move $t1, $a0 #same as above (need this for the address of v[l])
move $t4, $a1 #load k into t4
sll $t4, $t4, 2 #turn k into bytes to be offset
add $t0, $a0, $t4 #find the address of v[k]
move $t4, $a2 #load l into a1
sll $t4, $t4, 2 #turn l into bytes to be offset
add $t1, $a0, $t4 #find the address of v[l]
lw $t2, 0($t0) #store the element with index k in t2 (t2: temp in the C code)
lw $t3, 0($t1) #store the element with index l in t3
sw $t2, 0($t1) #store the element with index k in the address where v[l] was
sw $t3, 0($t0) #store v[l] where v[k] was
jr $ra
nop
partition:
addiu $sp,$sp,-56
sw $ra,44($sp)
sw $fp,40($sp)
move $fp,$sp
sw $a0,48($fp)
sw $a1,52($fp)
lw $v1,52($fp)
li $v0,1073676288 # 0x3fff0000
ori $v0,$v0,0xffff
addu $v0,$v1,$v0
sll $v0,$v0,2
lw $v1,48($fp)
addu $v0,$v1,$v0
lw $v0,0($v0)
sw $v0,36($fp)
sw $0,28($fp)
sw $0,32($fp)
b part_loop
nop
part_for:
lw $v0,32($fp)
sll $v0,$v0,2
lw $v1,48($fp)
addu $v0,$v1,$v0
lw $v1,0($v0)
lw $v0,36($fp)
slt $v0,$v1,$v0
beq $v0,$0,part_noswap
nop
lw $v0,28($fp)
addiu $v1,$v0,1
sw $v1,28($fp)
lw $a2,32($fp)
move $a1,$v0
lw $a0,48($fp)
jal swap
part_noswap:
lw $v0,32($fp)
addiu $v0,$v0,1
sw $v0,32($fp)
part_loop:
lw $v0,52($fp)
addiu $v1,$v0,-1
lw $v0,32($fp)
slt $v0,$v0,$v1
bne $v0,$0,part_for
nop
lw $v0,52($fp)
addiu $v0,$v0,-1
move $a2,$v0
lw $a1,28($fp)
lw $a0,48($fp)
jal swap
lw $v0,28($fp)
move $sp,$fp
lw $ra,44($sp)
lw $fp,40($sp)
addiu $sp,$sp,56
jr $ra
qsort:
move $t5, $ra #store temporarily the ret.addr. of qsort's caller
jal RetAddrMng #then store it on the stack
addi $t6, $t6, 1 #add 1 to t6, which counts the number of times qsort has been called
bgt $a1, 1, sort #sorting will continue if n > 1
sort:
jal partition
move $a1, $v0 #move 'p' from result to be the argument of the next qsort
jal qsort
jr $ra
RetAddrMng:
sll $t6, $t6, 2 #turn the number of times into offset bytes by quadrupling them
add $sp, $sp, $t6 #move the stack pointer 4*<number of times> bytes to find the next cell
sw $t5, 0($sp) #store the address in t5 into the stack
srl $t6, $t6, 2 #we will need again the number of times, so we invert the transformation by dividing with 4
jr $ra #continue with qsort
仅供参考,我正在使用MARS 4.5。
提前致谢。