1

I wrote this simple code:

#include <stdio.h>
void ok(){}

int main()
{
  int k=1;
  int l=1337;
  int *p;
  p=NULL;
  p=&k;
  ok();
} 

and I've disassembled it to see what the compiler does. Using objdump I obtain:

0000000000400546 <main>:
  400546:       55                      push   rbp
  400547:       48 89 e5                mov    rbp,rsp
  40054a:       48 83 ec 20             sub    rsp,0x20
  40054e:       64 48 8b 04 25 28 00    mov    rax,QWORD PTR fs:0x28
  400555:       00 00 
  400557:       48 89 45 f8             mov    QWORD PTR [rbp-0x8],rax
  40055b:       31 c0                   xor    eax,eax
  40055d:       c7 45 e8 01 00 00 00    mov    DWORD PTR [rbp-0x18],0x1
  400564:       c7 45 ec 39 05 00 00    mov    DWORD PTR [rbp-0x14],0x539
  40056b:       48 c7 45 f0 00 00 00    mov    QWORD PTR [rbp-0x10],0x0
  400572:       00 
  400573:       48 8d 45 e8             lea    rax,[rbp-0x18]
  400577:       48 89 45 f0             mov    QWORD PTR [rbp-0x10],rax
  40057b:       b8 00 00 00 00          mov    eax,0x0
  400580:       48 8b 55 f8             mov    rdx,QWORD PTR [rbp-0x8]
  400584:       64 48 33 14 25 28 00    xor    rdx,QWORD PTR fs:0x28
  40058b:       00 00 
  40058d:       74 05                   je     400594 <main+0x4e>
  40058f:       e8 8c fe ff ff          call   400420 <__stack_chk_fail@plt>
  400594:       c9                      leave  
  400595:       c3                      ret    
  400596:       66 2e 0f 1f 84 00 00    nop    WORD PTR cs:[rax+rax*1+0x0]
  40059d:       00 00 00 

I can understand everything except for the mov QWORD PTR [rbp-0x10],0x0, this correspond (I think)to p=NULL; but from mov QWORD PTR [rbp-0x8],rax I know that my pointer is on rbp-0x8 and it seems correct (the size of a pointer is 8bytes).

So why mov QWORD PTR [rbp-0x10],0x0 is called on rbp-0x10?

Also I don't know why xor eax,eax is called; for allignment?(if so why don't use nop). P.S I know that is sets eax to zero, but why ?

nnn
  • 3,980
  • 1
  • 13
  • 17
Ofey
  • 167
  • 7
  • 1
    Your pointer "p" is actually at `[rbp-0x10]` - see http://stackoverflow.com/questions/14414763/what-does-the-mov-rax-qword-ptr-fs0x28-assembly-instruction-do for more information on what `[rbp-0x8]` is being used for (specifically, the `mov rax,QWORD PTR fs:0x28` immediately preceding it). – Quietust Apr 03 '17 at 17:24
  • 1
    To not assume, you can have intermixed assembly with source code in objdump output. Compile with debug info: `gcc -g file.c` and run `objdump -S a.out` or `objdump --source a.out` – nnn Apr 03 '17 at 17:42

1 Answers1

1

From these lines

  6   int k=1;
  7   int l=1337;
  8   int *p;
  9   p=NULL;
 10   p=&k;

It is clear that these assembler instructions correspond to

  6   int k=1;
  40055d:       c7 45 e8 01 00 00 00    mov    DWORD PTR [rbp-0x18],0x1

  7   int l=1337;
  400564:       c7 45 ec 39 05 00 00    mov    DWORD PTR [rbp-0x14],0x539

  9   p=NULL;
  40056b:       48 c7 45 f0 00 00 00    mov    QWORD PTR [rbp-0x10],0x0
  400572:       00 

 10   p=&k;
  400573:       48 8d 45 e8             lea    rax,[rbp-0x18]
  400577:       48 89 45 f0             mov    QWORD PTR [rbp-0x10],rax

So the local variable p is placed at [rbp-0x10] and occupies a QWORD starting at [rbp-0x10] through [rbp-0x8] ( rbp-0x10 + 0x8 == rbp-0x8)

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • but the space between p (on rbp-0x10) and l (on rbp-0x14) is 0x04. Isn't a pointer 8 bytes long? How he can fit in a space of 0x04? – Ofey Apr 03 '17 at 18:46
  • @Ofey The space at addresses rbp -0x14 and rbp - 0x10 is occupied by the variable l. The space at addresses rbp-0x10 and rbp-0x8 is occupied by the pointer p. rbp-0x10 + 8 == rbp-0x8. – Vlad from Moscow Apr 03 '17 at 18:56
  • That's what i was mising! Thank you! – Ofey Apr 04 '17 at 07:05