linux-assembly.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Question about GCC and stack
@ 2005-09-12  6:50 James Colannino
  0 siblings, 0 replies; 5+ messages in thread
From: James Colannino @ 2005-09-12  6:50 UTC (permalink / raw
  To: linux-assembly

Hey everyone.  First off, I just wanted to say hi as this is the first 
time I've posted to this list.  I've been subscribed for a while and 
have been archiving the messages, but haven't said anything because I 
haven't really begun to get started in Assembly until recently.  Now 
that I'm posting you can expect more messages from me in the future :)  
Hopefully I won't be too annoying ;)

That being said,  I have some questions regarding the way GCC handles 
the stack when it initializes a function.  Consider the following code 
(AT&T syntax; output from gcc -S sourcefile.c):

pushl   %ebp
movl    %esp, %ebp
subl    $8, %esp
andl    $-16, %esp
movl    $0, %eax
subl    %eax, %esp
leave

This was generated from an empty main() function initialized like so:

sourcefile.c:

int main() {
}

I understand that GCC, at least under Linux, has an unusual way of 
entering into a function (which, as I understand, is why it doesn't use 
the enter instruction.)  I'm trying to figure out exactly what's going 
on here in detail.  I can piece together some things but am having 
trouble understanding this conceptually.   I know that esp points to the 
top of the stack.  I also see that first the value in ebp (the first 
instruction) is being pushed onto the stack, which I'm guessing has 
something to do with the program creating an activation record (I know 
very little about activation records however.)  But, I don't know what 
the register ebp is for.  I googled around and found that it is "used on 
intel CPU's to store the Stack Frame Pointer (sometimes called the Base 
Pointer), " but then I have no idea what the stack frame pointer is, so 
that wasn't of much help to me.  I then see that the value esp is being 
copied to ebp.  I'm not quite sure what that does, probably in part 
because I don't know what the stack frame pointer is or what it's for.  
Is it copying the address of the top of the stack ebp?  Why?  I then see 
that the instruction "subl $8, esp" subtracts 8 from the top of the 
stack's address.  I'm not sure however why this is done.  I have no idea 
what the andl instruction is for other than it ANDs the bits (I'm very 
fuzzy on my understanding of bits.)  I know it's used to mask bits out, 
but again, I'm not sure why this would need to be done here.  The last 
two instructions before "leave" looks like they return a default integer 
value of 0, which I'd expect GCC to do.

I hope these questions aren't too stupid or uneducated.  I'm just 
beginning and have a lot to learn.  If you don't mind endulging a 
curious mind's questions I'd be very grateful :)  Thanks very much in 
advance.

James

-- 
My blog: http://www.crazydrclaw.com/
My homepage: http://james.colannino.org/

"You can only find truth with logic if you have already found truth without it." --G. K. Chesterton


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Question about GCC and stack
@ 2005-09-12 18:09 Tavis Ormandy
  2005-09-12 20:50 ` Brian Raiter
  2005-09-12 23:13 ` James Colannino
  0 siblings, 2 replies; 5+ messages in thread
From: Tavis Ormandy @ 2005-09-12 18:09 UTC (permalink / raw
  To: James Colannino, linux-assembly

--On Sunday, September 11, 2005 23:50:43 -0700 James Colannino
<james@colannino.org> wrote:
> I understand that GCC, at least under Linux, has an unusual way of
> entering into a function (which, as I understand, is why it doesn't use
> the enter instruction.)

Actually, I believe the enter instruction is avoided as it's considerably
slower than manually opening the frame, there's no reason you cant
substitute the enter instruction into this fragment if you wanted to.

> Is it copying the address of the top of the stack ebp?  Why?

Yes, consider that as you manipulate the stack, accessing arguments and
local variables stored there can get complicated as you normally access
them  as offset to the sp, for example, sp+4, sp-16, etc.

Obviously some object at sp+4 will be at sp+8 if you push some value onto
the stack, as the stack pointer will have moved. In a complex function this
could become unmanageable (at least to a human programmer, gcc can handle
this in order to gain an extra free register, but at some sacrifice).

The function prologue backs up the %ebp from the caller, then copies the sp
onto it. Now stack variables and arguments are at fixed offsets from the
%ebp throughout, no matter what stack manipulation you perform.

If you try manipulating arguments/stack variables in the function and take
a look at the code generated, you will see how the frame pointer is used to
address them, eg movl -8(%ebp), %foo (for comparison, try compiling the
code with -fomit-frame-pointer).

> I then see
> that the instruction "subl $8, esp" subtracts 8 from the top of the
> stack's address.  I'm not sure however why this is done.
> I have no idea what the andl instruction is for other than it ANDs
> the bits (I'm very fuzzy on my understanding of bits.)  I know it's
> used to mask bits out, but again, I'm not sure why this would need
> to be done here.

This looks like gcc attempting to keep the stack aligned for performance
reasons. Check the gcc documentation for the -mpreferred-stack-boundary
option, which explains this behaviour.

>  The last
> two instructions before "leave" looks like they return a default integer
> value of 0, which I'd expect GCC to do.

Right, by convention the return value (if it fits) is placed into the %eax
register when the function returns to the caller, that's what it's doing.

The subl instruction is pointless, I dont know why it's inserted. It could
be just generic stub code that gcc always inserts for allocating stack
variables, but as in this case you dont use any, it allocates $0
bytes...I'm sure someone will correct me if there's a good reason for it :)

leave simply closes the stack frame, restoring the stack pointer (by
copying %ebp to %esp), then restoring the %ebp from the backup it made to
the stack when entering the function.

> I hope these questions aren't too stupid or uneducated.  I'm just
> beginning and have a lot to learn.  If you don't mind endulging a curious
> mind's questions I'd be very grateful :)  Thanks very much in advance.
> James


