汇编语言[MASM]引发异常

时间:2018-10-31 21:03:39

标签: assembly x86 irvine32

这是我的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”。

我不明白为什么,因为p1p2运行得很好,它们的代码与p3几乎相同。

2 个答案:

答案 0 :(得分:1)

esp是堆栈指针寄存器。在x86上,当您call使用函数时,堆栈用于传递参数和返回地址。

执行mov esp, eax时,您会将堆栈指针设置为ReadInt返回的值(根据其名称,我猜它是用户提供的值),您将其指定为{ {1}}。

异常代码0access 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

不影响程序流程,因此您可以根据需要进行操作。