这是我的MASM代码:
.data
promptMonth BYTE "Enter month ", 0
promptDay BYTE "Enter day ", 0
promptYear BYTE "Enter year ", 0
.code
main PROC
p1:
mov edx, OFFSET promptMonth
call WriteString
call ReadInt
mov ebp, eax
p2:
mov edx, OFFSET promptDay
call WriteString
call ReadInt
mov esp, eax
p3:
mov edx, OFFSET promptYear
call WriteString
call ReadInt
mov edi, eax
main ENDP ; Added by edit
由于某种原因,当代码到达p3
中的“ WriteString”函数时,出现错误
在Project.exe中的0x00403687处引发的异常:0xC0000005:
违反访问权限访问位置0x00000000”。
我不明白为什么,因为p1
和p2
运行得很好,它们的代码与p3
几乎相同。
答案 0 :(得分:1)
esp
是堆栈指针寄存器。在x86上,当您call
使用函数时,堆栈用于传递参数和返回地址。
执行mov esp, eax
时,您会将堆栈指针设置为ReadInt
返回的值(根据其名称,我猜它是用户提供的值),您将其指定为{ {1}}。
异常代码0
是access violation,因为0xC0000005
指令试图将调用代码的返回地址放到位置call WriteString
中,该位置为空指针。
解决方案:要存储从调用0x00000000
返回的值,请使用ReadInt
以外的寄存器。
此外,除非您知道您没有将指定的帧指针寄存器(esp
)用于其预期用途,否则也不应将其用作通用寄存器。
答案 1 :(得分:0)
您正在将
指令弄乱堆栈指针mov esp, eax
为什么还要这么做?
将返回值EAX
放到堆栈指针是一个真正的坏主意。
将EAX
放入EBP
的第一次尝试充其量是没有用的,因此到目前为止没有任何效果。
但是用返回值替换 Stack Pointer ESP
会弄乱所有内容。
不要这样做!
程序随后崩溃(@ p3)也就不足为奇了。
因此,要修复您的程序,请执行以下操作:
删除
mov ebp, eax
和
mov esp, eax
来自您的代码。
这应该可以解决您的主要问题。
最后一个
mov edi, eax
不影响程序流程,因此您可以根据需要进行操作。