+1 (315) 557-6473 

Allow Users To Manipulate 2D Arrays Using Assembly Language Assignment Solution.


Instructions

Objective
Write a assembly language assignment program that allows users to manipulate 2D arrays.

Requirements and Specifications

code to manipulate 2D arrays in Assembly language
code to manipulate 2D arrays in Assembly language 1
Screenshots of output
code to manipulate 2D arrays in Assembly language 2code to manipulate 2D arrays in Assembly language 3
code to manipulate 2D arrays in Assembly language 4code to manipulate 2D arrays in Assembly language 5
Source Code
;***********************************************************
; Programming Assignment 4
; Student Name:
; UT Eid:
; -------------------Save Simba (Part II)---------------------
; This is the starter code. You are given the main program
; and some declarations. The subroutines you are responsible for
; are given as empty stubs at the bottom. Follow the contract.
; You are free to rearrange your subroutines if the need were to
; arise.
;***********************************************************
.ORIG x4000
;***********************************************************
; Main Program
;***********************************************************
        JSR DISPLAY_JUNGLE
        LEA R0, JUNGLE_INITIAL
        TRAP x22
        LDI R0,BLOCKS
        JSR LOAD_JUNGLE
        JSR DISPLAY_JUNGLE
        LEA R0, JUNGLE_LOADED
        TRAP x22 ; output end message
HOMEBOUND
        LEA R0,PROMPT
        TRAP x22
        TRAP x20 ; get a character from keyboard into R0
        TRAP x21 ; echo character entered
        LD R3, ASCII_Q_COMPLEMENT ; load the 2's complement of ASCII 'Q'
        ADD R3, R0, R3 ; compare the first character with 'Q'
        BRz EXIT ; if input was 'Q', exit
;; call a converter to convert i,j,k,l to up(0) left(1),down(2),right(3) respectively
        JSR IS_INPUT_VALID
        ADD R2, R2, #0 ; R2 will be zero if the move was valid
        BRz VALID_INPUT
        LEA R0, INVALID_MOVE_STRING ; if the input was invalid, output corresponding
        TRAP x22 ; message and go back to prompt
        BR HOMEBOUND
VALID_INPUT
        JSR APPLY_MOVE ; apply the move (Input in R0)
        JSR DISPLAY_JUNGLE
        JSR IS_SIMBA_HOME
        ADD R2, R2, #0 ; R2 will be zero if Simba reached Home
        BRnp HOMEBOUND ; otherwise, loop back
EXIT
        LEA R0, GOODBYE_STRING
        TRAP x22 ; output a goodbye message
        TRAP x25 ; halt
JUNGLE_LOADED .STRINGZ "\nJungle Loaded\n"
JUNGLE_INITIAL .STRINGZ "\nJungle Initial\n"
ASCII_Q_COMPLEMENT .FILL x-71 ; two's complement of ASCII code for 'q'
PROMPT .STRINGZ "\nEnter Move \n\t(up(i) left(j),down(k),right(l)): "
INVALID_MOVE_STRING .STRINGZ "\nInvalid Input (ijkl)\n"
GOODBYE_STRING .STRINGZ "\nYou Saved Simba !Goodbye!\n"
BLOCKS .FILL x5000
;***********************************************************
; Global constants used in program
;***********************************************************
;***********************************************************
; This is the data structure for the Jungle grid
;***********************************************************
GRID .STRINGZ "+-+-+-+-+-+-+-+-+"
     .STRINGZ "| | | | | | | | |"
     .STRINGZ "+-+-+-+-+-+-+-+-+"
     .STRINGZ "| | | | | | | | |"
     .STRINGZ "+-+-+-+-+-+-+-+-+"
     .STRINGZ "| | | | | | | | |"
     .STRINGZ "+-+-+-+-+-+-+-+-+"
     .STRINGZ "| | | | | | | | |"
     .STRINGZ "+-+-+-+-+-+-+-+-+"
     .STRINGZ "| | | | | | | | |"
     .STRINGZ "+-+-+-+-+-+-+-+-+"
     .STRINGZ "| | | | | | | | |"
     .STRINGZ "+-+-+-+-+-+-+-+-+"
     .STRINGZ "| | | | | | | | |"
     .STRINGZ "+-+-+-+-+-+-+-+-+"
     .STRINGZ "| | | | | | | | |"
     .STRINGZ "+-+-+-+-+-+-+-+-+"
