2016-05-19 34 views
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 

enter image description here

+1

你做'推ebp'没有'流行ebp'将跳转到前搅乱堆栈'恩德:'。 – zx485

+0

谢谢,但不是,同样的问题。在ret 8之前添加pop ebp。****编辑:但是如果你把它放在jmp ende之前,它就可以工作。回答问题? – Chris

+2

不在'ret 8'之前,但在'jmp ende'之前。堆栈是LIFO(后进先出)。除此之外,'PROC'指令会在'ret'后立即处理,所以使用'ret'而不是'ret 8'。 – zx485

回答

0

只是缺少弹出EBP作为评论指出...