I'm learning gas currently and investigating the differences in
assembler being generated from C when running through an array using
indexing or pointers.
my little function to test the indexing looks like:
<findex.c>
int findex(int* array, int size)
{
int result = 0 ;
int i = 0 ;
for( ; i < size ; ++i ) result += array[i] ;
return result ;
}
</findex.c>
now the assembler being generated for that (using gcc -S findex.c using
gcc 3.4.3) looks like:
<assembler>
.file "findex.c"
.text
..globl findex
.type findex, @function
findex:
pushl %ebp
movl %esp,%ebp
subl $8, %esp
movl $0, -4(%ebp)
movl $0, -8(%ebp)
..L2:
movl -8(%ebp), %eax
cmpl 12(%ebp), %eax
jge .L3
movl -8(%ebp), %eax
leal 0(,%eax,4), %edx
movl 8(%ebp), %eax
movl (%edx,%eax), %edx
leal -4(%ebp), %eax
addl %edx, (%eax)
leal -8(%ebp), %eax
incl (%eax)
jmp .L2
..L3:
movl -4(%ebp),%eax
leave
ret
</assembler>
My question now is, what does the 5th instruction of .L2 do (i.e. 'leal
0(,%eax,4),%edx'). Especially the '0' in '0(,%eax,4)' confuses me. I've
seen in many textbooks how to address arrays using the base (which is
generally a global variable) but here the base is '0'. What does that
stand for?
Thanks in advance for any clarification!
|
|
0
|
|
|
|
Reply
|
Toon
|
4/7/2006 12:04:46 PM |
|
"Toon Knapen" <spamtrap@crayne.org> wrote in message
news:44365557$0$448$6c56d894@reader0.news.be.easynet.net...
> I'm learning gas currently and investigating the differences in
> assembler being generated from C when running through an array using
> indexing or pointers.
<snip>
>
> My question now is, what does the 5th instruction of .L2 do (i.e. 'leal
> 0(,%eax,4),%edx'). Especially the '0' in '0(,%eax,4)' confuses me. I've
> seen in many textbooks how to address arrays using the base (which is
> generally a global variable) but here the base is '0'. What does that
> stand for?
>
?
There is no base in 'leal 0(,%eax,4),%edx'. It's missing, i.e., between the
paren and comma. If there was a base, it'd look like something like this:
'leal 0(%ebx,%eax,4),%edx'
You might be confusing AT&T and Intel syntax. If so, this is worth a read:
http://www.delorie.com/djgpp/doc/brennan/brennan_att_inline_djgpp.html
On memory addressing, from Brennan's page:
"...
AT&T: immed32(basepointer,indexpointer,indexscale)
Intel: [basepointer + indexpointer*indexscale + immed32]
You could think of the formula to calculate the address as:
immed32 + basepointer + indexpointer * indexscale
"
IIRC, the indexscale must be 1,2,4,or 8.
The indexpointer is any register except esp.
The basepointer is any register.
And, immed32 is a 32-bit value (apparently, a signed value(?)... Could
someone clarify?)
For GAS, WASM (MASM like), and NASM respectively, the 'lea' instruction is
in these formats.
leal -4(%ecx,%ebx,2), %eax
lea eax,-0x4[ecx+ebx*2]
lea eax,[ecx+ebx*2-0x4]
Rod Pemberton
|
|
0
|
|
|
|
Reply
|
Rod
|
4/8/2006 8:16:41 AM
|
|
Rod Pemberton wrote:
> ?
> There is no base in 'leal 0(,%eax,4),%edx'. It's missing, i.e., between the
> paren and comma. If there was a base, it'd look like something like this:
> 'leal 0(%ebx,%eax,4),%edx'
>
> You might be confusing AT&T and Intel syntax. If so, this is worth a read:
> http://www.delorie.com/djgpp/doc/brennan/brennan_att_inline_djgpp.html
>
> On memory addressing, from Brennan's page:
> "...
> AT&T: immed32(basepointer,indexpointer,indexscale)
> Intel: [basepointer + indexpointer*indexscale + immed32]
>
> You could think of the formula to calculate the address as:
> immed32 + basepointer + indexpointer * indexscale
> "
>
> IIRC, the indexscale must be 1,2,4,or 8.
> The indexpointer is any register except esp.
> The basepointer is any register.
> And, immed32 is a 32-bit value (apparently, a signed value(?)... Could
> someone clarify?)
I'm sorry for the confusion because my terminology is a bit different. I
got my terminology from the book 'professional assembly language' of
Richard Blum. There it says that the expression is:
base_address(offset_addres,index,size)
Nevertheless, IIUC
'leal 0(,%eax,4),%edx'
is identical to
'leal (,%eax,4),%edx'
And IIUC this instruction will store the address of the eax register
into edx, right?
|
|
0
|
|
|
|
Reply
|
Toon
|
4/10/2006 7:34:21 AM
|
|
"Toon Knapen" <spamtrap@crayne.org> wrote in message
news:443a0a7d$0$438$6c56d894@reader0.news.be.easynet.net...
> Rod Pemberton wrote:
>
> > ?
> > There is no base in 'leal 0(,%eax,4),%edx'. It's missing, i.e., between
the
> > paren and comma. If there was a base, it'd look like something like
this:
> > 'leal 0(%ebx,%eax,4),%edx'
> >
> > You might be confusing AT&T and Intel syntax. If so, this is worth a
read:
> > http://www.delorie.com/djgpp/doc/brennan/brennan_att_inline_djgpp.html
> >
> > On memory addressing, from Brennan's page:
> > "...
> > AT&T: immed32(basepointer,indexpointer,indexscale)
> > Intel: [basepointer + indexpointer*indexscale + immed32]
> >
> > You could think of the formula to calculate the address as:
> > immed32 + basepointer + indexpointer * indexscale
> > "
> >
> > IIRC, the indexscale must be 1,2,4,or 8.
> > The indexpointer is any register except esp.
> > The basepointer is any register.
> > And, immed32 is a 32-bit value (apparently, a signed value(?)... Could
> > someone clarify?)
>
>
> I'm sorry for the confusion because my terminology is a bit different. I
> got my terminology from the book 'professional assembly language' of
> Richard Blum. There it says that the expression is:
> base_address(offset_addres,index,size)
>
> Nevertheless, IIUC
> 'leal 0(,%eax,4),%edx'
> is identical to
> 'leal (,%eax,4),%edx'
>
> And IIUC this instruction will store the address of the eax register
> into edx, right?
The purpose of 'lea' is to allow pointer and array arithmetic without
destroying any registers. Unfortunately or fortunately, the format is the
same as all the other instructions which work with data not adresses. The
benefit is that some simple arithmetic operations can be performed quickly
with any need for push/pop or mov's.
I haven't actually used lea that much, but my understanding is that 'leal
(,%eax,4),%edx' will move the value in eax multiplied by 4 into edx, i.e.,
in C, edx=eax*4; The "memory" reference on the 'lea' instruction probably
shouldn't be thought of as an actually a memory address or reference. It's
more like: "load this register with the address of this data which is at
this address that I've provided with this computation." You're already
supplying the address... i.e., it's the value being computed with the two
registers, offset, and multiplier.
To move the value in eax into edx, would be:
'leal (%eax,,),%edx
To move the value in 2 into edx, would be:
'leal 2(,,),%edx
To move the sum of eax+ebx into edx, would be:
'leal (%eax,%ebx,),%edx
To move 2*ebx into edx, would be:
'leal (,%ebx,2),%edx
To move the sum of eax+2*ebx into edx, would be:
'leal (%eax,%ebx,2),%edx
To move the sum of eax+4*ebx+3 into edx, would be:
'leal 3(%eax,%ebx,4),%edx
Rod Pemberton
|
|
0
|
|
|
|
Reply
|
Rod
|
4/11/2006 1:01:48 AM
|
|
Rod Pemberton wrote:
> I haven't actually used lea that much, but my understanding is that 'leal
> (,%eax,4),%edx' will move the value in eax multiplied by 4 into edx, i.e.,
> in C, edx=eax*4; The "memory" reference on the 'lea' instruction probably
> shouldn't be thought of as an actually a memory address or reference. It's
> more like: "load this register with the address of this data which is at
> this address that I've provided with this computation." You're already
> supplying the address... i.e., it's the value being computed with the two
> registers, offset, and multiplier.
>
>
Thanks for your replies. I finally understand now that the lea
instruction is used to multiply the index of the array by 4 (because it
's an array of 32bit int's) and store it in %edx.
Apparantly lea is very fast and as you say does not need extra
registers. Thanks again.
toon
|
|
0
|
|
|
|
Reply
|
Toon
|
4/11/2006 11:41:16 AM
|
|
Rod Pemberton wrote:
> I haven't actually used lea that much, but my understanding is that 'leal
> (,%eax,4),%edx' will move the value in eax multiplied by 4 into edx, i.e.,
> in C, edx=eax*4; The "memory" reference on the 'lea' instruction probably
> shouldn't be thought of as an actually a memory address or reference. It's
> more like: "load this register with the address of this data which is at
> this address that I've provided with this computation." You're already
> supplying the address... i.e., it's the value being computed with the two
> registers, offset, and multiplier.
>
>
Thanks for your replies. I finally understand now that the lea
instruction is used to multiply the index of the array by 4 (because it
's an array of 32bit int's) and store it in %edx.
Apparantly lea is very fast and as you say does not need extra
registers. Thanks again.
toon
|
|
0
|
|
|
|
Reply
|
Toon
|
4/11/2006 11:41:54 AM
|
|
|
5 Replies
242 Views
(page loaded in 0.086 seconds)
|