使用 Irvine32 库在 MASM 中编写 "simple calculator for 32-bit integers"。我该如何解决这个 "write access violation" 错误?

Writing a "simple calculator for 32-bit integers" in MASM using the Irvine32 library. How can I fix this "write access violation" error?

作业如下:

这是 Irvine32 库 (我必须使用) 文档的 link:http://programming.msjc.edu/asm/help/

现在我只是在试验如何制作一个成功的模板prompt/output,我正在从加法操作开始。我的问题是,在尝试使用 WriteString(一个 Irvine32 过程)打印响应输出的第一行时,我得到了 "write access violation"。它确实在控制台上打印了文本,但之后立即出现错误。让我感到困惑的是,在程序的早期,我成功地将 WriteString 用于其他字符串;很奇怪,它在这里不起作用。

调试时显示的错误截图如下:

这是我的代码:

.386
.MODEL flat,stdcall
.STACK 4096
ExitProcess PROTO,dwExitCode:DWORD
WriteString PROTO
ReadDec PROTO

.DATA

promptLineOne DB "1.  X + Y                    6.  X and Y",13,10,0
promptLineTwo DB "2.  X - Y                    7.  X or Y",13,10,0
promptLineThree DB "3.  X * Y                    8.  not X",13,10,0
promptLineFour DB "4.  X / Y                    9.  X xor Y",13,10,0
promptLineFive DB "5.  X mod Y                    10.  Exit Program",13,10,0
adding DB "Adding X and Y; enter X, then enter Y",0
added DB "The sum of X and Y is: ",0
tryAgain DB "Try again",0

.CODE

prompt PROC
  MOV ECX,5
  MOV EAX,0
  MOV EDI,OFFSET promptLineOne
  L1:
    MOV EDX,EDI
    INVOKE WriteString
    L2:
        INC EDI
        MOV AL,[EDI]
        CMP EAX,0
        JNZ L2
        INC EDI
    LOOP L1

RET
prompt ENDP

calculate PROC
  MOV EDX,OFFSET adding
  INVOKE WriteString
  op1 DD ?
  op2 DD ?
  result DD ?
  L1:
    INVOKE ReadDec
    JNC chastise
    JC FirstPass
    JNC L1
  FirstPass:
    MOV op1,EAX
  L2:
    INVOKE ReadDec
    JNC chastise
    JC SecondPass
    JNC L2
  SecondPass:
    MOV op2,EAX
    ADD EAX,op1
    ADD EAX,op2
    MOV result,EAX

    MOV EDX,OFFSET added
    INVOKE WriteString
    MOV EDX,OFFSET result
    INVOKE WriteString
RET
calculate ENDP

chastise PROC
  MOV EDX,OFFSET tryAgain
  INVOKE WriteString
RET
chastise ENDP

main PROC
  INVOKE prompt
  INVOKE ReadDec
  INVOKE calculate

  INVOKE ExitProcess,0
main ENDP

END main

感谢观看! :)

与 c++ 不同,asm 不允许您在代码中的任何位置定义变量。像这样:

calculate PROC
  MOV EDX,OFFSET adding
  INVOKE WriteString
  op1 DD ?
  op2 DD ?
  result DD ?
  L1:
    INVOKE ReadDec
    JNC chastise

这将执行 mov,执行 invoke,然后尝试执行位于 op1 的任何指令。自从?意味着这个位置的内容是未定义的,谁知道它包含什么?可以肯定的是,它不会按照您的意图进行。

很容易习惯编译器知道数据和代码之间区别的高级语言。但是在 asm 中,如果你把它放在你的 .code 部分,它就是代码。