C++ mips-g++-5.4列出bnez跳过div指令

C++ mips-g++-5.4列出bnez跳过div指令,c++,mips,instruction-set,C++,Mips,Instruction Set,我试图理解为什么mips-g++编译了一个简单的除法子程序,其中它跳过了带有bnez v0,(pseudo inst forbne)的实际div指令。我的理解是,如果除数为零,在这种情况下跳过div和trap或break是有意义的。如果除数不是零,它为什么要分支 我想知道我错过了什么 子程序 void do_div(int&a、int&b、int&result){ 结果=a/b; } 程序集列表: (编译器标志:-O0) 00000000: 0:27bdfff8附加sp,sp,-8 4:afb

我试图理解为什么mips-g++编译了一个简单的除法子程序,其中它跳过了带有
bnez v0,
(pseudo inst for
bne
)的实际div指令。我的理解是,如果除数为零,在这种情况下跳过div和trap或break是有意义的。如果除数不是零,它为什么要分支

我想知道我错过了什么

子程序
void do_div(int&a、int&b、int&result){
结果=a/b;
}
程序集列表: (编译器标志:-O0)

00000000:
0:27bdfff8附加sp,sp,-8
4:afbe0004 sw s8,4(sp)
8:03a0f025移动s8,sp
c:afc40008 sw a0,8(s8)
10:afc5000c sw a1,12(s8)
14:afc60010 sw a2,16(s8)
18:8fc20008 lw v0,8(s8)
1c:00000000无
20:8c430000 lw v1,0(v0)
24:8fc2000c lw v0,12(s8)
28:00000000无
2c:8c420000 lw v0,0(v0)
30:00000000无
34:14400002 bnez v0,40
38:0062001a零度分区,v1,v0
3c:0007000d断开0x7
40:00001010 mfhi v0
44:00001812 mflo v1
48:8fc20010 lw v0,16(s8)
4c:00000000无
50:ac430000 sw v1,0(v0)
54:00000000无
58:03c0e825移动sp,s8
5c:8fbe0004 lw s8,4(sp)
60:27bd0008附加sp,sp,8
64:03e00008 jr ra
68:00000000无

正如@EOF在评论中提到的,MIPS有分支延迟槽的概念

这来自于对BNE的描述(重点是我的):

如果GPR rs和GPR rt的内容不相等,则在执行延迟槽中的指令后,分支到有效目标地址

因此,
DIV
总是被执行。您可能会想,“如果
$v0
为0,这不是一个问题吗?”。但是
DIV
的描述是:

在任何情况下都不会发生算术异常

如果GPR rt中的除数为零,则算术结果值不可预测

因此,在零除数的情况下,您将得到一个不可预测的结果,我们无论如何都不会使用它,因为接下来要做的事情是使用
BREAK
指令触发断点异常


资料来源:MIPS32™ 程序员体系结构第二卷:MIPS32™ 指令集

请尝试创建一个适当的程序集来向我们展示,并包含由此生成的完整程序集(作为文本)。请不要发布文本图片。复制文本本身。此外,MIPS还具有分支延迟插槽。最后,如果您试图读取未优化的编译器输出,您将发现汇编非常困难。为编译器指定
-Os
-O2
-O3
,以生成可读的程序集。当然,我希望程序地址在列表中,出于某种原因,godbolt不允许我复制。无论如何,我自己编译了它并更新了列表。我相信-O0会产生更可读的输出,因为引擎盖下没有优化。@EOF为了给您提供更多的上下文,当pc为0x34
v0
时,它持有c代码中的除数
b
,而在0x38时,我们应该计算存储在hi和lo alu regs中的v1/v0和v1%v0。现在,作为b!=0,我们将跳过0x38和0x3c并跳到0x40。希望这能提供更好的背景。如果你不是一开始就假设我错了,你可能真的有机会理解这个问题。
00000000 <_Z6do_divRiS_S_>:
   0:   27bdfff8    addiu   sp,sp,-8
   4:   afbe0004    sw  s8,4(sp)
   8:   03a0f025    move    s8,sp
   c:   afc40008    sw  a0,8(s8)
  10:   afc5000c    sw  a1,12(s8)
  14:   afc60010    sw  a2,16(s8)
  18:   8fc20008    lw  v0,8(s8)
  1c:   00000000    nop
  20:   8c430000    lw  v1,0(v0)
  24:   8fc2000c    lw  v0,12(s8)
  28:   00000000    nop
  2c:   8c420000    lw  v0,0(v0)
  30:   00000000    nop
  34:   14400002    bnez    v0,40 <_Z6do_divRiS_S_+0x40>
  38:   0062001a    div zero,v1,v0
  3c:   0007000d    break   0x7
  40:   00001010    mfhi    v0
  44:   00001812    mflo    v1
  48:   8fc20010    lw  v0,16(s8)
  4c:   00000000    nop
  50:   ac430000    sw  v1,0(v0)
  54:   00000000    nop
  58:   03c0e825    move    sp,s8
  5c:   8fbe0004    lw  s8,4(sp)
  60:   27bd0008    addiu   sp,sp,8
  64:   03e00008    jr  ra
  68:   00000000    nop