在装配中可视化 '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 指向的开始,因此它会在 call
或 push
之后改变,例如。如果你想看到下方 RSP,进入红色区域,使用不同的基数,比如($rsp-16)
或其他东西。
如果您想查看不随 push/pop 移动的 RBP 下面的函数堆栈帧,您可能需要像 ($rbp - 16)
之类的基数。
当然,您的 x/8xw $rbp
命令不会向您显示您的指令存储到的任何内存,因为您正在存储低于 RBP = RSP。 (这在 x86-64 System V ABI 中实际上是安全的,它有一个红色区域。在许多其他调用约定中,信号处理程序或调试器评估 print foo(1)
其中 foo
是你程序中的一个函数。)
是否有任何方法可以以简单的、最好是直观的方式查看哪些值被压入堆栈?目前我正在使用 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 指向的开始,因此它会在 call
或 push
之后改变,例如。如果你想看到下方 RSP,进入红色区域,使用不同的基数,比如($rsp-16)
或其他东西。
如果您想查看不随 push/pop 移动的 RBP 下面的函数堆栈帧,您可能需要像 ($rbp - 16)
之类的基数。
当然,您的 x/8xw $rbp
命令不会向您显示您的指令存储到的任何内存,因为您正在存储低于 RBP = RSP。 (这在 x86-64 System V ABI 中实际上是安全的,它有一个红色区域。在许多其他调用约定中,信号处理程序或调试器评估 print foo(1)
其中 foo
是你程序中的一个函数。)