Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 在程序集Masm x86中推送到我自己的堆栈时出错_Assembly_X86_Stack_Masm - Fatal编程技术网

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

Assembly 在程序集Masm x86中推送到我自己的堆栈时出错,assembly,x86,stack,masm,Assembly,X86,Stack,Masm,我不熟悉组装。我已经做了几个月了。当我尝试将值推送到自己的堆栈数组时,我遇到了一个错误,导致程序崩溃。错误显示为“访问冲突写入位置”。我用调试器检查了一下,什么也没找到。因此,我将生成错误的代码放在程序的开头,只是想看看是否有其他代码(目前为止只是从文件中读取)导致了错误。我仍然得到错误。请帮帮我,我不知道发生了什么事。这是我的密码: .data myStack DWORD 30 DUP(?) top DWORD $ val DWORD 5 .code mov esi, OFFSE

我不熟悉组装。我已经做了几个月了。当我尝试将值推送到自己的堆栈数组时,我遇到了一个错误,导致程序崩溃。错误显示为“访问冲突写入位置”。我用调试器检查了一下,什么也没找到。因此,我将生成错误的代码放在程序的开头,只是想看看是否有其他代码(目前为止只是从文件中读取)导致了错误。我仍然得到错误。请帮帮我,我不知道发生了什么事。这是我的密码:

 .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
假设它逐渐变小,这是典型的基于微处理器的堆栈,然后将一些东西放到堆栈上:

mov eax, [esi]
add esi, 4
  • 递减堆栈指针
  • 将值移动到堆栈指针指向的位置
  • 要从堆栈上取下一些东西:

    mov eax, [esi]
    add esi, 4
    
  • 检索堆栈指针指向的内容
  • 递增堆栈指针
  • 当您将
    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
    

    除非有压倒一切的理由说明堆栈必须像处理器的堆栈一样工作(即“顶部”向下生长),否则在分配的缓冲区末尾使用“顶部”更容易做到这一点。原因是你不必反省去做。堆栈变得与任何其他缓冲区一样。将第一个项目添加到第一个位置,并增长到分配的缓冲区的末尾

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

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

    如果您按照我的建议实施:

    .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
    

    啊!好的,非常感谢你,潜伏者!这是我第一次使用$,所以我很困惑。所以我永远不必加载myStack?@lisabits,
    $
    只是指当前的程序计数器。所以
    top
    指向它自己地址的副本。在这种情况下,
    top
    指向的值实际上并不重要,因为您使用标签来表示堆栈结束后的位置。@lisabits,如果您使用
    top-DWORD$-myStack
    而不是
    top-DWORD$
    ,代码就会工作。是的,我知道$是当前地址。只是不知怎的,当我知道这件事时,我感到困惑。我猜我认为$本身就是在做$-myStack。很明显,我把这两个人搞混了。快到决赛了,哈哈。我的脑子快没了。谢谢@如果你觉得我的回答可以接受,如果你能把它标记为“接受”,我将不胜感激我想如果我那样做,我的教授会数到的。那么它就不是传统的堆栈了。不过,我现在一切都好了。只是一些需要对付的bug。谢谢,吉姆·米谢尔!我想让我大吃一惊的是,我从来没有在不加载的情况下访问过数组。我的意思是,我知道它会在记忆中的其他地方发生,但一开始我不知道为什么。现在一切都有意义了。@lisabits:不要把堆栈的实现与接口混淆起来。堆栈是一种抽象数据类型,可以向其中添加项。删除项目时,始终会获得最近添加的项目。如何实现其实并不重要。无论项目集合在缓冲区中是“向上”还是“向下”,或者您以某种方式随机存储它们,都是无关紧要的。重要的是,它以正确的顺序返回项目。看,我没有把它和任何东西混淆。我已经完成了程序并交了上来。我想说的是,我的教授告诉我们这样做,如果我不这样做,他可能会数数。我已经让他为比这更无关紧要的事情数数了。@Jim Mischel。。。为什么当我把标签放在评论的前面时,堆栈溢出会一直删除它们?我知道它没有那样对你。奇怪的