Search code examples
c++assemblygdbstack-memory

gdb - x86_64 assembly - viewing stack


I debug the assembly code of the following simple program:

int main()
{
    int x = 5;
    return 0;
}

I set the breakpoint on the return statement. gdb shows the following assembly code (intel syntax):

(gdb) disass
Dump of assembler code for function main():
   0x00005555555545fa <+0>: push   rbp
   0x00005555555545fb <+1>: mov    rbp,rsp
   0x00005555555545fe <+4>: mov    DWORD PTR [rbp-0x4],0x5
=> 0x0000555555554605 <+11>:    mov    eax,0x0
   0x000055555555460a <+16>:    pop    rbp
   0x000055555555460b <+17>:    ret    
End of assembler dump.

Here is the info about rsp register:

(gdb) info reg rsp
rsp            0x7fffffffdcb0   0x7fffffffdcb0

The value of the x variable should be placed on the stack, how to print the stack ? I try the following command but without success:

(gdb) x/10x $rsp
0x7fffffffdcb0: 0x55554610  0x00005555  0xf7a03c87  0x00007fff
0x7fffffffdcc0: 0x00000001  0x00000000  0xffffdd98  0x00007fff
0x7fffffffdcd0: 0x00008000  0x00000001

Moreover I don't understand why the difference between the above addresses is equal 16.


Solution

  • The value of the x variable should be placed on the stack, how to print the stack ?

    What you're seeing is something called a red zone - any function is allowed to use some stack space below the stack pointer. It's an optimization at ABI level - the stack pointer only needs moved when calling another function or exceeding the red zone (128 bytes on SysV ABI).

    Notice that the value is stored 4 bytes below the frame pointer rbp (which here is equal to the stack pointer rsp).

                                mov    DWORD PTR [rbp-0x4],0x5
    

    So try printing the stack starting from $rsp - 4 or less.

    x/10wx $rsp-4
    

    Or compile with -mno-red-zone (but note that on SysV ABI stack pointer is aligned on 16 bytes so your value will probably be at $rsp + 12).

    Moreover I don't understand why the difference between the above addresses is equal 16

    The memory dump contains 16 bytes per line (see 4 values of 4 bytes each). So next line starts 16 bytes later (or 0x10). with x/10x you requested to print 10 hex values (by default dwords), so you get 40 bytes of memory printed.

    You can print a single dword value with x/wx $rsp-4.

    For more details refer to GDB docs - Memory.