gcc version 4.1.2 20070925 (Red Hat 4.1.2-33)
The reason I mention this is purely because multiple versions of code are on the Chapter 6 page; meaning that different gcc versions with different switches generate slightly different assembly. While all that is important no doubt, it isn't right now when we're taking small steps towards understanding the basics. Lets go on..Here's the edited function code that I'm using:
---------------------------------------------------------
2
3 void function3args(int a, int b , int c)
4 {
5 printf("%d %d %d\n" , a , b , c);
6 }
7
8 int main(int argc, char **argv)
9 {
10 int a;
11 int *ptr;
12 function3args(1,2,3);
13 }
---------------------------------------------------------
Like last time , lets compile it with gdb support and open up the disassembly in gdb. Oh and you have that pen and paper with those columns too..rt? ;)
[arvind@dilby ~]$ gcc -ofunc1 -ggdb functions.c
[arvind@dilby ~]$ gdb -q func1
Using host libthread_db library "/lib/libthread_db.so.1".
0x080483f1
0x080483f4
0x080483f7
0x080483f8
0x080483fa
lea 0x4(%esp),%ecx -- No change in esp
and $0xfffffff0,%esp -- Logical and changes esp to bfc49ec0
Then there are 3 push instructions which decrease the value of the stack by 12 . So after the first 6 instructions the value of ESP is bfc49eb4 ( bfc49ec0 - 12). Just before the last push ESP is saved into EBP. This value in ebp will not change at all till it is popped and the function main ends. You can check the value of esp and ebp after each instruction by using x/xw $esp and x/xw $ebp . To advance instructions type nexti.
Then there is a sub $0x24,%esp which is to allocate space for local variables on the stack. Why 0x24? Lets look at the code in main().
The 3 arguments are then pushed on to the stack . Note that the arguments are passed on to the stack in reverse.
0x080483fe
0x08048406
0x0804840e
Note down the values for esp and ebp carefully just before executing this instruction.
0x08048415
Now get the disassembly for the function - function3args and lets see what happens there:
0x080483c4
0x080483c5
Notice that the stored value of ebp which had remained constant during the lifetime of main is pushed on to the stack? And the current stack pointer made the current value of ebp? If there's another function after this, ebp will be pushed on to the stack again and so on. Once the last function completes the ebp's of each function are popped off till you reach the ebp of main at which point the program exits.
0x080483c7
Values for variables are allocated on the stack for the function function3args.
0x080483ca
0x080483cd
0x080483d1
0x080483d4
0x080483d8
0x080483db
Move the arguments of the function on to the stack.
0x080483df
0x080483e6
Call the printf function with the arguments.
0x080483eb
If you look at the value of ebp just after this instruction , you'd see its value change back to its earlier value which means this function has exited.
0x080483ec
Exit from function3args
0x0804841a
0x0804841d
0x0804841e
0x0804841f
0x08048422
Exit from main.
Hope that clarified things a little better. Next post we won't go so much into detail, we'll make a couple of assumptions based on the previous 2 posts and learn a little more. Have fun :)
No comments:
Post a Comment