Dump of assembler code for function main:
0x0804833e <+0>: push %ebp
0x0804833f <+1>: mov %esp,%ebp
0x08048341 <+3>: sub $0x8,%esp
0x08048344 <+6>: and $0xfffffff0,%esp
0x08048347 <+9>: mov $0x0,%eax
0x0804834c <+14>: add $0xf,%eax
0x0804834f <+17>: add $0xf,%eax
0x08048352 <+20>: shr $0x4,%eax
0x08048355 <+23>: shl $0x4,%eax
0x08048358 <+26>: sub %eax,%esp
=> 0x0804835a <+28>: movl $0x10,-0x4(%ebp)
0x08048361 <+35>: movl $0x0,-0x8(%ebp)
0x08048368 <+42>: pushl -0x4(%ebp)
0x0804836b <+45>: call 0x8048334 <myfunc1 at test.c:4>
0x08048370 <+50>: add $0x4,%esp
0x08048373 <+53>: pushl -0x8(%ebp)
0x08048376 <+56>: call 0x8048339 <myfunc2 at test.c:8>
0x0804837b <+61>: add $0x4,%esp
0x0804837e <+64>: mov $0x0,%eax
0x08048383 <+69>: leave
0x08048384 <+70>: ret
End of assembler dump.
(gdb) info line
Line 16 of "test.c" starts at address 0x804835a <main+28 at test.c:16> and ends at 0x8048361 <main+35 at test.c:17>.------------------------------------(1)
(gdb) shell cat test.c
#include<stdio.h>
void myfunc1(int recv_arg1)
{
/* does nothing */
}
void myfunc2(int recv_arg1)
{
/* does nothing */
}
int main(int argc,char **argv)
{
int var1;
int var2;
var1 = 16;
var2 = 0;
myfunc1(var1);
myfunc2(var2);
return 0;
}
Note in (1) that the asm code for main is within that range !! and the asm code before this range is for something else ? What ? surely something mysterious !!
Allow me to comment this for you.
0x0804833e <+0>: push %ebp ; Establish standard
0x0804833f <+1>: mov %esp,%ebp ; stack frame record
0x08048341 <+3>: sub $0x8,%esp ; Make room for locals
0x08048344 <+6>: and $0xfffffff0,%esp ; Align esp to 16-byte memory
0x08048347 <+9>: mov $0x0,%eax ; eax=0
0x0804834c <+14>: add $0xf,%eax ; eax=f
0x0804834f <+17>: add $0xf,%eax ; eax= (eax + 0xf)
0x08048352 <+20>: shr $0x4,%eax ; ( >> 4)
0x08048355 <+23>: shl $0x4,%eax ; ( << 4)
;The above math rounds up eax as set by 0x0804834c to the next 16-byte boundary
;In this case, eax will be 0x10, rounded up from 0x0f. You compiled without
;optimizations? This could be a "probe" checking whether the upcoming call
;will fail?
0x08048358 <+26>: sub %eax,%esp ; Make room for "0x10 more mystery bytes"
0x0804835a <+28>: movl $0x10,-0x4(%ebp) ; var1 = 16
0x08048361 <+35>: movl $0x0,-0x8(%ebp) ; var2 = 0
0x08048368 <+42>: pushl -0x4(%ebp) ; push var1
0x0804836b <+45>: call 0x8048334 <myfunc1 at test.c:4> ;myfunc1( );
0x08048370 <+50>: add $0x4,%esp ; pop (var1)
0x08048373 <+53>: pushl -0x8(%ebp) ; push var2
0x08048376 <+56>: call 0x8048339 <myfunc2 at test.c:8> ;myfunc2( );
0x0804837b <+61>: add $0x4,%esp ; pop (var2)
0x0804837e <+64>: mov $0x0,%eax ; return 0;
0x08048383 <+69>: leave ; undo standard stack frame
0x08048384 <+70>: ret ; actual return
I think it is a good question, why finally execute 0x08048358
which allocates seemingly useless space. I suspect this is a check for esp out of range exception before performing the call. If you specify the processor you are using, I wonder if this will "go away" -- it smells like it might be for a specific chip's errata.
The code from 0x0804833e <+0>
upto (and including) 0x08048358 <+26>
is setting up what is known as a stack frame.
The first four statements are very standard. First you save the old base pointer (which is called the frame pointer in the Wikipedia article). You then set up a new base pointer by using the current value of the stack pointer.
Next, you decrement the stack pointer to make room for you local variables (notice you subtract 0x8 which is enough for you two ints). Finally, it makes sure the stack pointer is aligned to a 16 bit address.
The next group of lines (from 0x08048347 <+9>
to 0x08048358 <+26>
) are a bit odd. The effect is to grow the stack more, but I'm at a loss to explain why it used 5 instructions to compute the value (since there is no variable, it should be able to do that at compile time) or why it needs to grow the stack more.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With