Hope this helps, 

Tavis.

-------------------------------------
taviso@sdf.lonestar.org | finger me for my gpg key.
-------------------------------------------------------

  

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Question about GCC and stack
  2005-09-12 18:09 Question about GCC and stack Tavis Ormandy
@ 2005-09-12 20:50 ` Brian Raiter
  2005-09-12 23:15   ` James Colannino
  2005-09-12 23:13 ` James Colannino
  1 sibling, 1 reply; 5+ messages in thread
From: Brian Raiter @ 2005-09-12 20:50 UTC (permalink / raw
  To: linux-assembly

> The subl instruction is pointless, I dont know why it's inserted. It
> could be just generic stub code that gcc always inserts for
> allocating stack variables, but as in this case you dont use any, it
> allocates $0 bytes...I'm sure someone will correct me if there's a
> good reason for it :)

I expect that the instructions obtained by the original poster were
created by gcc without optimization. Run gcc with -O2 or so would
probably yield a simpler set of instructions.

b

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Question about GCC and stack
  2005-09-12 18:09 Question about GCC and stack Tavis Ormandy
  2005-09-12 20:50 ` Brian Raiter
@ 2005-09-12 23:13 ` James Colannino
  1 sibling, 0 replies; 5+ messages in thread
From: James Colannino @ 2005-09-12 23:13 UTC (permalink / raw
  To: linux-assembly

Tavis Ormandy wrote:

>Hope this helps
>  
>

That was very good information.  Thank you :)

James

-- 
My blog: http://www.crazydrclaw.com/
My homepage: http://james.colannino.org/

"You can only find truth with logic if you have already found truth without it." --G. K. Chesterton


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Question about GCC and stack
  2005-09-12 20:50 ` Brian Raiter
@ 2005-09-12 23:15   ` James Colannino
  0 siblings, 0 replies; 5+ messages in thread
From: James Colannino @ 2005-09-12 23:15 UTC (permalink / raw
  To: linux-assembly

Brian Raiter wrote:

>>The subl instruction is pointless, I dont know why it's inserted. It
>>could be just generic stub code that gcc always inserts for
>>allocating stack variables, but as in this case you dont use any, it
>>allocates $0 bytes...I'm sure someone will correct me if there's a
>>good reason for it :)
>>    
>>
>
>I expect that the instructions obtained by the original poster were
>created by gcc without optimization. Run gcc with -O2 or so would
>probably yield a simpler set of instructions.
>  
>

It was without -O2, but when I used -O2, the code was pretty much the 
same.  The only difference was that instead of moving the value 0 into 
eax, xor eax, eax was used to mask out all the bits (equalling 0, and 
I'm assuming that's probably slightly more efficient than moving a value 
into a register.)  Also, instead of the leave instruction, the ebp and 
esp were manipulated manually, I guess because maybe the leave 
instruction, like the enter instruction, is slower?

James

-- 
My blog: http://www.crazydrclaw.com/
My homepage: http://james.colannino.org/

"You can only find truth with logic if you have already found truth without it." --G. K. Chesterton


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2005-09-12 23:15 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-09-12 18:09 Question about GCC and stack Tavis Ormandy
2005-09-12 20:50 ` Brian Raiter
2005-09-12 23:15   ` James Colannino
2005-09-12 23:13 ` James Colannino
  -- strict thread matches above, loose matches on Subject: below --
2005-09-12  6:50 James Colannino

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).