将C交叉编译为MIPS64并进行模拟

时间:2012-10-12 15:09:23

标签: c assembly mips mips64

我需要将以下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架构的汇编代码有什么问题?

1 个答案:

答案 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

考虑使用另一个编译器或其他模拟器,因为这两个明显相互讨厌。