可视化装配中“堆栈”的工具

问题描述

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

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

我知道gdb中有x/8xw $rbp或其变体,但是我想逐步浏览代码时就像动画或持续可视化一样查看它。有办法吗?

解决方法

每次GDB停止运行时,display都会打印一些内容,例如

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

在每个步骤之后获得这样的输出。 (来自_start的那个,因此RSP指向argc(0x1),然后指向argv[0](指针),然后指向argv[1](NULL),然后指向{{1} }等)

envp[0]

GDB强制转换表达式的工作方式是将{0x1,0x7fffffffea02,0x0,0x7fffffffea0e,0x7fffffffea1e,0x7fffffffea6c,0x7fffffffea7e,0x7fffffffea92} (堆栈指针)解引用为单个$rsp,然后将其强制转换为long的数组。当然,这实际上不能在C语言中使用,但是GDB表达式仅使用类似C的语法,它们不是正确的C语言。可能有更简单的写法,但这是我通过反复试验得出的。

这将以内存地址的升序显示qwords,从一个RSP指向开始,因此它将在longcall之后更改。如果要在红色区域中看到下方 RSP,请使用其他基准,例如push之类的东西。


如果要使函数的堆栈框架在RBP下的视图不随推/弹出动作而移动,则可能需要像($rsp-16)之类的基体。

当然,您的($rbp - 16)命令不会向您显示指令存储的任何内存,因为您存储的是以下 RBP = RSP。 (实际上,在带有红色区域的x86-64 System V ABI中,这是可以保证安全的。在许多其他调用约定中,可以通过信号处理程序或调试器评估x/8xw $rbp以异步方式踩踏{{1 1}}是您程序中的函数。)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...