Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GDB - What is the mysterious Assembly code?

Tags:

c++

c

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 !!

like image 259
Onkar Mahajan Avatar asked Jul 01 '10 05:07

Onkar Mahajan


2 Answers

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.

like image 80
Heath Hunnicutt Avatar answered Oct 05 '22 17:10

Heath Hunnicutt


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.

like image 45
R Samuel Klatchko Avatar answered Oct 05 '22 17:10

R Samuel Klatchko