为什么 GCC 发出“lea”而不是“sub”来进行减法?
-
12-12-2019 - |
题
我正在查看一些通过反汇编一些 C 程序生成的程序集,我对经常重复看到的单个优化感到困惑。
当我没有对 GCC 编译器进行优化时,使用 subl
减法指令,但是当我打开优化时(-O3
准确地说)编译器使用 leal
指令而不是减法,示例如下:
没有优化:
83 e8 01 subl $0x1, %eax
有优化
8d 6f ff leal -0x1(%edi), %ebp
这两条指令都是 3 个字节长,所以我在这里没有看到优化。有人可以帮助我并尝试解释编译器的选择吗?
任何帮助,将不胜感激。
解决方案
如果没有看到产生此结果的原始 C 代码,很难判断。
但如果我必须猜测的话 那是因为 leal
允许在不破坏源寄存器的情况下异地进行减法。
这可以节省额外的寄存器移动。
第一个例子:
83 e8 01 subl $0x1, %eax
覆盖 %eax
从而破坏了原有的价值。
第二个例子:
8d 6f ff leal -0x1(%edi), %ebp
商店 %edi - 1
进入 %ebp
. %edi
被保存以供将来使用。
其他提示
还要记住 lea
不影响标志,而 sub
做。因此,如果后续指令不依赖于通过减法更新的标志,则 不是 更新标志也会更加高效。
不隶属于 StackOverflow