I'm trying to program a maze solver in assembly. We are given a driver program that sends the current x position in the si register, the y position in the di register, the moving direction in the bx register and the maze itself in the bp register.
I'm supposed to check to see if the mouse can move left, then forward, then right then back.
My problem is that when i try to run this it doesnt seem to be modifying the si di or bx registers and i cannot find out why.
Can someone please look to see if there are any glaring issues that might be causing this. I never post on here but im running out of options thank you very much.
;---------------------------------------------------------------------
; Program: nextval subroutine
;
; Function: Find next mouse move in an array 15 by 30.
; We can move into a position if its contents is blank ( 20h ).
;
; Input: Calling sequence is:
; x pointer si
; y pointer di
; dir pointer bx E=1 S=2 W=3 N=4
; maze pointer bp
;
; Output: x,y,dir modified in caller's data segment
;
; Owner: Dana A. Lasher
;
; Date: Update Reason
; --------------------------
; 11/06/2016 Original version
;
;
;---------------------------------------
.model small ;64k code and 64k data
.8086 ;only allow 8086 instructions
public nextval ;allow extrnal programs to call
;---------------------------------------
;---------------------------------------
.data ;start the data segment
;---------------------------------------
value db 30
;---------------------------------------
.code ;start the code segment
;---------------------------------------
; Save any modified registers
;---------------------------------------
nextval:
push cx ; save cx register
mov cl, 0 ; set testing phase to 0 stored in ch
;---------------------------------------
; Code to make 1 move in the maze
;---------------------------------------
testnext:
push ax ; save ax register
push dx ; save dx register
push bx ; save bx register
push si ; save si register
push di ; sav di register
mov dh, [si] ; load the x value into dh
mov dl, [di] ; load the y value into dl
inc cl ; increment the testing phase
direction:
cmp word ptr [bx], 1 ; is the moving direction East
je goingeast ; yes, jump to the going east function
cmp word ptr [bx], 2 ; is the moving direction south
je goingsouth ; yes, jump to the going south function
cmp word ptr [bx], 3 ; is the moving direction west
je goingwest ; yes, jump to the going west function
cmp word ptr [bx], 4 ; is the moving direction north
je goingnorth ; yes, jump to the going north function
jmp exit
;---------------------------------------
; Going East Check order: N-E-S-W
;---------------------------------------
goingeast:
cmp cl, 1 ; is the testing phase phase 1
je checknorth ; yes, check to see if a move north is valid
cmp cl, 2 ; is the testing phase phase 2
je checkeast ; yes, check to see if a move east is valid
cmp cl, 3 ; is the testing phase phase 3
je checksouth ; yes, check to see if a move south is valid
cmp cl, 4 ; is the testing phase phase 4
je checkwest ; yes, check to see if a move west is valid
jmp exit
;---------------------------------------
; Going South Check order: E-S-W-N
;---------------------------------------
goingsouth:
cmp cl, 1 ; is the testing phase phase 1
je checkeast ; yes, check to see if a move east is valid
cmp cl, 2 ; is the testing phase phase 2
je checksouth ; yes, check to see if a move south is valid
cmp cl, 3 ; is the testing phase phase 3
je checkwest ; yes, check to see if a move west is valid
cmp cl, 4 ; is the testing phase phase 4
je checknorth ; yes, check to see if a move north is valid
jmp exit
;---------------------------------------
; Going West Check order: S-W-N-E
;---------------------------------------
goingwest:
cmp cl, 1 ; is the testing phase phase 1
je checksouth ; yes, check to see if a move south is valid
cmp cl, 2 ; is the testing phase phase 2
je checkwest ; yes, check to see if a move west is valid
cmp cl, 3 ; is the testing phase phase 3
je checknorth ; yes, check to see if a move north is valid
cmp cl, 4 ; is the testing phase phase 4
je checkeast ; yes, check to see if a move east is valid
jmp exit
;---------------------------------------
; Going North Check order: W-N-E-S
;---------------------------------------
goingnorth:
cmp cl, 1 ; is the testing phase phase 1
je checkwest ; yes, check to see if a move west is valid
cmp cl, 2 ; is the testing phase phase 2
je checknorth ; yes, check to see if a move north is valid
cmp cl, 3 ; is the testing phase phase 3
je checkeast ; yes, check to see if a move east is valid
cmp cl, 4 ; is the testing phase phase 4
je checksouth ; yes, check to see if a move south is valid
jmp exit
;---------------------------------------
; Check East X + 1 Y same
;---------------------------------------
checkeast:
inc byte ptr [si] ; increment the x position
inc dh ; incremement dh to the x position being tested
mov ch, 1 ; update the testing direction ch to 1
jmp testposition ; jump to the test position function
;---------------------------------------
; Check South X same Y + 1
;---------------------------------------
checksouth:
inc byte ptr [di] ; increment the y position
inc dl ; increment dl to the y position being tested
mov ch, 2 ; update the testing direction ch to 2
jmp testposition ; jump to the test position function
;---------------------------------------
; Check West X - 1 Y same
;---------------------------------------
checkwest:
dec byte ptr [si] ; decrement the x position
dec dh ; update dh to the x position being tested
mov ch, 3 ; update the testing direction ch to 3
jmp testposition ; jump to the test position function
;---------------------------------------
; Check North X same Y - 1
;---------------------------------------
checknorth:
dec byte ptr [di] ; increment the y position
dec dl ; update dl to the y position being tested
mov ch, 4 ; update the testing direction ch to 4
testposition:
mov ax, [di] ; move the y position being tested into the ax register
dec ax ; decrement the ax register for the offset calculation
mul [value] ; multiply the al register by 30 and store the product in ax
add ax, [si] ; add the x position to the ax
dec ax ; decrement the ax register for the offset calculation
mov [si], ax ; move the offset calculated inside of ax into si
mov ax, ds:[bp + si] ; access the maze using data segment override with the offset in si
cmp ax, 20h ; position in the maze at the offset empty
je exit ; yes jump to the exit function
pop di ; no, restore the di register
pop si ; no, restore the si register
pop bx ; no, restore the bx register
pop dx ; no, restore the dx register
pop ax ; no, restore the ax register
jmp testnext ; test the next move direction
;---------------------------------------
; Restore registers and return
;---------------------------------------
exit:
pop di ; restore the di register
pop si ; restore the si register
pop bx ; restore the bx register
; here the dx and cx registers should still have the needed information
mov byte ptr [si], dh ; update x position
mov byte ptr [di], dl ; update y position
mov byte ptr [bx], ch ; update moving direction
pop dx ; restore the dx register
pop ax ; restore the ax register
pop cx ; restore the cx register
ret ; return
;---------------------------------------
end nextval
; Output: x,y,dir modified in caller's data segment
Given this sentence in the preamble, I think it's rather a good thing that the SI
, DI
, and BX
registers are not modified by your maze solver...
One of the problems in your code is that you destroy the original data while testing is in progress. And because you need to test several times over, the subsequent tests will be using garbage data.
Within the procedure you must only work from the local copies of X and Y that you loaded in the DH
and DL
registers.
These have to go:
inc byte ptr [si] ; increment the x position inc byte ptr [di] ; increment the y position dec byte ptr [si] ; decrement the x position dec byte ptr [di] ; increment the y position
mov [si], ax ; move the offset calculated inside of ax into si
This instruction does not what the comment says. That would be mov si, ax
.
And just as important, you should not be destroying SI
at this point in the program!
From the dec ax
instructions in the testposition part, we see that you expect X and Y to be 1-based coordinates. That's fine but you must use the locally modified values in DH
and DL
in the calculation:
The offset address calculation suits a byte-sized array (the maze). Therefore you should not be compairing a word from it!
Try next code:
mov al, DL ; move the y position being tested into the AL register
dec al ; decrement the AL register for the offset calculation
mul [value] ; multiply the al register by 30 and store the product in ax
add al, DH ; add the x position to the ax
adc ah, 0
dec ax ; decrement the ax register for the offset calculation
push si ; Preserve SI
mov si, ax ; move the offset calculated inside of ax into si
mov al, ds:[bp + si] ; access the maze using data segment override with offset si
pop si ; Restore SI
cmp al, 20h ; position in the maze at the offset empty
je exit ; yes jump to the exit function
Are you sure that the direction variable dir is actually a word. I would sooner expect to find that small value in a byte-sized variable.