mips-g++-5.4 列表 bnez 跳过 div 指令
mips-g++-5.4 listing bnez skips div instruction
我试图理解为什么 mips-g++ 编译一个简单的 division 子例程,它在其中跳过带有 bnez v0, <jmp>
的实际 div 指令([=14 的伪指令) =]).我的理解是,如果 divisor 为零,则跳过 div 并在这种情况下捕获或中断是有意义的。如果 divisor 不为零,为什么要分支?
我想了解我所缺少的。
子程序
void do_div(int &a, int &b, int &result){
result = a/b;
}
汇编列表:
(编译器标志:-O0)
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
正如@EOF 在评论中提到的,MIPS 有分支延迟槽的概念。
这是来自BNE
(强调我的)的描述:
If the contents of GPR rs and GPR rt are not equal, branch to the effective target address after the instruction in the delay slot is executed.
所以 DIV
总是被执行。您可能会想 “嗯,如果 $v0
为 0,那不是个问题吗?”。但是 DIV
的描述说:
No arithmetic exception occurs under any circumstances.
If the divisor in GPR rt is zero, the arithmetic result value is UNPREDICTABLE.
因此,在除数为零的情况下,您最终会得到不可预测的结果,我们无论如何都不会使用它,因为接下来要做的是使用 BREAK
指令触发断点异常.
来源:面向程序员的 MIPS32™ 架构第 II 卷:MIPS32™ 指令集
我试图理解为什么 mips-g++ 编译一个简单的 division 子例程,它在其中跳过带有 bnez v0, <jmp>
的实际 div 指令([=14 的伪指令) =]).我的理解是,如果 divisor 为零,则跳过 div 并在这种情况下捕获或中断是有意义的。如果 divisor 不为零,为什么要分支?
我想了解我所缺少的。
子程序
void do_div(int &a, int &b, int &result){
result = a/b;
}
汇编列表:
(编译器标志:-O0)
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
正如@EOF 在评论中提到的,MIPS 有分支延迟槽的概念。
这是来自BNE
(强调我的)的描述:
If the contents of GPR rs and GPR rt are not equal, branch to the effective target address after the instruction in the delay slot is executed.
所以 DIV
总是被执行。您可能会想 “嗯,如果 $v0
为 0,那不是个问题吗?”。但是 DIV
的描述说:
No arithmetic exception occurs under any circumstances.
If the divisor in GPR rt is zero, the arithmetic result value is UNPREDICTABLE.
因此,在除数为零的情况下,您最终会得到不可预测的结果,我们无论如何都不会使用它,因为接下来要做的是使用 BREAK
指令触发断点异常.
来源:面向程序员的 MIPS32™ 架构第 II 卷:MIPS32™ 指令集