“leal 0x10(%ebx), %eax”中的 0x10 是什么? x86汇编指令?
对于这条 LEAL 指令,0x10 的作用是什么?是乘法、加法还是其他什么?
leal 0x10(%ebx), %eax
有人可以澄清一下吗?这是 Linux 机器上的 x86 汇编器。
What the function is of the 0x10 in regards to this LEAL instruction? Is it a multiply or addition or is something else?
leal 0x10(%ebx), %eax
Can someone please clarify? This is x86 assembler on a Linux box.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
leal 或 lea 全称是“加载有效地址”,它的作用正是如此:它进行地址计算。
在您的示例中,地址计算非常简单,因为它只是向 ebx 添加偏移量并将结果存储在 eax 中:
eax = ebx + 0x10
lea 可以做更多事情。它可以将寄存器与常量 2、4 和 8 相加、相乘,以进行字、整数和双精度数的地址计算。它还可以添加偏移量。
请注意,lea 的特殊之处在于它永远不会修改标志,即使您将其用作简单的添加(如上例所示)。编译器有时会利用此功能并用 lea 替换添加项以帮助调度程序。由于这个原因,在编译代码中执行简单算术的 lea 指令并不罕见。
leal, or lea full name is "Load effective address" and it does exactly this: It does an address calculation.
In your example the address calculation is very simple, because it just adds a offset to ebx and stores the result in eax:
eax = ebx + 0x10
lea can do a lot more. It can add registers, multiply registers with the constants 2, 4 and 8 for address calculations of words, integers and doubles. It can also add an offset.
Note that lea is special in the way that it will never modify the flags, even if you use it as a simple addition like in the example above. Compilers sometimes exploit this feature and replace an addition by a lea to help the scheduler. It's not uncommon to see lea instructions doing simple arithmetic in compiled code for that reason.
lea
代表“加载有效地址”;它是一种使用 IA32 指令集的复杂寻址模式进行算术运算的方法。l
后缀是一种区分 Linux 机器上 GNU as 语法中指令操作数大小的方法。所以,简而言之,是的,这是一种加法指令。它还可以同时处理 2、4 或 8 的乘法。
另请参阅此相关问题(他们在哪里使用讨论相同指令的英特尔语法):
lea
stands for "load effective address"; it is a way to use the sophisticated adressing modes of the IA32 instruction set to do arithmetic. Thel
suffix is a way to distinguish the size of instruction operands in the syntax of GNU as, that you have on your Linux box.So, in short, yes, it's a kind of addition instruction. It can also handle multiplications by 2, 4, or 8 at the same time.
See also this related question (where they are using the Intel syntax to discuss the same instruction):
GNU 作为 2.18 文档
https://sourceware.org/ binutils/docs-2.18/as/i386_002dMemory.html
然后 Intel 语法是不言自明的。
更重要的是,文档还解释了一般情况:
。当我们省略地址的某些部分时,例如
-4(%ebp)
,AT&T 中会很混乱,但是通过文档中的示例,我们可以轻松推断出所有语法情况。为了真正理解正在发生的事情,我建议您看一下指令是如何编码的。这是一个很好的教程:http://www.c-jump.com /CIS77/CPU/x86/lecture.html 当您看到这一点时,就会清楚为什么地址的某些部分可能被省略,以及每个表单将编译成什么。
GNU as 2.18 docs
https://sourceware.org/binutils/docs-2.18/as/i386_002dMemory.html
and then the Intel Syntax is self explanatory.
More importantly, the docs also explain the general case:
Things do get a bit messy in AT&T when we omit some parts of the address, e.g.
-4(%ebp)
, but with the examples in the docs we can easily deduce all the syntax cases.To really understand what is going on, I recommend that you take a look at how instructions are encoded. This is a good tutorial: http://www.c-jump.com/CIS77/CPU/x86/lecture.html When you see that, it will become clear why some parts of the address may be omitted, and what each form will compile to.
为了补充 Nils 响应,
回顾一下,IA32 汇编器中的寻址模式通常采用以下形式:
IO(Rb, Ri, s),其中:
IO = 立即偏移
Rb = 基址寄存器
Ri = 索引寄存器
s = 缩放因子 { 1, 2, 4, 8}
因此,有效地址计算为 *IO + [Eb] + [Ei]s
leal 看起来很相似与movl等其他指令不同,但它有点特殊。
它不是从源读取到目标,而是复制有效的
源地址到目的地址。
所以它可以用来生成以后内存引用的指针,也可以
正如尼尔斯指出的,用于基本算术运算。
例如:
让寄存器%edx包含x的值
leal 1(%edx, %edx, 8),%eax
将加载有效地址1 + x + 8*x = 1 + 9x注册%eax。
本质上,操作:
leal source, destination => 目的地 = 地址 源
如果您熟悉 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 strong> (%eax, %eax,2), %eax 会将值 3x 分配给寄存器 %eax
希望这会有所帮助
To add to Nils response,
As a refresher, the addresing mode in IA32 assembler is generally of the form:
IO(Rb, Ri, s), where:
IO = Immediate Offset
Rb = Base Register
Ri = Index Register
s = Scaling Factor {1, 2, 4, 8}
So the effective address is computed as *IO + [Eb] + [Ei]s
leal looks similar to other instructions like movl, but it is a bit special.
Instead of reading from the source to the destination, it copies the effective
address of the source to the destination.
So it can be used to generate pointers for later memory references, and also
for basic arithmetic operations, as Nils pointed out.
For example:
let register %edx contain a value of x
leal 1(%edx, %edx, 8), %eax
will load the effective address of 1 + x + 8*x = 1 + 9x to register %eax.
In essence, the operation:
leal source, destination => destination = address of source
If you're familiar with C, it is the equivalent of :
char * b = &a;
where the address of char a is assigned to char pointer b
more examples:
Let register %eax hold value x, and register %ecx hold value y
leal (%eax, %ecx, 4), %edx will assign the value x + 4y to register %edx
leal 0xB(, %ecx, 5), %edx will assign the value 0xB + 5y = 11 + 5y to %edx
leal (%eax, %eax,2), %eax will assign the value 3x to register %eax
Hope this helps