;***********************************************************
; this data stores the state of current position of Simba and his Home
;***********************************************************
CURRENT_ROW .BLKW #1 ; row position of Simba
CURRENT_COL .BLKW #1 ; col position of Simba
HOME_ROW .BLKW #1 ; Home coordinates (row and col)
HOME_COL .BLKW #1
;***********************************************************
;***********************************************************
;***********************************************************
;***********************************************************
;***********************************************************
;***********************************************************
; The code above is provided for you.
; DO NOT MODIFY THE CODE ABOVE THIS LINE.
;***********************************************************
;***********************************************************
;***********************************************************
;***********************************************************
;***********************************************************
;***********************************************************
;***********************************************************
;***********************************************************
; DISPLAY_JUNGLE
; Displays the current state of the Jungle Grid
; This can be called initially to display the un-populated jungle
; OR after populating it, to indicate where Simba is (*), any
; Hyena's(#) are, and Simba's Home (H).
; Input: None
; Output: None
; Notes: The displayed grid must have the row and column numbers
;***********************************************************
DISPLAY_JUNGLE
    ADD R6, R6, #-7 ; allocate space in stack for registers
    STR R0, R6, #0 ; save R0 on stack
    STR R1, R6, #1 ; save R1 on stack
    STR R2, R6, #2 ; save R2 on stack
    STR R3, R6, #3 ; save R3 on stack
    STR R4, R6, #4 ; save R4 on stack
    STR R5, R6, #5 ; save R5 on stack
    STR R7, R6, #6 ; save R7 on stack
    LEA R0, COLHEADER ; print the column header
    TRAP x22
    LD R1, GRIDPTR ; load grid address
    AND R2, R2, #0 ; row number
    LD R3, ROWWID ; load grid row width
ROWLOOP
    ; print the row start spaces
    LD R0, SPACE ; load space char
    TRAP x21 ; print space
    TRAP x21 ; print space
    ADD R0, R1, #0 ; load current grid row pointer
    TRAP x22 ; print row
    ADD R1, R1, R3 ; advance to next row
    LD R0, NEWLINE ; load newline char
    TRAP x21 ; print newline
    LD R0, ASCII0 ; load ascii 0
    ADD R0, R0, R2 ; convert row number to ascii
    TRAP x21 ; print row number
    LD R0, SPACE ; load space char
    TRAP x21 ; print space
    ADD R0, R1, #0 ; load current grid row pointer
    TRAP x22 ; print row
    ADD R1, R1, R3 ; advance to next row
    LD R0, NEWLINE ; load newline char
    TRAP x21 ; print newline
    ADD R2, R2, #1 ; increment row number
    ADD R0, R2, #-8 ; compare row with 8
    BRn ROWLOOP ; repeat loop while col < 8
    LD R0, SPACE ; load space char
    TRAP x21 ; print space
    TRAP x21 ; print space
    ADD R0, R1, #0 ; load current grid row pointer
    TRAP x22 ; print row
    LD R0, NEWLINE ; load newline char
    TRAP x21 ; print newline
    LDR R0, R6, #0 ; load R0
    LDR R1, R6, #1 ; load R1
    LDR R2, R6, #2 ; load R2
    LDR R3, R6, #3 ; load R3
    LDR R4, R6, #4 ; load R4
    LDR R5, R6, #5 ; load R5
    LDR R7, R6, #6 ; load R7
    ADD R6, R6, #7 ; restore stack pointer
    JMP R7
