【问题标题】:Weired behaviour of GNU AS on divu MIPS instructionGNU AS 在 divu MIPS 指令上的奇怪行为
【发布时间】:2017-01-23 03:37:11
【问题描述】:

为了在 FPGA 上测试我们的 MIPS 实现,我编写了几个汇编测试代码。我正在使用 mips-linux-gnu-as 进行编译。

下面的代码是为了测试divu的实现,从代码来看,条件beq $t2, $t1, label1预期通过,$t1中加载了3。

.set noreorder
.text
__start:
    li  $t1, 10         
    li  $t2, 2

    divu $t1, $t2
    mflo $t2
    li $t1, 5
    beq $t2, $t1, label1
    j label2
label1:
    li  $t1, 3
label2:
    nop

我的问题是 gnu-as 为上述代码产生了奇怪的输出,以不同的执行行为结束,并且 3 从未加载到 $t1 中。

段.text的反汇编

00000000 <__start>:
0:   2409000a        addiu   t1,zero,10
4:   240a0002        addiu   t2,zero,2
8:   15400002        bnez    t2,14 <__start+0x14>
c:   012a001b        divu    zero,t1,t2
10:   0007000d        break   0x7
14:   00004812        mflo    t1
18:   00005012        mflo    t2
1c:   24090005        addiu   t1,zero,5
20:   11490001        beq     t2,t1,28 <label1>
24:   0800000b        j       2c <label2>

00000028 <label1>:
28:   24090003        addiu   t1,zero,3

0000002c <label2>:
2c:   00000000        sll     zero,zero,0x0

非常感谢任何帮助。

【问题讨论】:

    标签: assembly mips gnu-assembler binutils


    【解决方案1】:

    延迟槽中可能不会发生分支和跳转。 beq 的延迟槽中有 j。另外,我认为您也不希望 addiu t1, zero, 3j 的延迟槽中。您可能应该使用.set reorder 而不是.set noreorder。或者,您需要学习如何处理分支延迟槽。

    【讨论】:

    • 我的问题是我看不懂gcc为divu指令生成的代码。根据我对 RISC 管道的理解,divu 将始终被执行。但是为什么生成的代码会在 t1 (mflo t1) 中加载 lo 的值呢?我的意思是 t1 应该保持 10 作为一个值...
    • @AliAbdallah 我也不知道额外的 mflo 在那里做什么。编译器可能正在生成它以解决 CPU 错误(例如,插入延迟以允许更多时间进行除法)。在您的上下文中,至少在现代 MIPS CPU 上,这条额外的指令是无用且无害的。但这与真正的问题无关,即您如何处理分支延迟槽。
    猜你喜欢
    • 1970-01-01
    • 2011-04-17
    • 2012-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-09
    • 2013-07-03
    相关资源
    最近更新 更多