For our coursework we had to write code in MARS to calculate the memory address of a given coordinate.
.globl main
.data
amountOfRows: .word 16 # The mount of rows of pixels
amountOfColumns: .word 32 # The mount of columns of pixels
promptRows: .asciiz "Please enter the row number:\n"
promptCols: .asciiz "Please enter the column number:\n"
msgShowMemoryAddress: .asciiz "The memory address for the pixel is:\n"
msgErrorValues: .asciiz "The entered value for row/column is invalid, please enter a valid value:\n"
.text
###################################################################################
translate_coordinates:
sw $fp, 0($sp) # push old frame pointer (dynamic link)
move $fp, $sp # frame pointer now points to the top of the stack
subu $sp, $sp, 20 # allocate 16 bytes on the stack
sw $ra, -4($fp) # store the value of the return address
sw $s0, -8($fp) # save locally used registers
sw $s1, -12($fp)
sw $s2, -16($fp)
move $s0, $a0 # $s0 = x coordinate
move $s1, $a1 # $s1 = y coordinate
move $s2, $a2 # $s2 = width for calculations
sll $t3, $s1, 5 # shift y left by 5 which is equal to multiplication of 32
add $t4, $t3, $s0 # (y * 32) + x = index of pixel
sll $t5, $t4, 2 # shift index left by 2 which is equal to multiplication of 4
add $t6, $gp, $t5 # memory address = gp + offset
move $v0, $t6 # place result in return value location
lw $s2, -16($fp) # reset saved register $s2
lw $s1, -12($fp) # reset saved register $s1
lw $s0, -8($fp) # reset saved register $s0
lw $ra, -4($fp) # get return address from frame
move $sp, $fp # get old frame pointer from current fra
lw $fp, ($sp) # restore old frame pointer
jr $ra
###################################################################################
main:
li $v0, 4 # print string
la $a0, promptRows # message to ask the user for the row number
syscall
li $v0, 5 # read integer
syscall # ask the user for a row number
move $t0, $v0
li $v0, 4 # print string
la $a0, promptCols # message to ask the user for the column number
syscall
li $v0, 5 # read integer
syscall # ask the user for a column number
move $t1, $v0
lw $t2, amountOfColumns #load amountOfColumns into $t2
move $a0, $t0 # Put procedure arguments
move $a1, $t1 # Put procedure arguments
move $a2, $t2
jal translate_coordinates # Call procedure
move $t6, $v0 # Get procedure result
move $a0, $t6
li $v0, 1 # syscall code 1 is for print_int
syscall
exit:
li $v0, 10 # syscall to end the program
syscall
I wrote this code to calculate the memory address of a pixel but whenever I run it I get this error:
Error in : invalid program counter value: 0x00000000
We had to use a stackframe for this and I'm quite new to that.
Because I'm quite new to it, it might be that I made some mistakes when it comes to that.
By default, MARS starts running the code at the start of .text
, and since in your code the function comes before main
, it is running the function without calling it properly.
There are three options:
j main
immediately after .text
main
if defined (off by default)main
comes immediately after .text