在装配中可视化 'the stack' 的工具

Tools to visualize 'the stack' in assembly

是否有任何方法可以以简单的、最好是直观的方式查看哪些值被压入堆栈?目前我正在使用 gdb 进行调试,但想知道是否有任何其他程序(或者甚至可能是另一种模式下的 gdb)在我逐步执行每条指令时查看堆栈的样子,例如在这个程序中:

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

我知道在 gdb 中有 x/8xw $rbp 或其变体,但我想在单步执行代码时将其视为动画或持续可视化。有办法吗?

display 每次 GDB 停止时打印一些东西,例如

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

在每一步之后得到这样的输出。 (这个来自_start,所以RSP指向argc(0x1),然后是argv[0](一个指针),然后是argv[1](NULL),然后是envp[0], 等等)

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

GDB 转换表达式通过将 $rsp(堆栈指针)取消引用为单个 long,然后将其转换为 long 的数组来工作。这当然在 C 中实际上不起作用,但 GDB 表达式仅使用 C-like 语法,它们不是正确的 C。可能有更简单的方法来编写它,但这是我通过试验和错误。

这将以内存地址的递增顺序显示 qwords,从一个 RSP 指向的开始,因此它会在 callpush 之后改变,例如。如果你想看到下方 RSP,进入红色区域,使用不同的基数,比如($rsp-16)或其他东西。


如果您想查看不随 push/pop 移动的 RBP 下面的函数堆栈帧,您可能需要像 ($rbp - 16) 之类的基数。

当然,您的 x/8xw $rbp 命令不会向您显示您的指令存储到的任何内存,因为您正在存储低于 RBP = RSP。 (这在 x86-64 System V ABI 中实际上是安全的,它有一个红色区域。在许多其他调用约定中,信号处理程序或调试器评估 print foo(1) 其中 foo 是你程序中的一个函数。)