LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 06-23-2006, 01:25 PM   #1
Mercurius
Member
 
Registered: Jul 2005
Distribution: Slackware 11, Solaris 10
Posts: 143

Rep: Reputation: 15
ASM and Stack Questions


#include <stdio.h>

void function(int a, int b, int c)
{
char buff[4];
}

int main()
{
function(1, 2, 3);
}

0x0804835c <main+0>: push %ebp
0x0804835d <main+1>: mov %esp,%ebp
0x0804835f <main+3>: sub $0x8,%esp //why substract 8 from esp??
0x08048362 <main+6>: and $0xfffffff0,%esp
0x08048365 <main+9>: mov $0x0,%eax
0x0804836a <main+14>: sub %eax,%esp
0x0804836c <main+16>: sub $0x4,%esp //why substract 4 from esp??
0x0804836f <main+19>: push $0x3
0x08048371 <main+21>: push $0x2
0x08048373 <main+23>: push $0x1
0x08048375 <main+25>: call 0x8048354 <function>
0x0804837a <main+30>: add $0x10,%esp //and then why add back 16 or 0x10 to esp??
0x0804837d <main+33>: leave
0x0804837e <main+34>: ret

1. what the lines 0x08048362, 0x08048365, 0x0804836a ??
2. why not substract 0x12 or 18 in one single instruction? why does it substract 18?
3. why do we add 16 to esp at the end of the call? I mean should it not be before the call? You allready pused 3, 2, 1 on the stack, so does the push not automaticaly store the numbers? I mean why allocate space AFTER you pushed something on the stack, since by pushing it is already on the stack occuping space. And why 16 since an int is 4 bytes and we need only 12 ... ?
 
Old 06-23-2006, 01:46 PM   #2
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,659
Blog Entries: 4

Rep: Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939
The compiler never promised that the code it generates would be identical to your source-code, only that it would do the same thing. Depending on the optimization-level used, machine-specific flags and so forth, the code might be substantially different.

For example, on many processor-types there are things like "cache lines" and the internal bus-width of the processor to think about. Multiples of 16 bytes (that is, addresses which fall on 16-byte boundaries) might be more efficiently handled by the CPU than other widths, so the compiler might "round up."

Then there are "calling conventions" to consider: who reserves space on the stack for a function, and when, and then ditto for cleaning-up. This is why the stack-management instructions occur when and where they do.
 
Old 06-23-2006, 02:20 PM   #3
Mercurius
Member
 
Registered: Jul 2005
Distribution: Slackware 11, Solaris 10
Posts: 143

Original Poster
Rep: Reputation: 15
Ok, then how do I visualize correctly the stack and where the so called "junk" is? I mean in my case the stack for main would be ...

$1 - this would be 4 bytes ... ?
$2 - this would be also 4 bytes ...
$3 - the same ...
RET - always 4
EBP - always 4
buff - and this should would be 4


Well, basicly, if there are so many options and architectures and methods, how do you visualize the stack? I searched for a software to help that, but I seemed to fine none. I think I must master it myself right ... ?
 
Old 06-23-2006, 02:33 PM   #4
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,659
Blog Entries: 4

Rep: Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939
"It just works." What you'll find, when any function is running, is something like this ...


<<parameters>>
<<stack frame>>
<<local variables>>
<<possible empty space here>>
<<temporary stuff from moment to moment>>


As I said, calling-conventions vary as to who is responsible for setting up the stack-frame, in which order the parameters get pushed onto the stack, and who cleans-up these various things (the caller or the callee). It's quite common to see optimizers deliberately add "extra" space here and there, e.g. to preserve alignment, because the internal on-chip buses of modern CPUs are very wide and favor certain alignments. Or there could be other reasons known only to folks like Richard Stallman.

So, fiddle with your program in various ways and notice how the assembly-code that is generated changes. Enjoy.
 
