将 C 代码转换为 MIPS(汇编源代码)
Converting C code to MIPS (Assembly Source Code)
我的任务是将此代码转换为汇编代码:
int prodArray (int A[], int n) {
if (!n)
return 1;
else if (n == 1)
return A[0];
int mid = n / 2;
int left = prodArray(A, mid);
int right = prodArray(A + mid, n - mid);
return left * right;
}
这是我目前的情况,请注意循环、循环 2 和循环 3 几乎相同:
main:
add $t0, [=11=], [=11=] # Initialize t0
add $t1, [=11=], [=11=] # Initialize t1
addi $t4, [=11=], 1 # Make t2 equal to 1
# Main Loop
loop:
beq $a1, $t2, exit # If the second argument is 0 branch to exit
beq $a1, [=11=], exit2 # If the second argument is 1 branch to exit2
srl $t2, $a1, 1 # Divide n by 2
sll $t3, $a1, 1 # Multiply n by 2
add $a1, $t2, [=11=] # make n half
b loop2 # branch to loop
loop2:
beq $a1, $t2, exit
beq $a1, [=11=], exit2
srl $t2, $a1, 1
sll $t3, $a1, 1
add $a0, $a0, $t2 # Make a0 point to A + mid
b loop3
loop3:
beq $a1, $t2, exit
beq $a1, [=11=], exit2
srl $t2, $a1, 1
sll $t3, $a1, 1
add $a1, $t2, [=11=]
b loop
# exit
exit:
ja $ra, $t4
exit2:
ja $ra, 0(a1)
我不太擅长组装,需要任何我能得到的帮助。请注意,a0 是第一个参数,a1 是第二个参数。
感谢您提供的任何指导!
如果您有 gcc
编译器,请使用 -S
开关,例如:gcc -S helloworld.c
。这将生成一个包含汇编代码的 .s
文件。这个问题有更多信息:How do you get assembler output from C/C++ source in gcc?
这里有一些提示……
您开始使用的 C 代码中没有任何循环,因此您的程序集中也不应该有任何循环。这个函数确实会调用自己,但是应该像任何其他子例程调用一样实现它(即,使用 jal
),而不是试图将函数内联到自身中。 (事实上 ,如果不进行一些相当大的重构,您不能内联此子例程。)
记住在子程序调用后将需要恢复的任何寄存器保存在堆栈上,包括 $v0
和 $v1
中的原始参数,以及 return 地址$ra
.
没有ja
指令。在子例程结束时使用的正确指令是 jr $ra
,您需要在执行之前将 return 值放入 $v0
。
不要忘记分支延迟槽!我看到许多地方的指令最终可能会执行您不想要的;您现在可能只想在每个条件分支之后添加一个 nop
。
我的任务是将此代码转换为汇编代码:
int prodArray (int A[], int n) {
if (!n)
return 1;
else if (n == 1)
return A[0];
int mid = n / 2;
int left = prodArray(A, mid);
int right = prodArray(A + mid, n - mid);
return left * right;
}
这是我目前的情况,请注意循环、循环 2 和循环 3 几乎相同:
main:
add $t0, [=11=], [=11=] # Initialize t0
add $t1, [=11=], [=11=] # Initialize t1
addi $t4, [=11=], 1 # Make t2 equal to 1
# Main Loop
loop:
beq $a1, $t2, exit # If the second argument is 0 branch to exit
beq $a1, [=11=], exit2 # If the second argument is 1 branch to exit2
srl $t2, $a1, 1 # Divide n by 2
sll $t3, $a1, 1 # Multiply n by 2
add $a1, $t2, [=11=] # make n half
b loop2 # branch to loop
loop2:
beq $a1, $t2, exit
beq $a1, [=11=], exit2
srl $t2, $a1, 1
sll $t3, $a1, 1
add $a0, $a0, $t2 # Make a0 point to A + mid
b loop3
loop3:
beq $a1, $t2, exit
beq $a1, [=11=], exit2
srl $t2, $a1, 1
sll $t3, $a1, 1
add $a1, $t2, [=11=]
b loop
# exit
exit:
ja $ra, $t4
exit2:
ja $ra, 0(a1)
我不太擅长组装,需要任何我能得到的帮助。请注意,a0 是第一个参数,a1 是第二个参数。
感谢您提供的任何指导!
如果您有 gcc
编译器,请使用 -S
开关,例如:gcc -S helloworld.c
。这将生成一个包含汇编代码的 .s
文件。这个问题有更多信息:How do you get assembler output from C/C++ source in gcc?
这里有一些提示……
您开始使用的 C 代码中没有任何循环,因此您的程序集中也不应该有任何循环。这个函数确实会调用自己,但是应该像任何其他子例程调用一样实现它(即,使用
jal
),而不是试图将函数内联到自身中。 (事实上 ,如果不进行一些相当大的重构,您不能内联此子例程。)记住在子程序调用后将需要恢复的任何寄存器保存在堆栈上,包括
$v0
和$v1
中的原始参数,以及 return 地址$ra
.没有
ja
指令。在子例程结束时使用的正确指令是jr $ra
,您需要在执行之前将 return 值放入$v0
。不要忘记分支延迟槽!我看到许多地方的指令最终可能会执行您不想要的;您现在可能只想在每个条件分支之后添加一个
nop
。