【问题标题】:Crosscompiling C to MIPS64 and simulating将 C 交叉编译为 MIPS64 并进行仿真
【发布时间】:2012-10-12 15:09:22
【问题描述】:

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

【问题讨论】:

    标签: c assembly mips mips64


    【解决方案1】:

    来自 WINMIPS64 的第 7 页documentation

    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
    

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

    【讨论】:

    • 感谢一千次。我根据您的建议更改了文件,但现在模拟器挂在第 4、13 和 24 行。您知道要进行最后的修改吗? mips64交叉编译器是否还有另一个c? .align 2 .text daddui $sp,$0,0x400 main: daddiu $sp,$sp,-24 sw $fp,20($sp) daddui $fp,$sp,0 sw $0,8($fp) jr $ L2 nop $L3: lw $2,8($fp) daddiu $2,$2,1 sw $2,8($fp) $L2: lw $2,8($fp) slt $2,$2,10 bne $2,$0,$ L3 nop daddui $2,$0,0 daddui $sp,$fp,0 lw $fp,20($sp) daddiu $sp,$sp,24 jr $31 nop
    • 那些行仍然有daddiu而不是daddui
    • 谢谢杰夫!我改了一下,用asm.exe检查了代码,不幸的是第二遍有17个错误。
    • 我已将我的版本添加到答案中。
    • 感谢您更新您的代码:我将它保存在一个单独的 .s 文件中并通过 asm.exe 运行它。终端给我以下消息,WINMIPS64 也是如此:''Pass 2 completed with 16 errors''
    猜你喜欢
    • 1970-01-01
    • 2012-10-22
    • 2013-02-20
    • 1970-01-01
    • 2013-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-07
    相关资源
    最近更新 更多