0

嗨,我有一个关于装配 x86 的问题

这是我的代码

INCLUDE Irvine32.inc
.data
day WORD 0
month WORD 0
year WORD 0


prompt1 BYTE "enter month: ",0
prompt2 BYTE "enter day: ",0
prompt3 BYTE "enter an year: ",0
prompt4 BYTE " the day of the week is ",0

.code
main PROC

mov edx, OFFSET prompt1
call writeString
mov edx, 0
call readInt
call crlf
mov month, ax

mov eax, 0
mov edx, OFFSET prompt2
call writeString
mov edx, 0
call readInt
call crlf
mov day, ax


mov eax, 0
mov edx, OFFSET prompt3
call writeString
mov edx, 0
call readInt
call crlf
mov year, ax



mov eax, 0
mov ebx, 0
mov ax, 14
sub ax, month
mov bx, 12
div bx
mov si, ax ;; a store in si
sub year, ax
mov di, year ;; y store in di
mov ax, ax
mul bx
add ax, month
mov cx, 2
sub ax, cx
mov ecx, 0
mov cx, ax ;; m store in cx

mov eax, 0
mov ebx, 0
mov esp, 0
mov ebp, 0

add day, di
mov ax, di
mov bx, 4
div bx
add day, ax
mov sp, day
mov eax, 0
mov ebx, 0
mov ax, di
mov bl, 100
div bl
mov ah, 0
sub day, ax


mov eax, 0
mov ebx, 0
mov dx, 0
mov ax, di
mov bx, 400
div bx
add day, ax
mov bp, day  ;; temporary holder for d value up to y/400 calculation

mov eax, 0
mov ebx, 0
mov ax, 31
mul cx
mov bx, 12
div bx
add bp, ax
mov al, 7
div al




    exit
main ENDP

END main

我正在调试这段代码,一切似乎都相应地工作,直到我到达退出指令,然后 Visual Studio 给了我这个错误“访问冲突写入位置 0x000009DF”,我有点困惑,它在代码末尾给了我这个错误,为什么退出命令会出现访问冲突

这是我的输入

enter month: 4

enter day: 15

enter an year: 2013

在程序结束时,我得到寄存器 al = 1 的值,这就是我想要的,所以我不知道为什么当代码中没有其他错误时它给了我这个错误有人可以帮忙吗?预先感谢

4

2 回答 2

0

要访问 ram 位置,请使用括号,因为它更易于阅读。

 mov [year], ax

 mov di, [year]

最好防止对代码的误解,因为如果我们使用

mov di, year

它可能是错误的

mov di, offset year

因为如果我们使用 NASM 而不是 MASM,那么这条指令不需要偏移量声明来获取偏移地址。NASM 从不解释

mov di, year

作为对 ram 位置的访问。

......

通常堆栈指针 (E)SP 仅用于使用我们的堆栈。如果我们使用调用指令,那么调用者的地址会被压入栈中,所以如果我们在这个子程序结束时使用 ret 指令,那么地址会从栈中弹出,并且 programmcounter 会被设置为call 指令之后的下一条指令。

但是,如果我们暂时不使用堆栈,那么我们可以将堆栈指针的地址保存到一个 ram 位置,以便免费使用堆栈指针。最后,我们可以将旧地址从 ram 位置取回到堆栈指针中。

提示:在指令中使用 (E)SP 或 E(BP) 作为地址寄存器,标准段寄存器是“SS”而不是“DS”。

mov [bp], ax   ; SS:BP
mov [sp], ax   ; SS:SP
mov ax, [bp]   ; SS:BP
mov ax, [sp]   ; SS:SP

mov [si], ax   ; DS:SI
mov [di], ax   ; DS:DI
mov [bx], ax   ; DS:BX
mov ax, [si]   ; DS:SI
mov ax, [di]   ; DS:DI
mov ax, [bx]   ; DS:BX

..

我不知道为什么会出现这种访问冲突。但是,我认为在使用 SP 之前将 ESP 设置为零可以解决此问题。我认为最好先保存堆栈指针的地址,然后在最后取回这个地址。

短剑

于 2013-05-13T10:14:44.423 回答
-3

我发现了错误。就是这一行:

mov sp, day

在此之前我没有设置esp为零,这就是程序显示访问冲突的原因。

于 2013-05-06T16:55:29.717 回答