最近恶补汇编时发现lea指令很有意思, 但大部分书都把它一笔带过, 同时网上的资料又很少, 所以记一下.

lea, load effective address, 加载有效地址. 指令形式是从存储器读数据到寄存器, 效果是将存储器的有效地址写入到目的操作数, 简单说, 就是C语言中的”&”.

例如在32位环境下, 有内存位置标签foo, 则下面两行效果相同:

movl $foo, %edi
leal foo, %edi

同时, lea还有个很有用但同时又很难理解的用法, 例如这样:

leal 5(%edx, %edx, 2), %eax

假设%edx的值为x, 上面这行会将%eax的值设置为”3x+5”.

奇怪吧, 一个取址的指令怎么用来做简单算术操作了? 其实理解起来也不难, 5(%edx, %edx, 2)是存储器”3x+5”这个地址中的值, 这个值作为leal的源操作数会被取地址, 地址是什么? 自然就是”3x+5”!

值得注意的是, 不管是AT&T还是Intel语法, lea都是加载有效地址, 所以运算结果需得在地址空间能表示的大小范围内.

PS: 可能有人会问为什么不把源操作数写成5(, %edx, 3), 这个嘛, 因为这种寻址模式的比例因子只能是1, 2, 4或者8.