在 Assembly Masm x86 中推送到我自己的堆栈时出错

Error Pushing To My Own Stack in Assembly Masm x86

我是装配新手。我已经做了几个月了。当我尝试将一个值压入我自己的堆栈数组时,我遇到了一个使我的程序崩溃的错误。错误显示,"Access Violation Writing Location"。我已经用调试器逐步检查它,但一无所获。因此,我将生成错误的代码放在程序的开头,以查看是否有其他代码(目前只是从文件中读取)可能导致了错误。我仍然得到错误。请帮助我,我不知道发生了什么。这是我的代码:

 .data
 myStack DWORD 30 DUP(?)
 top DWORD $
 val DWORD 5

 .code
 mov esi, OFFSET myStack 
 mov eax, val
 add esi, top 
 sub esi, 4              
 mov [esi], eax   ;this is where it crashes

假设它增长向下,典型的基于微处理器的堆栈,然后将一些东西放到堆栈上:

  1. 递减堆栈指针
  2. 将值移动到栈指针指向的地方

然后从堆栈中取出一些东西:

  1. 检索堆栈指针指向的内容
  2. 增加堆栈指针

当您将 top 加到 myStack 时,您将得到一个与其他地方相去甚远的地址,可能在您的程序 space 之外。 top 本身 已经是堆栈顶部的地址,无需向其添加任何内容。

因此,在您的情况下,top 已经是堆栈的顶部。所以你的初始堆栈指针应该是 top:

 .data
 myStack DWORD 30 DUP(?)
 top DWORD $
 val DWORD 5

.code
 mov esi, OFFSET top    ; Initialize the stack pointer
 mov eax, val           ; Load a value into eax
 sub esi, 4             ; push eax onto the stack
 mov [esi], eax

在上面,"stack pointer"(最初是 top)第一次减去 4 将得到 top - 4,这是最后 4 个字节 space在你的 myStack 区域。

从堆栈中弹出一个值:

mov eax, [esi]
add esi, 4

或者,您可以设置 top 不同的方式,这样您的代码就可以工作了。但它稍微复杂一些:

.data
 myStack DWORD 30 DUP(?)
 top DWORD $-myStack           ; the value here is current location minus myStack
 val DWORD 5

 .code
 mov esi, OFFSET myStack        ; Setup the stack pointer
 add esi, top 
 mov eax, val                   ; get value in eax
 sub esi, 4                     ; push eax          
 mov [esi], eax

除非有一个压倒一切的原因为什么你的堆栈 必须 像处理器的堆栈一样工作(即 "top" 向下增长),使用 "top" 到分配缓冲区的末尾。原因是您不必向后思考即可。堆栈变得就像任何其他缓冲区一样。您在第一个位置添加第一个项目,并向分配缓冲区的末尾增长。

"Push"是往下一个可用位置添加一个item的事情。 "Pop"是从最高使用位置移除的问题。

请注意,效率与我的论点无关。无论哪种方式,您所做的工作量都是相同的。这只是更容易考虑,因为堆栈的实现方式与任何其他数组类型结构一样:您添加的第一项将进入第一个(编号最小的)地址,等等。它只是一个缓冲区,您可以按 LIFO 顺序访问。

如果你按照我的建议实现它:

.data
myStack DWORD 30 DUP(?)
top DWORD myStack
val DWORD 5

.code

MyPush:
    // call with EAX containing the value you want to store
    mov esi,[top]
    mov [esi],eax
    add esi,4
    mov [top],esi
    ret

MyPop:
    // returns the value on the top of the stack in EAX
    mov esi,[top]
    sub esi,4
    mov eax,[esi]
    mov [top],esi
    ret