samuelbrody1249
samuelbrody1249

Reputation: 4787

Tools to visualize 'the stack' in assembly

Are there any ways to see what values that are pushed onto the stack in a simple, preferably visual way? Currently I'm using gdb for debugging, but was wondering if there were any other programs (or possibly even gdb in another mode) to have a view onto what the stack looks like as I step through each instruction, for example in this program:

.globl main
main:
    push %rbp
    mov %rsp, %rbp
    movb $8, -1(%rbp)
    movw $30, -4(%rbp)
    mov -1(%rbp), %rax
    add -4(%rbp), %rax

I know in gdb there is x/8xw $rbp or variations thereof, but I'd like to view this almost like an animation or constant visualization while stepping through code. Is there a way to do that?

Upvotes: 1

Views: 1806

Answers (1)

Peter Cordes
Peter Cordes

Reputation: 366066

There's display to print something every time GDB stops, e.g.

display /x (long [8])*(long*)$rsp

to get output like this after every step. (This one from _start, so RSP is pointing at argc (0x1), then argv[0] (a pointer), then argv[1] (NULL), then envp[0], etc.)

{0x1, 0x7fffffffea02, 0x0, 0x7fffffffea0e, 0x7fffffffea1e, 0x7fffffffea6c, 0x7fffffffea7e, 0x7fffffffea92}

The GDB cast expression works by dereferencing $rsp (the stack pointer) as a single long, then casting that to an array of long. This of course wouldn't actually work in C, but GDB expressions only use C-like syntax, they aren't proper C. There might be an easier way to write this, but it's what I came up with through trial and error.

This will show qwords in increasing order of memory address, starting with the one RSP points to, so it will change after a call or push, for example. If you want to see below RSP, into the red zone, use a different base, like ($rsp-16) or something.


If you want a view of your function's stack frame below RBP that doesn't move with push/pop, you might want a base like ($rbp - 16) or something.

Of course, your x/8xw $rbp command doesn't show you any of the memory your instructions store into, because you're storing below RBP = RSP. (That's actually guaranteed safe in the x86-64 System V ABI, which has a red zone. In many other calling conventions, that could be stepped on asynchronously by a signal handler, or by a debugger evaluating print foo(1) where foo is a function in your program.)

Upvotes: 1

Related Questions