我正在查看通过反汇编一些C程序生成的一些程序集,我对我经常重复看到的单个优化感到困惑。
当我没有对GCC编译器进行优化时,使用subl
指令进行减法,但是当我确实打开了优化(-O3
为准确)时,编译器使用leal
指令而不是减法,例如:
没有优化:
83 e8 01 subl $0x1, %eax
优化
8d 6f ff leal -0x1(%edi), %ebp
这两条指令都是3个字节长,所以我没有在这里看到优化。有人可以帮助我并尝试解释编译器的选择吗?
任何帮助都将不胜感激。
答案 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 更新标志也会更有效。