masm调用过程访问冲突

时间:2016-03-13 18:27:40

标签: visual-studio assembly masm irvine32

所以我在装配中进行分配以生成斐波那契序列。我已经在主程序中成功编写了代码,但是当我尝试将其包装在自己的程序中并调用该程序时,我遇到了访问冲突错误。这是我的代码:

INCLUDE Irvine32.inc

.data
array DWORD 47 DUP(?)

.code
main proc
mov esi, OFFSET array

call generate_fibonacci

invoke ExitProcess,0
main endp

generate_fibonacci PROC

mov DWORD PTR [esi], 1h
add esi, 4
mov DWORD PTR [esi], 1h
push [esi]
push [esi - 4]
add esi, 4
mov ecx, 45
L1: 
pop eax
pop ebx
add eax, ebx
mov DWORD PTR [esi], eax
add esi, 4
push [esi - 4]
push [esi - 8]
loop L1
ret

generate_fibonacci ENDP

end main

错误如下所示:“项目中某些内存位置引发异常......:访问冲突执行位置相同的内存位置

我注意到,当执行调用generate_fibonacci指令时,错误消息中列出的内存位置被加载到EIP寄存器中。我不知道如何解决这个问题。

1 个答案:

答案 0 :(得分:3)

PROC中的推送和弹出不均衡。

在循环L1:之前你进行了2次推送。在循环L1:内,您可以进行2次弹出和2次弹出。当循环L1:结束时,当ret尝试拉出返回地址时,仍会在堆栈上留下2个项目。因此,代码会尝试在导致访问冲突的某个地方恢复执行。

请在ret指令前添加两行代码以清理堆栈

pop eax
pop eax
ret

如果相同的代码在main中有效,则可行,因为main并非以ret结尾。

编辑。您可以通过将最近的条款保留在寄存器中来大大简化它。最后三个字词将位于eaxebxedx

generate_fibonacci PROC

    mov     eax, 1                  ;init first two terms
    mov     DWORD PTR [esi], eax    ;store first two terms
    add     esi, 4
    mov     DWORD PTR [esi], eax
    add     esi, 4

    mov     ebx, eax
    mov     ecx, 45                 ;init loop count
L1: 
    mov     edx, ebx                ;move terms along
    mov     ebx, eax
    add     eax, edx                ;sum last two terms
    mov     DWORD PTR [esi], eax
    add     esi, 4
    loop    L1
    ret

generate_fibonacci ENDP