GDB - What is the mysterious assembly code?

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 (1) that the asm code for main is in this range! and asm code before this range for something else? What kind? Surely something mysterious !!

+3
source share
4 answers

Let me comment on 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 this is a good question, why, finally, perform 0x08048358, which allocates a seemingly useless space. I suspect this is an esp exception check out of range before making the call. If you specify the processor that you are using, I wonder if it will "go away" - it smells as if it could be for certain cover errors.

+9
source

0x0804833e <+0> upto ( ) 0x08048358 <+26> .

. ( ). , .

, ( , 0x8, ints). , , 16- .

( 0x08048347 <+9> 0x08048358 <+26>) . , , , 5 ( , ) .

+6

... , .

< +3 < +26 > . , , ? , , , ​​ .

:

, , , , . , 16 ( ) main + 28.

.

+2

( , ...). , , , . "" , .

. . gcc -S C, , , , -On, .

   0x0804833e <+0>:     push   %ebp

      save current ebp register

   0x0804833f <+1>:     mov    %esp,%ebp

      copy esp register to ebp (aka base pointer or frame pointer)

   0x08048341 <+3>:     sub    $0x8,%esp

      make rooms on the stack (for 2 32bit integers)

   0x08048344 <+6>:     and    $0xfffffff0,%esp

      align stack to multiple of 16

   0x08048347 <+9>:     mov    $0x0,%eax

      eax = 0

   0x0804834c <+14>:    add    $0xf,%eax

      eax += 15

   0x0804834f <+17>:    add    $0xf,%eax

      eax += 15 (eax == 30)

   0x08048352 <+20>:    shr    $0x4,%eax
   0x08048355 <+23>:    shl    $0x4,%eax

      total effect: zeros less significant nibble of eax;
      30 = b:11110  ->   eax = b:10000

   0x08048358 <+26>:    sub    %eax,%esp

       more 16 bytes room on the esp

       esp ->          dword     room made by last esp-eax
                       dword
                       dword
                       dword
                       ...       maybe stuffs because of alignment
                       dword     first two dword created by esp-8 (var2)
                       dword     (var1)
       ebp ->          dword     original ebp ptr
                       ...

=> 0x0804835a <+28>:    movl   $0x10,-0x4(%ebp)

       put 16 in -4(ebp), so we realize that it is var1

   0x08048361 <+35>:    movl   $0x0,-0x8(%ebp)

       put 0 in -8(ebp) so we realize it is var2

   0x08048368 <+42>:    pushl  -0x4(%ebp)
   0x0804836b <+45>:    call   0x8048334 <myfunc1 at test.c:4>

       pass var1 to myfunc1 (args are passed on stack, by convention)

   0x08048370 <+50>:    add    $0x4,%esp

       and cleaning the stack is up to the caller

   0x08048373 <+53>:    pushl  -0x8(%ebp)
   0x08048376 <+56>:    call   0x8048339 <myfunc2 at test.c:8>
   0x0804837b <+61>:    add    $0x4,%esp

       pass var2 to myfunc2 and "clears" the stack

   0x0804837e <+64>:    mov    $0x0,%eax

       return value (0)

   0x08048383 <+69>:    leave

       is the same as doing esp = ebp; pop ebp, i.e. take the stack
       back at the initial point after the first push, and then retrieve
       back original ebp value

   0x08048384 <+70>:    ret

       return to the caller (return 0 <- eax)

This code is suboptimal. It does unnecessary things, and not what I get with gcc v 4.3.2 and without optimization. In particular, things like two instant additions can become one add-on (even at the most basic stage of optimization by default), and a pair of shr-shl can become one and. In fact, this code looks weirder than the β€œregular” compiler looks.

+1
source

Source: https://habr.com/ru/post/1752578/


All Articles