1

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

4

1 回答 1

5

从 WINMIPS64文档的第 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

考虑获得另一个编译器或另一个模拟器,因为这两个显然互相讨厌。

于 2012-10-12T17:23:52.093 回答