【问题标题】:inspect stack in assembly检查组装中的堆栈
【发布时间】:2026-01-24 15:50:01
【问题描述】:

我在 inline-assembly 中推送一些 int 值:

_asm
  {
  mov eax,i3  
  push eax
  mov eax,ii  
  }  

稍后我通过 pops 检索这个值:

_asm
  {
  pop eax
  mov ii,eax  
  pop eax
  mov i3,eax  
  }  

我想在不弹出的情况下检查我的堆栈。我需要重新排列或重新审视一些值。完成后我可以恢复堆栈。

我对 asm 很生疏。有没有类似的东西:

mov ii,esp+4 

这会移动下一个(不是当前的)堆栈元素吗?我只是猜测。 我需要这段代码在 32 位 win 和 64 位 win 环境下运行。

【问题讨论】:

  • 使用调试器的内存视图窗口。但最重要的是,不要编写那样的代码。改用局部变量,它也在堆栈上。调试器可以显示值。

标签: assembly stack inspect


【解决方案1】:

我想在不弹出的情况下检查我的堆栈。我需要重新排列或重新查看一些值。

这就是堆栈分配变量在函数中的作用方式 - 因此函数序言通常后面跟着 sub esp, x,其中 x 是要分配的空间量。

因此,C(和 C++)中的变量访问是检查堆栈。或者,如果您知道编译器是如何分配变量的,您可以从您的内联 ASM 中读取它们。

实现您想要做的事情的一种方法可能是将输入变量和输出变量都列为内联汇编的操作数。这篇osdev 文章很好地解释了它。这样,无论编译器如何在编码更改和优化标志之间重新排序堆栈,您的汇编器仍然可以工作。

或者,如果您自己编写整个函数,您可以像这样在给定地址加载堆栈的值:

mov eax, DWORD PTR [ebp-8]

这将使用位于ebp-8 的内存地址的值加载eax

【讨论】:

  • 当我把东西压入堆栈时。在我的示例中,我执行“push eax”。一个 4 字节的值被添加到堆栈中。这在大多数系统上是否相同。例如,当使用 win64 时,“push eax”是否会在堆栈上添加一个 8 字节的值?