关于这个LEAL指令,0x10的功能是什么?它是一个乘法或加法还是别的东西?
leal 0x10(%ebx), %eax
有人可以澄清一下吗?这是Linux机器上的x86汇编程序 .
leal,或lea全名是“加载有效地址”,它确实如下:它进行地址计算 .
在您的示例中,地址计算非常简单,因为它只是向ebx添加了一个偏移量并将结果存储在eax中:
eax = ebx 0x10
lea可以做更多 . 它可以添加寄存器,将寄存器与常数2,4和8相乘,用于字,整数和双精度的地址计算 . 它还可以添加偏移量 .
请注意,lea的特殊之处在于它永远不会修改标志,即使您将其用作上述示例中的简单添加项 . 编译器有时会利用此功能并用lea替换添加以帮助调度程序 . 由于这个原因,在编译代码中看到lea指令执行简单算术并不罕见 .
lea 代表"load effective address";这是一种使用IA32指令集的复杂地址模式进行算术运算的方法 . l 后缀是一种区分GNU语法中指令操作数大小的方法,就像你在Linux机器上一样 .
lea
l
所以,简而言之,是的,它是一种加法指令 . 它还可以同时处理乘法2,4或8 .
另请参见this related question(他们使用Intel语法讨论相同的指令):
GNU as 2.18 docs
https://sourceware.org/binutils/docs-2.18/as/i386_002dMemory.html
AT&T:-4(%ebp),英特尔:[ebp - 4]
然后英特尔语法是自解释的 .
更重要的是,文档还解释了一般情况:
表单的Intel语法间接内存引用
section:[base + index*scale + disp]
被翻译成AT&T语法
section:disp(base, index, scale)
其中base和index是可选的32位基数和索引寄存器,disp是可选的位移,而scale,取值1,2,4和8,乘以index来计算操作数的地址
当我们省略地址的某些部分时,例如在AT&T中,事情会变得有些混乱 . -4(%ebp) ,但是通过文档中的示例,我们可以轻松推断出所有语法案例 .
-4(%ebp)
为了真正理解发生了什么,我建议你看看如何编码指令 . 这是一个很好的教程:http://www.c-jump.com/CIS77/CPU/x86/lecture.html当你看到它时,会清楚为什么地址的某些部分可能被省略,以及每个表格将编译成什么 .
要添加Nils响应,
作为复习,IA32汇编程序中的地址模式通常具有以下形式:
IO(Rb,Ri,s),其中:
IO =立即偏移
Rb =基址寄存器
Ri =索引寄存器
s =缩放因子{1,2,4,8}
所以有效地址计算为 *IO + [Eb] + [Ei]s
leal 看起来类似于像movl这样的其他指令,但它有点特别 . 它不是从源读取到目标,而是将源的有效地址复制到目标 .
因此,它可用于为以后的内存引用生成指针,也可用于基本算术运算,如Nils所指出的那样 .
例如:
让寄存器%edx包含值x
leal 1(%edx,%edx,8),%eax
将加载1 x 8 * x = 1 9x的有效地址以注册%eax .
从本质上讲,操作:
leal source,destination => destination = address of source
如果你熟悉C,它相当于:
char * b =&a;
其中char a的地址被赋给char指针b
更多例子:
让寄存器%eax保持值x,并注册%ecx保持值y
leal (%eax,%ecx,4),%edx将值x 4y分配给寄存器%edx
leal 0xB(,%ecx,5),%edx将值0xB 5y = 11 5y分配给%edx
leal (%eax,%eax,2),%eax将值3x分配给寄存器%eax
希望这可以帮助
4 回答
leal,或lea全名是“加载有效地址”,它确实如下:它进行地址计算 .
在您的示例中,地址计算非常简单,因为它只是向ebx添加了一个偏移量并将结果存储在eax中:
eax = ebx 0x10
lea可以做更多 . 它可以添加寄存器,将寄存器与常数2,4和8相乘,用于字,整数和双精度的地址计算 . 它还可以添加偏移量 .
请注意,lea的特殊之处在于它永远不会修改标志,即使您将其用作上述示例中的简单添加项 . 编译器有时会利用此功能并用lea替换添加以帮助调度程序 . 由于这个原因,在编译代码中看到lea指令执行简单算术并不罕见 .
lea
代表"load effective address";这是一种使用IA32指令集的复杂地址模式进行算术运算的方法 .l
后缀是一种区分GNU语法中指令操作数大小的方法,就像你在Linux机器上一样 .所以,简而言之,是的,它是一种加法指令 . 它还可以同时处理乘法2,4或8 .
另请参见this related question(他们使用Intel语法讨论相同的指令):
GNU as 2.18 docs
https://sourceware.org/binutils/docs-2.18/as/i386_002dMemory.html
然后英特尔语法是自解释的 .
更重要的是,文档还解释了一般情况:
当我们省略地址的某些部分时,例如在AT&T中,事情会变得有些混乱 .
-4(%ebp)
,但是通过文档中的示例,我们可以轻松推断出所有语法案例 .为了真正理解发生了什么,我建议你看看如何编码指令 . 这是一个很好的教程:http://www.c-jump.com/CIS77/CPU/x86/lecture.html当你看到它时,会清楚为什么地址的某些部分可能被省略,以及每个表格将编译成什么 .
要添加Nils响应,
作为复习,IA32汇编程序中的地址模式通常具有以下形式:
IO(Rb,Ri,s),其中:
IO =立即偏移
Rb =基址寄存器
Ri =索引寄存器
s =缩放因子{1,2,4,8}
所以有效地址计算为 *IO + [Eb] + [Ei]s
leal 看起来类似于像movl这样的其他指令,但它有点特别 . 它不是从源读取到目标,而是将源的有效地址复制到目标 .
因此,它可用于为以后的内存引用生成指针,也可用于基本算术运算,如Nils所指出的那样 .
例如:
让寄存器%edx包含值x
leal 1(%edx,%edx,8),%eax
将加载1 x 8 * x = 1 9x的有效地址以注册%eax .
从本质上讲,操作:
leal source,destination => destination = address of source
如果你熟悉C,它相当于:
char * b =&a;
其中char a的地址被赋给char指针b
更多例子:
让寄存器%eax保持值x,并注册%ecx保持值y
leal (%eax,%ecx,4),%edx将值x 4y分配给寄存器%edx
leal 0xB(,%ecx,5),%edx将值0xB 5y = 11 5y分配给%edx
leal (%eax,%eax,2),%eax将值3x分配给寄存器%eax
希望这可以帮助