我需要将以下C代码翻译成MIPS64:
#include <stdio.h>
int main() {
int x;
for (x=0;x<10;x++) {
}
return 0;
}
我使用codebench将此代码交叉编译为MIPS64。创建了以下代码:
.file 1 "loop.c"
.section .mdebug.abi32
.previous
.gnu_attribute 4, 1
.abicalls
.option pic0
.text
.align 2
.globl main
.set nomips16
.set nomicromips
.ent main
.type main, @function
main:
.frame $fp,24,$31 # vars= 8, regs= 1/0, args= 0, gp= 8
.mask 0x40000000,-4
.fmask 0x00000000,0
.set noreorder
.set nomacro
addiu $sp,$sp,-24
sw $fp,20($sp)
move $fp,$sp
sw $0,8($fp)
j $L2
nop
$L3:
lw $2,8($fp)
addiu $2,$2,1
sw $2,8($fp)
$L2:
lw $2,8($fp)
slt $2,$2,10
bne $2,$0,$L3
nop
move $2,$0
move $sp,$fp
lw $fp,20($sp)
addiu $sp,$sp,24
j $31
nop
.set macro
.set reorder
.end main
.size main, .-main
.ident "GCC: (Sourcery CodeBench 2012.03-81) 4.6.3"
要检查代码是否按预期工作,我通常使用WINMIPS64模拟器。由于一个或其他原因,此模拟器不想接受此代码。似乎每行代码都是错误的。我一直在看这个问题超过一天。我希望有人可以帮助我解决这个问题。这个mips64架构的汇编代码有什么问题?
答案 0 :(得分:5)
来自WINMIPS64 documentation的第7页:
The following assembler directives are supported
.data - start of data segment
.text - start of code segment
.code - start of code segment (same as .text)
.org <n> - start address
.space <n> - leave n empty bytes
.asciiz <s> - enters zero terminated ascii string
.ascii <s> - enter ascii string
.align <n> - align to n-byte boundary
.word <n1>,<n2>.. - enters word(s) of data (64-bits)
.byte <n1>,<n2>.. - enter bytes
.word32 <n1>,<n2>.. - enters 32 bit number(s)
.word16 <n1>,<n2>.. - enters 16 bit number(s)
.double <n1>,<n2>.. - enters floating-point number(s)
删除上面列表中没有的所有内容,因为它不会在模拟器中运行。
您需要将.align
移至.text
根据文档,WINMIPS64需要daddi
/ daddui
而不是addi
/ addiu
。
根据文档,move $a, $b
不是受支持的助记符。请改为使用daddui $a, $b, 0
替换它们。
slt
需要slti
。
最后,模拟器需要j
的绝对地址,但是你给它一个寄存器。请改用jr
。
此时我得到一个无限循环。这是因为堆栈指针未初始化。模拟器只给你0x400字节的内存,所以继续将堆栈初始化为0x400:
.text
daddui $sp,$0,0x400
现在它运行。由于您自己运行代码,因此返回寄存器中不会有任何内容,最终的jr $31
只会将其恢复到开头。
这是我的版本:
.align 2
.text
daddui $sp,$0,0x400
main:
daddui $sp,$sp,-24
sw $fp,20($sp)
daddui $fp,$sp,0
sw $0,8($fp)
j $L2
nop
$L3:
lw $2,8($fp)
daddui $2,$2,1
sw $2,8($fp)
$L2:
lw $2,8($fp)
slti $2,$2,10
bne $2,$0,$L3
nop
daddui $2,$0,0
daddui $sp,$fp,0
lw $fp,20($sp)
daddui $sp,$sp,24
jr $31
nop
考虑使用另一个编译器或其他模拟器,因为这两个明显相互讨厌。