What is the 0x10 in the "leal 0x10(%ebx), %eax" x86 assembly instruction?
What the function is of the 0x10 in regards to this LEAL 开发者_StackOverflowinstruction? 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.
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
stands for "load effective address"; it is a way to use the sophisticated adressing modes of the IA32 instruction set to do arithmetic. The l
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 as 2.18 docs
https://sourceware.org/binutils/docs-2.18/as/i386_002dMemory.html
AT&T: -4(%ebp), Intel: [ebp - 4]
and then the Intel Syntax is self explanatory.
More importantly, the docs also explain the general case:
An Intel syntax indirect memory reference of the form
section:[base + index*scale + disp]
is translated into the AT&T syntax
section:disp(base, index, scale)
where base and index are the optional 32-bit base and index registers, disp is the optional displacement, and scale, taking the values 1, 2, 4, and 8, multiplies index to calculate the address of the operand
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.
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
精彩评论