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