COLHEADER .STRINGZ "\n 0 1 2 3 4 5 6 7 \n"
SPACE .FILL x20
NEWLINE .FILL x0A
ASCII0 .FILL x30
ROWWID .FILL x12
GRIDPTR .FILL GRID
;***********************************************************
; LOAD_JUNGLE
; Input: R0 has the address of the head of a linked list of
; gridblock records. Each record has four fields:
; 0. Address of the next gridblock in the list
; 1. row # (0-7)
; 2. col # (0-7)
; 3. Symbol (can be I->Initial,H->Home or #->Hyena)
; The list is guaranteed to:
; * have only one Inital and one Home gridblock
; * have zero or more gridboxes with Hyenas
; * be terminated by a gridblock whose next address
; field is a zero
; Output: None
; This function loads the JUNGLE from a linked list by inserting
; the appropriate characters in boxes (I(*),#,H)
; You must also change the contents of these
; locations:
; 1. (CURRENT_ROW, CURRENT_COL) to hold the (row, col)
; numbers of Simba's Initial gridblock
; 2. (HOME_ROW, HOME_COL) to hold the (row, col)
; numbers of the Home gridblock
;
;***********************************************************
LOAD_JUNGLE
    ADD R6, R6, #-7 ; allocate space in stack for R7
    STR R0, R6, #0 ; save R0 on stack
    STR R1, R6, #1 ; save R1 on stack
    STR R2, R6, #2 ; save R2 on stack
    STR R3, R6, #3 ; save R3 on stack
    STR R4, R6, #4 ; save R4 on stack
    STR R5, R6, #5 ; save R5 on stack
    STR R7, R6, #6 ; save R7 on stack
    ADD R3, R0, #0 ; save head address in R3
WHILE1
    ADD R3, R3, #0 ; see if node is null
    BRz ENDWHILE ; if null, end loop
    LDR R1, R3, #1 ; load row
    LDR R2, R3, #2 ; load column
    JSR GRID_ADDRESS ; load address in grid
    LDR R2, R3, #3 ; load node character
    STR R2, R0, #0 ; save character in grid
    NOT R2, R2 ; take one's complement
    ADD R2, R2, #1 ; take two's complement (negative)
    LD R1, INITIAL ; load initial char
    ADD R1, R1, R2 ; compare character with initial
    BRnp IFHOME ; if not equal, see if it's home
    LD R1, ASTER ; load asterisk character
    STR R1, R0, #0 ; save character in grid
    LDR R1, R3, #1 ; load row
    LEA R0, CURRENT_ROW ; load current row pointer
    STR R1, R0, #0 ; save row
    LDR R1, R3, #2 ; load column
    LEA R0, CURRENT_COL ; load current column pointer
    STR R1, R0, #0 ; save column
    BR NEXT ; go to next node
IFHOME
    LD R1, HOME ; load home char
    ADD R1, R1, R2 ; compare character with home
    BRnp NEXT ; if not equal, go to next node
    LDR R1, R3, #1 ; load row
    LEA R0, HOME_ROW ; load home row pointer
    STR R1, R0, #0 ; save row
    LDR R1, R3, #2 ; load column
    LEA R0, HOME_COL ; load home column pointer
    STR R1, R0, #0 ; save column
NEXT
    LDR R3, R3, #0 ; load next node
    BR WHILE1 ; repeat loop
ENDWHILE
    LDR R0, R6, #0 ; load R0
    LDR R1, R6, #1 ; load R1
    LDR R2, R6, #2 ; load R2
    LDR R3, R6, #3 ; load R3
    LDR R4, R6, #4 ; load R4
    LDR R5, R6, #5 ; load R5
    LDR R7, R6, #6 ; load R7
    ADD R6, R6, #7 ; restore stack pointer
    JMP R7
HYENA .FILL x23
ASTER .FILL x2A
HOME .FILL x48
INITIAL .FILL x49
;***********************************************************
; GRID_ADDRESS
; Input: R1 has the row number (0-7)
; R2 has the column number (0-7)
; Output: R0 has the corresponding address of the space in the GRID
; Notes: This is a key routine. It translates the (row, col) logical
; GRID coordinates of a gridblock to the physical address in
; the GRID memory.
;***********************************************************
GRID_ADDRESS
    ADD R6, R6, #-2 ; allocate space in stack for registers
    STR R1, R6, #0 ; save R1 on stack
    STR R2, R6, #1 ; save R2 on stack
    ADD R0, R1, R1 ; multiply row * 2
    ADD R1, R0, R0 ; multiply row * 4
    ADD R1, R1, R1 ; multiply row * 8
    ADD R1, R1, R1 ; multiply row * 16
    ADD R1, R1, R0 ; add row*16 + row*2 = row*18
    ADD R1, R1, R1 ; multiply row * 36
    LD R0, ROWWID ; load row width
    ADD R1, R1, R0 ; add row*36 + 18 to get row offset in grid
    ADD R2, R2, R2 ; multiply column*2
    ADD R2, R2, #1 ; add column*2 + 1
    ADD R1, R1, R2 ; add row*36 + 18 + column*2 + 1 to get offset of (row, col)
    LD R0, GRIDPTR ; load grid address
    ADD R0, R0, R1 ; add grid address to offset to get required address
    LDR R1, R6, #0 ; load R1
    LDR R2, R6, #1 ; load R2
    ADD R6, R6, #2 ; restore stack pointer
    JMP R7
;***********************************************************
; IS_INPUT_VALID
; Input: R0 has the move (character i,j,k,l)
; Output: R2 zero if valid; -1 if invalid
; Notes: Validates move to make sure it is one of i,j,k,l
; Only checks if a valid character is entered
;***********************************************************
IS_INPUT_VALID
    ADD R6, R6, #-2 ; allocate space in stack for R7
    STR R0, R6, #0 ; save R0 on stack
    STR R1, R6, #1 ; save R1 on stack
    AND R2, R2, #0
    NOT R2, R2
    LD R1, ASCII_I_COMPLEMENT ; load the 2's complement of ASCII 'i'
    ADD R1, R0, R1 ; compare the first character with 'i'
    BRn INVALID ; if input was <'i', return -1
    LD R1, ASCII_M_COMPLEMENT ; load the 2's complement of ASCII 'l'
    ADD R1, R0, R1 ; compare the first character with 'l'
    BRp INVALID ; if input was >'l', return -1
    NOT R2, R2
INVALID
    LDR R0, R6, #0 ; load R0
    LDR R1, R6, #1 ; load R1
    ADD R6, R6, #2 ; restore stack pointer
    JMP R7
ASCII_I_COMPLEMENT .FILL x-69 ; two's complement of ASCII code for 'i'
ASCII_M_COMPLEMENT .FILL x-6c ; two's complement of ASCII code for 'l'
;***********************************************************
; SAFE_MOVE
; Input: R0 has 'i','j','k','l'
; Output: R1, R2 have the new row and col if the move is safe
; If the move is unsafe, that is, the move would
; take Simba to a Hyena or outside the Grid then
; return R1=-1
; Notes: Translates user entered move to actual row and column
; Also checks the contents of the intended space to
; move to in determining if the move is safe
; Calls GRID_ADDRESS
; This subroutine does not check if the input (R0) is
; valid. This functionality is implemented elsewhere.
;***********************************************************
SAFE_MOVE
    ADD R6, R6, #-3 ; allocate space in stack for R7
    STR R0, R6, #0 ; save R0 on stack
    STR R3, R6, #1 ; save R3 on stack
    STR R7, R6, #2 ; save R7 on stack
    LEA R1, CURRENT_ROW ; load current row pointer
    LDR R1, R1, #0 ; load row
    LEA R2, CURRENT_COL ; load current column pointer
    LDR R2, R2, #0 ; load column
    LD R3, ASCII_I_COMPLEMENT ; load the 2's complement of ASCII 'i'
    ADD R3, R0, R3 ; compare the character with 'i'
    BRz MOVU
    ADD R3, R3, #-1 ; compare the character with 'j'
    BRz MOVL
    ADD R3, R3, #-1 ; compare the character with 'k'
    BRz MOVD
MOVR
    ADD R2, R2, #1 ; x++
    BR CHKSAFE
MOVL
    ADD R2, R2, #-1 ; x--
    BR CHKSAFE
MOVU
    ADD R1, R1, #-1 ; y--
    BR CHKSAFE
MOVD
    ADD R1, R1, #1 ; y++
CHKSAFE
    ADD R1, R1, #0 ; y<0 -> unsafe
    BRn UNSAFE
    ADD R0, R1, #-7 ; y>7 -> unsafe
    BRp UNSAFE
    ADD R2, R2, #0 ; x<0 -> unsafe
    BRn UNSAFE
    ADD R0, R2, #-7 ; x>7 -> unsafe
    BRp UNSAFE
    JSR GRID_ADDRESS ; get address of new position
    LDR R0, R0, #0 ; load character at position
    LD R3, HYENA_COMPLEMENT ; load complement of hyena character
    ADD R0, R0, R3 ; compare char with hyena
    BRnp RETN ; if not hyena -> safe
UNSAFE
    AND R1, R1, #0 ; return -1
    NOT R1, R1
RETN
    LDR R0, R6, #0 ; load R0
    LDR R3, R6, #1 ; load R3
    LDR R7, R6, #2 ; load R7
    ADD R6, R6, #3 ; restore stack pointer
    JMP R7
HYENA_COMPLEMENT .FILL x-23
;***********************************************************
; APPLY_MOVE
; This subroutine makes the move if it can be completed.
; It checks to see if the movement is safe by calling
; SAFE_MOVE which returns the coordinates of where the move
; goes (or -1 if movement is unsafe as detailed below).
; If the move is Safe then this routine moves the player
; symbol to the new coordinates and clears any walls (|�s and -�s)
; as necessary for the movement to take place.
; If the movement is unsafe, output a console message of your
; choice and return.
; Input:
; R0 has move (i or j or k or l)
; Output: None; However must update the GRID and
; change CURRENT_ROW and CURRENT_COL
; if move can be successfully applied.
; Notes: Calls SAFE_MOVE and GRID_ADDRESS
;***********************************************************
APPLY_MOVE
    ADD R6, R6, #-7 ; allocate space in stack for R7
    STR R0, R6, #0 ; save R0 on stack
    STR R1, R6, #1 ; save R1 on stack
    STR R2, R6, #2 ; save R2 on stack
    STR R3, R6, #3 ; save R3 on stack
    STR R4, R6, #4 ; save R4 on stack
    STR R5, R6, #5 ; save R5 on stack
    STR R7, R6, #6 ; save R7 on stack
    LD R3, CROW ; load current row pointer
    LDR R3, R3, #0 ; load current position
    LEA R5, OLDR
    STR R3, R5, #0 ; save in oldr
    LD R4, CCOL ; load current col pointer
    LDR R4, R4, #0 ; load current position
    LEA R5, OLDC
    STR R4, R5, #0 ; save in oldc
    JSR SAFE_MOVE ; check if it's a safe move
    ADD R1, R1, #0 ; see if it's safe
    BRn NOMOVE ; if negative, don't move
    JSR GRID_ADDRESS ; get address of next move
    LD R5, ASTER
    STR R5, R0, #0 ; save asterisk
    LD R3, CROW ; load current row pointer
    STR R1, R3, #0 ; save row
    LD R4, CCOL ; load current col pointer
    STR R2, R4, #0 ; save column
    LD R1, OLDR ; get old position
    LD R2, OLDC ; get old position
    JSR GRID_ADDRESS ; get address of previous position
    LD R5, SPACE
    STR R5, R0, #0 ; save space
    LDR R3, R3, #0 ; load current row position
    LDR R4, R4, #0 ; load current col position
    LD R5, ROWWID ; load rowwidth
    NOT R0, R1
    ADD R0, R0, #1
    ADD R0, R3, R0 ; subtract cur row - old row
    BRp TSTCOL ; if positive, use rowwid
    BRz ADD0 ; if zero, use zero
    NOT R5, R5 ; use -rowwid
    ADD R5, R5, #1
    BR TSTCOL
ADD0
    AND R5, R5, #0
TSTCOL
    NOT R0, R2
    ADD R0, R0, #1
    ADD R4, R4, R0 ; subtract cur col - old col
    ADD R4, R4, R5 ; add change in row + change in col
    JSR GRID_ADDRESS ; get address of position
    ADD R0, R0, R4 ; advance grid position
    LD R5, SPACE
    STR R5, R0, #0 ; save space
    BR APPRTN
NOMOVE
    LEA R0, UNSAFE_MOVE_STRING ; if the input was unsafe, output corresponding
    TRAP x22 ; message and go back to prompt
APPRTN
    LDR R0, R6, #0 ; load R0
    LDR R1, R6, #1 ; load R1
    LDR R2, R6, #2 ; load R2
    LDR R3, R6, #3 ; load R3
    LDR R4, R6, #4 ; load R4
    LDR R5, R6, #5 ; load R5
    LDR R7, R6, #6 ; load R7
    ADD R6, R6, #7 ; restore stack pointer
    JMP R7
CROW .FILL CURRENT_ROW
CCOL .FILL CURRENT_COL
HROW .FILL HOME_ROW
HCOL .FILL HOME_COL
OLDR .BLKW 1
OLDC .BLKW 1
UNSAFE_MOVE_STRING .STRINGZ "\nUnSafe Move\n"
;***********************************************************
; IS_SIMBA_HOME
; Checks to see if the Simba has reached Home.
; Input: None
; Output: R2 is zero if Simba is Home; -1 otherwise
;
;***********************************************************
IS_SIMBA_HOME
    ADD R6, R6, #-3 ; allocate space in stack for registers
    STR R1, R6, #0 ; save R1 on stack
    STR R3, R6, #1 ; save R3 on stack
    STR R4, R6, #2 ; save R4 on stack
    LD R1, CROW ; load current row pointer
    LDR R1, R1, #0 ; load row
    LD R2, CCOL ; load current column pointer
    LDR R2, R2, #0 ; load column
    LD R3, HROW ; load home row pointer
    LDR R3, R3, #0 ; load row
    LD R4, HCOL ; load home column pointer
    LDR R4, R4, #0 ; load column
    NOT R3, R3 ; convert home row to negative
    ADD R3, R3, #1
    NOT R4, R4 ; convert home col to negative
    ADD R4, R4, #1
    ADD R1, R1, R3 ; compare rows and columns
    BRnp NOHOME ; if not equal, not home
    ADD R2, R2, R4
    BRz ISHOME ; if zero, it's home
NOHOME
    AND R2, R2, #0 ; else, return -1
    NOT R2, R2
ISHOME
    LDR R1, R6, #0 ; load R1
    LDR R3, R6, #1 ; load R3
    LDR R4, R6, #2 ; load R4
    ADD R6, R6, #3 ; restore stack pointer
    JMP R7
    .END
; This section has the linked list for the
; Jungle's layout: #(0,1)->H(4,7)->I(2,1)->#(1,1)->#(6,3)->#(3,5)->#(4,4)->#(5,6)
 .ORIG x5000
 .FILL Head ; Holds the address of the first record in the linked-list (Head)
blk2
 .FILL blk4
 .FILL #1
    .FILL #1
 .FILL x23
Head
 .FILL blk1
    .FILL #0
 .FILL #1
 .FILL x23
blk1
 .FILL blk3
 .FILL #4
 .FILL #7
 .FILL x48
blk3
 .FILL blk2
 .FILL #2
 .FILL #1
 .FILL x49
blk4
 .FILL blk5
 .FILL #6
 .FILL #3
 .FILL x23
blk7
 .FILL #0
 .FILL #5
 .FILL #6
 .FILL x23
blk6
 .FILL blk7
 .FILL #4
 .FILL #4
 .FILL x23
blk5
 .FILL blk6
 .FILL #3
 .FILL #5
 .FILL x23
 .END