Old 06-24-2006, 09:31 AM   #5
Mercurius
Member
 
Registered: Jul 2005
Distribution: Slackware 11, Solaris 10
Posts: 143

Original Poster
Rep: Reputation: 15
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv[])
{
char buff[512];

if (argc < 2)
{
printf("Usage: %s <string>\n", argv[0]);
exit(1);
}
strcpy(buff, argv[1]);
printf("Buffer: %s\n", buff);

return 0;
}

0x080483f4 <main+0>: push %ebp
0x080483f5 <main+1>: mov %esp,%ebp
0x080483f7 <main+3>: sub $0x208,%esp
0x080483fd <main+9>: and $0xfffffff0,%esp
0x08048400 <main+12>: mov $0x0,%eax
0x08048405 <main+17>: sub %eax,%esp
0x08048407 <main+19>: cmpl $0x1,0x8(%ebp)
0x0804840b <main+23>: jg 0x804842c <main+56>
0x0804840d <main+25>: sub $0x8,%esp
0x08048410 <main+28>: mov 0xc(%ebp),%eax
0x08048413 <main+31>: pushl (%eax)
0x08048415 <main+33>: push $0x8048584
0x0804841a <main+38>: call 0x80482f8 <printf@plt>
0x0804841f <main+43>: add $0x10,%esp
0x08048422 <main+46>: sub $0xc,%esp
0x08048425 <main+49>: push $0x1
0x08048427 <main+51>: call 0x8048308 <exit@plt>
0x0804842c <main+56>: sub $0x8,%esp
0x0804842f <main+59>: mov 0xc(%ebp),%eax
0x08048432 <main+62>: add $0x4,%eax
0x08048435 <main+65>: pushl (%eax)
0x08048437 <main+67>: lea 0xfffffdf8(%ebp),%eax
0x0804843d <main+73>: push %eax
0x0804843e <main+74>: call 0x8048318 <strcpy@plt>
0x08048443 <main+79>: add $0x10,%esp
0x08048446 <main+82>: sub $0x8,%esp
0x08048449 <main+85>: lea 0xfffffdf8(%ebp),%eax
0x0804844f <main+91>: push %eax
0x08048450 <main+92>: push $0x8048598
0x08048455 <main+97>: call 0x80482f8 <printf@plt>
0x0804845a <main+102>: add $0x10,%esp
0x0804845d <main+105>: mov $0x0,%eax
0x08048462 <main+110>: leave
0x08048463 <main+111>: ret

How would the stack look here? Should it not be ... ?

argv[0]
argv[1]
RET
EBP
char buff[512]
 
Old 06-24-2006, 02:00 PM   #6
paulsm4
LQ Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Hi -

This book might help:
Programming From The Ground Up, Jonathan Bartlett
http://www.amazon.com/gp/product/097...lance&n=283155

It's also available as a free download:
http://savannah.nongnu.org/projects/pgubook/

Your real question has less to do with assembly-language syntax than with simply trying to understand how and why the x86/C language stack works. That's definitely a commendable goal. I think Mr. Bartlett's book will help - with this, and with future questions you'll undoubtedly have.

Check it out - I think you'll like it.
 
Old 06-26-2006, 11:30 PM   #7
Mercurius
Member
 
Registered: Jul 2005
Distribution: Slackware 11, Solaris 10
Posts: 143

Original Poster
Rep: Reputation: 15
Thanks a lot, I began studying it, I like it indeed, very clear and concise.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Difference b/t Kernel stack and User stack hazzyb Linux - Software 2 09-29-2008 07:40 PM
stack organization questions 0x0000h Linux - Security 2 08-26-2005 11:04 AM
Have you seen such asm code? snowing Programming 2 07-07-2005 05:13 AM
Linux 32 ASM introuble Programming 2 05-10-2005 06:56 AM
How to use C functions in asm? LongName Programming 4 08-29-2004 12:25 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 03:44 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration