所以我在装配中进行分配以生成斐波那契序列。我已经在主程序中成功编写了代码,但是当我尝试将其包装在自己的程序中并调用该程序时,我遇到了访问冲突错误。这是我的代码:
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寄存器中。我不知道如何解决这个问题。
答案 0 :(得分:3)
PROC
中的推送和弹出不均衡。
在循环L1:
之前你进行了2次推送。在循环L1:
内,您可以进行2次弹出和2次弹出。当循环L1:
结束时,当ret
尝试拉出返回地址时,仍会在堆栈上留下2个项目。因此,代码会尝试在导致访问冲突的某个地方恢复执行。
请在ret
指令前添加两行代码以清理堆栈
pop eax
pop eax
ret
如果相同的代码在main
中有效,则可行,因为main
并非以ret
结尾。
编辑。您可以通过将最近的条款保留在寄存器中来大大简化它。最后三个字词将位于eax
,ebx
,edx
。
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