【问题标题】:How do I force GAS to generate output identical to input?如何强制 GAS 生成与输入相同的输出?
【发布时间】:2015-05-18 01:40:58
【问题描述】:

我想编写具有公共 C 接口的代码,但完全在 MIPS 中实现,主要作为学习练习。但是,我坚持与 GAS 作斗争,因为它似乎认为它比我更了解。

为了说明,假设我想在 MIPS 中实现以下内容:

int bar(void)
{
    return (4 / 2);
}

如上所述,我希望能够从 C 调用 ASM 例程,因此我们需要一个 C 代码文件 bar.c 以及 bar.S 中的 MIPS 程序集。

bar.c:

extern int bar(void);

void _start()
{
    int foo = bar();
}

bar.S:

.global bar .text

bar:
    addi $2, $0, 4
    addi $3, $0, 2
    div $2, $3
    mflo $2
    jr $31
    addu $3, $0, $0

mipsel-none-elf-gcc bar.c bar.S -o bar.elf -ffreestanding -nostdinc -nostdlib 成功编译了这个,但mipsel-none-elf-objdump -d bar.elf 显示 GAS 正在弄乱我的 bar() 代码:

00400050 <bar>:
  400050:       20020004        addi    v0,zero,4
  400054:       20030002        addi    v1,zero,2
  400058:       14600002        bnez    v1,400064 <bar+0x14>
  40005c:       0043001a        div     zero,v0,v1
  400060:       0007000d        break   0x7
  400064:       2401ffff        li      at,-1
  400068:       14610004        bne     v1,at,40007c <bar+0x2c>
  40006c:       3c018000        lui     at,0x8000
  400070:       14410002        bne     v0,at,40007c <bar+0x2c>
  400074:       00000000        nop
  400078:       0006000d        break   0x6
  40007c:       00001012        mflo    v0
  400080:       00001012        mflo    v0
  400084:       03e00008        jr      ra
  400088:       00000000        nop
  40008c:       00001821        move    v1,zero

我不希望分区检查、延迟插槽修复或汇编程序在这里以任何方式“有帮助”:如果有必要,我完全有能力自己处理这些事情。我如何告诉 GAS 只是一个愚蠢的装配工?

【问题讨论】:

标签: c optimization mips gnu-assembler


【解决方案1】:

这个问题在 cmets 中解决了。 GAS 接受 div 的三操作数版本,如果第一个操作数是 $0,则除法检查被禁用。至于延迟槽,.set noreorder 指令可防止指令重新排序(duh)。将程序集更改为:

.set noreorder

.global bar .text

bar:
    addi $2, $0, 4
    addi $3, $0, 2
    div $0, $2, $3
    mflo $2
    jr $31
    addu $3, $0, $0

产生正确的输出:

00400050 <bar>:
  400050:       20020004        addi    v0,zero,4
  400054:       20030002        addi    v1,zero,2
  400058:       0043001a        div     zero,v0,v1
  40005c:       00001012        mflo    v0
  400060:       03e00008        jr      ra
  400064:       00001821        move    v1,zero

【讨论】:

  • 更正确的解释是2操作数pneumonic是宏名。 3操作数形式是一条指令。
猜你喜欢
  • 1970-01-01
  • 2016-06-09
  • 1970-01-01
  • 2019-03-19
  • 1970-01-01
  • 2021-07-10
  • 2011-05-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多