C++ mips-g++-5.4列出bnez跳过div指令
我试图理解为什么mips-g++编译了一个简单的除法子程序,其中它跳过了带有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
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: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为0x34v0
时,它持有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