为什么GCC会为减法发出“lea”而不是“sub”?

时间:2012-10-02 01:21:26

标签: gcc assembly x86 compiler-optimization gas

我正在查看通过反汇编一些C程序生成的一些程序集,我对我经常重复看到的单个优化感到困惑。

当我没有对GCC编译器进行优化时,使用subl指令进行减法,但是当我确实打开了优化(-O3为准确)时,编译器使用leal指令而不是减法,例如:

没有优化:

83 e8 01     subl $0x1, %eax 

优化

8d 6f ff     leal -0x1(%edi), %ebp 

这两条指令都是3个字节长,所以我没有在这里看到优化。有人可以帮助我并尝试解释编译器的选择吗?

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:13)

如果没有看到产生这个的原始C代码,很难说清楚。

但如果我不得不猜测,那是因为leal允许减法在不破坏源寄存器的情况下完成。

这可以节省额外的寄存器移动。


第一个例子:

83 e8 01     subl $0x1, %eax 

覆盖%eax,从而破坏原始值。

第二个例子:

8d 6f ff     leal -0x1(%edi), %ebp 

%edi - 1存储到%ebp。保留%edi以供将来使用。

答案 1 :(得分:10)

请注意,lea不会影响标志而sub会影响标志。因此,如果随后的指令不依赖于减法更新的标志,那么 not 更新标志也会更有效。