错误在装配Masm x86中推送到我自己的堆栈

时间:2015-04-13 01:00:25

标签: assembly x86 stack masm

我是装配新手。我已经做了几个月了。当我尝试将值推送到我自己的堆栈数组时,我收到一个错误,导致程序崩溃。错误说,"访问违规写入位置"。我已经使用调试器逐步完成它并且一无所获。因此,我在程序开头放置了生成错误的代码,以查看是否有其他代码(只是从文件中读取到目前为止)可能导致它。我仍然得到错误。请帮帮我,我不知道发生了什么。这是我的代码:

 .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

2 个答案:

答案 0 :(得分:1)

除非你的堆栈必须像处理器的堆栈一样工作(即“顶部”增长),这是一个压倒一切的原因,所以使用“顶部”朝向末端执行此操作要容易得多。分配缓冲区。原因是你不必反省思考。堆栈变得像任何其他缓冲区一样。您在第一个位置添加第一个项目,并在分配的缓冲区末尾增长。

“推送”是将项目添加到下一个可用位置的问题。 “流行”是从最高使用位置移除的问题。

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

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

.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

答案 1 :(得分:0)

假设它增长 down ,典型的基于微处理器的堆栈,然后把东西放到堆栈上:

  1. 减少堆栈指针
  2. 将值移动到堆栈指针指向的位置
  3. 并从堆栈中取出一些东西:

    1. 检索堆栈指针指向的内容
    2. 递增堆栈指针
    3. 当你将top加到myStack时,你将获得一个远离其他地方的地址,可能在你的程序空间之外。 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
      

      在上面,从“堆栈指针”(最初为top)中第一次减去4将产生top - 4,这是myStack中的最后一个4字节空格区域。

      从堆栈中弹出一个值:

      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