1
请考虑下面的MASM汇编代码片段。因为它会跳到skip2并且工作得很好。注释掉jmp skip2行,前半部分执行 - 实际上不行。相反,在VS2015调试模式下,我收到访问冲突错误。我附上了我对堆栈激活记录的解释的Excel图表。在(1)下是esp和补偿 - 如果你jmp跳过2,这个工作正常。 (2)是ebp及其偏移量(我认为),它会说[ebp + 40]和[ebp + 44]应该起作用。它没有,也没有其他天真的想法(3),也许与pushad,这是正确的地方开始与ebp。绿色显示pushad指令后堆栈的结果。黄色显示目标,即@I和@k,显然需要取消引用。通过引用传递的exhange两个变量不会合作
我哪里错了?
Exchange PROC
pushad
jmp skip2 ; comment this jmp instruction out and works fine.
push ebp
mov ebp, esp
mov eax, [ebp+44] ; eax gets @k
mov ecx, [eax] ; ecx gets k.
mov ebx, [ebp+40] ; ebx gets @i.
mov edx, [ebx] ; edx gets i.
mov [eax], edx ; k = i.
mov [ebx], ecx ; i = k.
pop ebp ; EDITED: THIS IS THE FIX
jmp ende
skip2:
mov eax, [esp+40] ; eax gets @k
mov ecx, [eax] ; ecx gets k.
mov ebx, [esp+36] ; ebx gets @i.
mov edx, [ebx] ; edx gets i.
mov [eax], edx ; k = i.
mov [ebx], ecx ; i = k.
ende:
popad
ret 8
Exchange ENDP
你做'推ebp'没有'流行ebp'将跳转到前搅乱堆栈'恩德:'。 – zx485
谢谢,但不是,同样的问题。在ret 8之前添加pop ebp。****编辑:但是如果你把它放在jmp ende之前,它就可以工作。回答问题? – Chris
不在'ret 8'之前,但在'jmp ende'之前。堆栈是LIFO(后进先出)。除此之外,'PROC'指令会在'ret'后立即处理,所以使用'ret'而不是'ret 8'。 – zx485