Question

Hi i have a question about assembly x86

this is my code

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

I' m debugging this code everything seems to work accordingly, until I reach the exit instruction then visual studio gave me this error " Access violation writing location 0x000009DF", I a bit confused that it gave me this error at the end of the code, why would there be access violation at the exit command

this is my input

enter month: 4

enter day: 15

enter an year: 2013

At the end of the program i get value of register al = 1 which is what i want so I don't know why it gave me this error when there is no other error in the code can anyone help ? thank in advance

Was it helpful?

Solution 2

I found the error. It is this line:

mov sp, day

I did not set esp to zero before this, that’s why the program shows an access violation.

OTHER TIPS

For to access to a ram location please use brackets, because it is easier to read.

 mov [year], ax

 mov di, [year]

And it is better for to prevent a missunderstanding the code, because if we use

mov di, year

it can be missenterprete with

mov di, offset year

because if we use NASM instead of MASM, then this instruction do not need the offset declaration for to get the offset address. NASM never interpret the instruction of

mov di, year

as an acces to a ram location.

.....

Normaly the stackpointer (E)SP is only for to use our stack. If we use a call instruckton, then the address of the caller will be pushed on the Stack, so if we use a ret instrucktion at the end of this subroutine, then the address will be popped from the stack and the programmcounter will be set to the next instruction after the call instruction.

But if we do not use the stack for a moment, then we can save the address of the stackpointer to a ram location for to free use also the stackpointer. At the end we can get the old address back from the ram location into the stackpointer.

Hint: Using (E)SP or E(BP) inside of an instruction as an addressregister the standard segmentregister is "SS" and not "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

..

I do not know why this access violation appears. But, i do not think that this can be fixed with setting ESP to zero before using SP. I think it is bettter to save the address of the stackpointer before and get this address back at the end.

Dirk

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top