for(int i = 0; i < 6; i++) {
int temp = pos[i];
x[temp] = data[i];
}
让我们说我已经用mips创建了数组,然后,
main: la $s1, x ## load address of x into $s1
la $s2, pos # load address of pos into $s2
la $s3, data # load address of data into $s3
li $s6, 6 # for loop test.
li $s0, 0 # i variable
这就是我尝试将两行C ++翻译成mips的方法,
add $t1, $s2, $s0 # Get pos[i] and put in $t1;
sw $t1, ($t3) # int temp = pos[i]
add $t2, $s3, $s0 # Get data[i] and put in #t2
add $t4, $s1, $t3 # Get x[temp] and store it in $t4
sw $t2, ($t4) # x[temp] = data[i];
addi $s0, $s0, 1 # i++
blt $s0, $s6, for # (for i < 6)
但是当我在qtspim上运行它时(当与完整代码结合使用时)我得到的输出是
0 0 0 0 0 0 0 0 0 0
而不是
0 73 0 47 0 0 23 0 0 26
我应该得到的是什么......我做错了什么?谢谢。
答案 0 :(得分:2)
你有一些基本结构正确并且有好的评论。
但是,有一些错误的单位化值,使用错误的寄存器而不实际从内存中取出。此外,索引值必须转换为字节偏移量。
我制作了两个版本的程序。带有bug注释的版本。并且,清理和工作版本。
这是带注释的版本[请原谅无偿的风格清理]:
main:
la $s1,x # load address of x into $s1
la $s2,pos # load address of pos into $s2
la $s3,data # load address of data into $s3
li $s6,6 # for loop test.
li $s0,0 # i variable
# This is how I tried translating the two lines of C++ into mips,
for:
# NOTE/BUG: for the index values, when adding them to the base address
# of a given array, we need a _byte_ offset (i.e. the index multiplied by
# 4)
# NOTE/BUG: this does _not_ fetch pos[i] from memory -- it merely puts "i"
# into the target
add $t1,$s2,$s0 # Get pos[i] and put in $t1;
# NOTE/BUG: $t3 is never initialized to anything
sw $t1,($t3) # int temp = pos[i]
# NOTE/BUG: this does _not_ fetch pos[i] from memory -- it merely puts "i"
# into the target
add $t2,$s3,$s0 # Get data[i] and put in #t2
# NOTE/BUG: $t3 should contain an _index_ value -- it would have to be
# multiplied by 4 to create a _byte_ offset
add $t4,$s1,$t3 # Get x[temp] and store it in $t4
sw $t2,($t4) # x[temp] = data[i];
addi $s0,$s0,1 # i++
blt $s0,$s6,for # (for i < 6)
这是清理过的版本。我添加了缺少的代码,使其成为一个完整的可运行程序。我尽量保留原始代码,不幸的是,我不得不重构它:
.text
.globl main
#
# for (int i = 0; i < 6; i++) {
# int temp = pos[i];
# x[temp] = data[i];
# }
main:
la $s1,x # load address of x into $s1
la $s2,pos # load address of pos into $s2
la $s3,data # load address of data into $s3
li $s6,6 # for loop test.
li $s0,0 # i variable
la $a0,msg_pos
move $a1,$s2
jal print
la $a0,msg_data
move $a1,$s3
jal print
for:
sll $t0,$s0,2 # get byte offset for pos/data
addu $t1,$s2,$t0 # get address of pos[i]
lw $t1,0($t1) # get value of pos[i] (i.e. temp)
bltz $t1,next # skip negative indexes
bge $t1,6,next # skip indexes that overflow
sll $t1,$t1,2 # convert temp to byte offset
addu $t1,$s1,$t1 # get address of x[temp]
addu $t2,$s3,$t0 # get address of data[i]
lw $t2,0($t2) # get value of data[i]
sw $t2,0($t1) # x[temp] = data[i]
next:
addi $s0,$s0,1 # i++
blt $s0,$s6,for # (for i < 6)
la $a0,msg_x
move $a1,$s1
jal print
li $v0,10
syscall
# print -- print array
#
# arguments:
# a0 -- message pointer
# a1 -- array pointer
print:
li $a2,6
li $v0,4
syscall
print_loop:
li $v0,4
la $a0,msg_space
syscall
li $v0,1
lw $a0,0($a1)
syscall
addiu $a1,$a1,4
addi $a2,$a2,-1
bgtz $a2,print_loop
li $v0,4
la $a0,msg_nl
syscall
jr $ra
.data
pos: .word 5, 0, 4, 1, 3, 2
data: .word 1, 2, 3, 4, 5, 6
x: .word -1, -1, -1, -1, -1, -1
msg_pos: .asciiz "pos:"
msg_data: .asciiz "data:"
msg_x: .asciiz "x:"
msg_space: .asciiz " "
msg_nl: .asciiz "\n"
修改:虽然不是原始代码的一部分,但我在temp
上添加了一个边界检查,因为它是问题类似问题的一部分,无论如何都很有道理。