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

Hun*_*len 10 x86 assembly gcc gnu-assembler compiler-optimization

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

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

没有优化:

83 e8 01     subl $0x1, %eax 
Run Code Online (Sandbox Code Playgroud)

优化

8d 6f ff     leal -0x1(%edi), %ebp 
Run Code Online (Sandbox Code Playgroud)

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

任何帮助,将不胜感激.

Mys*_*ial 14

没有看到产生这个的原始C代码就很难分辨.

但是,如果我不得不猜测,这是因为leal允许减法在不破坏源寄存器的情况下进行.

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


第一个例子:

83 e8 01     subl $0x1, %eax 
Run Code Online (Sandbox Code Playgroud)

覆盖%eax从而破坏原始价值.

第二个例子:

8d 6f ff     leal -0x1(%edi), %ebp 
Run Code Online (Sandbox Code Playgroud)

商店%edi - 1进入%ebp.%edi保留供将来使用.


Doc*_*Max 10

请记住,lea这不会影响标志,sub而是.因此,如果随后的指令不依赖于减法更新的标志,则不更新标志也将更有效.