Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于LEA的gcc优化_Gcc_Assembly_Optimization - Fatal编程技术网

基于LEA的gcc优化

基于LEA的gcc优化,gcc,assembly,optimization,Gcc,Assembly,Optimization,我正在摆弄gcc的优化选项,发现以下几行: int bla(int moo) { return moo * 384; } 翻译为: 0: 8d 04 7f lea (%rdi,%rdi,2),%eax 3: c1 e0 07 shl $0x7,%eax 6: c3 retq 我知道移位表示2^7的乘法。第一行必须是3的乘法 所以,我完全被“lea”这句话弄糊涂了。

我正在摆弄gcc的优化选项,发现以下几行:

int bla(int moo) {
  return moo * 384;
}
翻译为:

0:   8d 04 7f                lea    (%rdi,%rdi,2),%eax
3:   c1 e0 07                shl    $0x7,%eax
6:   c3                      retq
我知道移位表示2^7的乘法。第一行必须是3的乘法

所以,我完全被“lea”这句话弄糊涂了。lea不应该加载地址吗?

lea(%ebx,%esi,2),%edi
只做计算
ebx+esi*2
并将结果存储在
edi

即使
lea
设计用于计算和存储有效地址,它也可以而且经常被用作优化技巧,对非内存地址的内容执行计算

lea    (%rdi,%rdi,2),%eax
shl    $0x7,%eax
相当于:

eax = rdi + rdi*2;
eax = eax * 128;

由于
moo
位于
rdi
中,它将
moo*384
存储在
eax

中,这是x86内核上的标准优化技巧。AGU(地址生成单元)是处理器中生成地址的子部分,能够进行简单的算术运算。它不是一个成熟的ALU,但有足够的晶体管来计算索引和缩放地址。添加和移动。LEA,Load有效地址指令是在AGU中调用逻辑并使其计算简单表达式的一种方法

这里的优化机会是AGU独立于ALU运行。所以你可以得到超标量执行,两条指令同时执行


这在代码片段中并不明显,但如果在所显示的需要ALU的指令之前进行计算,则可能会发生这种情况。这是一个只有在更简单的cpu核心486和Pentium vintage上才真正得到回报的把戏。现代处理器有多个ALU,因此不再需要这种技巧。

非常感谢!我知道你可以在不改变标志之类的情况下用lea做一些欺骗的事情,但是为了完整性,这个…地址操作数获取的语法是:±d(A,B,C),它将被转换成±d+B*CBy。顺便说一句,唯一使用AGU的
lea
的现代CPU是Intel Atom。在所有其他现代CPU上,它都被分配给ALU。但是,它仍然很有用,因为它结合了多个操作,具有任意输出寄存器,并且不改变标志。此外,这种形式(64位地址,32位结果)是64位模式下
lea
的最短编码。还请注意,移位通常比
IMUL
快;用移位替换“乘以常数”也是许多CPU的常见优化。启用它的精确GCC优化标志是什么(例如,
-fuse lea
,由
-O3
表示)。