For this project I am given a maze represented as an array of bytes that either contains 20h (empty space that can be moved into) or anything else (full space that cannot be moved into)
From the driver program I am given
x pointer si
y pointer di
dir pointer bx E=1 S=2 W=3 N=4
maze pointer bp
I have figured out how to modify the registers once I determine if a space is empty and have also calculated the offset into the maze at which the byte I'm testing resides.
The formula: (Y-1) * 30 + (X-1) calculates the offset of the byte I want to test into the array. 30 is the width of the maze.
So essentially I need to do something like
mov al, ds:[bp + ((Y-1) * 30 + (X-1))]
and then compare the byte stored in al from the maze with 20h to see if i can move to that position
my current code for this is: which works correctly
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
jne testnext ; yes jump to the exit function
we are graded on efficiency and its noted that we could use "advanced indirect addressing to avoid doing all of this offset calculation in ax so if you know how that could be done i would be incredibly grateful.
here is the full code:
;---------------------------------------------------------------------
; 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
push ax ; save ax register
push dx ; save dx register
mov cl, 0 ; set testing phase to 0 stored in ch
;---------------------------------------
; Code to make 1 move in the maze
;---------------------------------------
testnext:
mov ax, 0
mov dx, 0
mov dh, [si]
mov dl, [di]
inc cl ; increment the testing phase
direction:
cmp byte ptr [bx], 1 ; is the moving direction East
je goingeast ; yes, jump to the going east function
cmp byte ptr [bx], 2 ; is the moving direction south
je goingsouth ; yes, jump to the going south function
cmp byte ptr [bx], 3 ; is the moving direction west
je goingwest ; yes, jump to the going west function
cmp byte 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 dh ; incremement dh to the x position being tested
mov ch, 1 ; update the testing direction ch to 1
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
jne testnext ; yes jump to the exit function
inc byte ptr [si] ; update x position
mov byte ptr [bx], 1 ; update moving direction
jmp exit
;---------------------------------------
; Check South X same Y + 1
;---------------------------------------
checksouth:
inc dl ; increment dl to the y position being tested
mov ch, 2 ; update the testing direction ch to 2
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
jne testnext ; yes jump to the exit function
inc byte ptr [di] ; update x position
mov byte ptr [bx], 2 ; update moving direction
jmp exit
;---------------------------------------
; Check West X - 1 Y same
;---------------------------------------
checkwest:
dec dh ; update dh to the x position being tested
mov ch, 3 ; update the testing direction ch to 3
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
jne testnext ; yes jump to the exit function
dec byte ptr [si] ; update x position
mov byte ptr [bx], 3 ; update moving direction
jmp exit
;---------------------------------------
; Check North X same Y - 1
;---------------------------------------
checknorth:
dec dl ; update dl to the y position being tested
mov ch, 4 ; update the testing direction ch to 4
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
jne testnext ; yes jump to the exit function
dec byte ptr [di] ; update x position
mov byte ptr [bx], 4 ; update moving direction
jmp exit
;---------------------------------------
; Restore registers and return
;----------------d-----------------------
exit:
; here the dx and cx registers should still have the needed information
pop dx ; restore the dx register
pop ax ; restore the ax register
pop cx ; restore the cx register
ret ; return
;---------------------------------------
end nextval