Hello guyz, im new in assembly. I have this exercise using MIPS. The idea is to write a fuction that finds the bounding box of shapes in a bitmap. "0s" are the background and "1s" the foreground. I have Runtime exception at 0x00400254: fetch address not aligned on word boundary 0x1001000e on line 191 (lw $a0, ($s0)). My code look like
.data
matrix: .word 0
nrow: .word 5
ncol: .word 7
space: .asciiz " "
endl: .asciiz "\n"
original: .asciiz "The original bitmap:"
heap: .word 0 # always last defined var
.text
.globl __start
__start: jal heap_init # always start by calling this
lw $a0, nrow # create nrow-by-ncol array
lw $a1, ncol
sw $v0, matrix # save handle to it
move $a0, $v0
# init array
la $a0, original
li $v0, 4
syscall
barray: la $a0, endl
li $v0, 4
syscall
lw $a0, nrow # create nrow-by-ncol array
lw $a1, ncol
jal create_bm
sw $v0, matrix # save handle to it
move $a0, $v0
# init array
move $s4, $0
move $s0, $0 # s0 holds row index
lw $s2, nrow
lw $s3, ncol
j cond_L5
L5: move $a1, $s0
move $s1, $0 # s1 holds col
j cond_L6
L6: move $a2, $s1
move $a3, $s4
jal set_bm
addi $s4, $s4, 1 # increment count
addi $s1, $s1, 1 # increment col index
cond_L6: blt $s1, $s3, L6 # end of inner (col) loop
addi $s0, $s0, 1 # increment row index
cond_L5: blt $s0, $s2, L5 # gone through all rows?
la $a1, get_bm
jal print_array # print array
jal bbox
li $v0, 10
syscall
##
# heap_init
#
# initialises the simple heap
#
# requires AT THE END OF DATA SEGMENT
# heap: .word 0
##
heap_init: la $t9, heap # this is the address of start of heap
addi $t9, $t9, 4 # first word as ptr to next avail wrd
sw $t9, heap # save avail ptr value
jr $ra
##
# halloc
# allocate memory on simple heap
# this heap keeps growing as it has no free facility
#
# a0: size of allocation
# note that we may allocate more, to preserve word alignment
##
halloc: lw $v0, heap # ptr to next avail word
rem $t8, $a0, 4 # allocation whole words?
beqz $t8, halloc_nopad # yes, do alloc
li $t9, 4 # no: pad
sub $t9, $t9, $t8
add $a0, $a0, $t9
halloc_nopad: add $a0, $a0, $v0 # compute new avail ptr
sw $a0, heap # save its value
jr $ra # return ptr to alloc space (old ptr)
##
# create_bm
# create bitmap (bit array)
#
# a0: number of rows
# a1: number of columns
#
##
create_bm: sub $sp, $sp, 4 # push return address onto stack
sw $ra, ($sp)
move $t0, $a0 # save a0 into t0
li $a0, 12 # alloc matrix metadata (3 words)
jal halloc
move $t1, $v0 # t1 holds ptr to metadata
mul $a0, $t0, $a1 # matrix_size = nrows * ncols
rem $t2, $a0, 8 # are we on byte boundary?
sne $t2, $t2, 0 # if no: add 1 to byte count
srl $a0, $a0, 3 # divide by 8 for num of bytes
add $a0, $a0, $t2 # so not loosing bits
jal halloc # alloc on heap
sw $t0, ($t1) # save nrows
sw $a1, 4($t1) # save ncolumn
sw $v0, 8($t1) # save ptr to storage proper in metadata
move $v0, $t1 # return metadata ptr
lw $ra, ($sp) # pop return address
add $sp, $sp, 4
jr $ra # done
##
# set_bm
# set element in bit array
#
# a0: matrix ptr (array handle)
# a1: row
# a2: column
##
set_bm: lw $t0, 4($a0) # number of columns
mul $t0, $t0, $a1 # compute index in 1-dim array, as
add $t0, $t0, $a2 # row*col_size + col
rem $t2, $t0, 8 # offset in byte
srl $t0, $t0, 3 # index of byte
lw $t1, 8($a0) # load address (ptr) of array proper
add $t0, $t0, $t1 # address of byte
lbu $t3, ($t0) # load byte
li $t4, 0x00000080 # create mask
srlv $t4, $t4, $t2
or $t3, $t3, $t4 # set the bit
sb $t3, ($t0) # write byte back
jr $ra # done
##
# reset_bm
# reset element in bit array
#
# a0: matrix ptr (array handle)
# a1: row
# a2: column
##
reset_bm: lw $t0, 4($a0) # number of columns
mul $t0, $t0, $a1 # compute index in 1-dim array, as
add $t0, $t0, $a2 # row*col_size + col
rem $t2, $t0, 8 # offset in byte
srl $t0, $t0, 3 # index of byte
lw $t1, 8($a0) # load address (ptr) of array proper
add $t0, $t0, $t1 # address of byte
lbu $t3, ($t0) # load byte
li $t4, 0xFFFFFF7F # create mask
srav $t4, $t4, $t2
and $t3, $t3, $t4 # reset the bit
sb $t3, ($t0) # write byte back
jr $ra # done
##
# get_bm
# get element in byte array
#
# a0: matrix ptr (array handle)
# a1: row
# a2: column
##
get_bm: lw $t0, 4($a0) # number of columns
mul $t0, $t0, $a1 # compute index in 1-dim array, as
add $t0, $t0, $a2 # row*col_size + col
rem $t2, $t0, 8 # offset in byte
srl $t0, $t0, 3 # index of byte
lw $t1, 8($a0) # load address (ptr) of array proper
add $t0, $t0, $t1 # address of byte
lbu $t3, ($t0) # load byte
li $t4, 0x00000080 # create mask
srlv $t4, $t4, $t2
and $t3, $t3, $t4 # clear all other the bits
seq $v0, $t3, 1 # v0 is 0 if t3 == 0, 1 otherwise
jr $ra # done
bbox: sub $sp, $sp, 28
sw $ra, ($sp)
sw $s0, ($sp)
sw $s1, 4($sp)
sw $s2, 8($sp)
sw $s3, 12($sp)
move $s0, $a0
lw $a0, ($s0)
lw $s3, 4($s0)
move $a1, $s3
jal create_bm
move $s2, $v0
move $a0, $s2
jal reset_bm
move $s1, $0
j flowcL1
flowL1: move $a0, $s0
move $a1, $0
move $a2, $s1
jal get_bm
beqz $v0, flowelse1
move $a1, $s2
move $a2, $0
move $a3, $s1
jal dfs_bbox
flowelse1: addi $s1, $s1, 1
flowcL1: blt $s1, $s3, flowL1
move $v0, $s2
dfs_bbox: sub $sp, $sp, 28
sw $ra, ($sp)
sw $s0, 4($sp)
sw $s1, 8($sp)
sw $s2, 12($sp)
sw $s3, 16($sp)
sw $s4, 20($sp)
sw $s5, 24($sp)
move $s0, $a0
move $s1, $a1
move $s2, $a2
move $s3, $a3
lw $s4, ($s0)
lw $s5, 4($s0)
bltz $s2, dfspathret
bge $s2, $s4, dfspathret
bltz $s3, dfspathret
bge $s3, $s5, dfspathret
move $a1, $s2
move $a2, $s3
jal get_bm
beqz $v0, dfspathret
move $a0, $s1
jal get_bm
beq $v0, 1, dfspathret
jal set_bm
jr $ra
move $a0, $s0
move $a1, $s1
move $a2, $s2
addi $a2, $a2, 1
move $a3, $s3
jal dfs_bbox
# visit neighbour on left
move $a0, $s0
move $a1, $s1
move $a2, $s2
move $a3, $s3
addi $a3, $a3, -1
jal dfs_bbox
# visit neighbour on right
move $a0, $s0
move $a1, $s1
move $a2, $s2
move $a3, $s3
addi $a3, $a3, 1
jal dfs_bbox
# visit neighbour above
move $a0, $s0
move $a1, $s1
move $a2, $s2
addi $a2, $a2, -1
move $a3, $s3
jal dfs_bbox
dfspathret: lw $ra, ($sp)
lw $s0, 4($sp)
lw $s1, 8($sp)
lw $s2, 12($sp)
lw $s3, 16($sp)
lw $s4, 20($sp)
lw $s5, 24($sp)
add $sp, $sp, 28
jr $ra
##
# print_array
# print an array (of bits, bytes or words)
#
# a0: matrix ptr (array handle)
# a1: ptr to get function
#
# requires (in data segment)
# space: .asciiz " "
# endl: .asciiz "\n"
##
print_array: sub $sp, $sp, 28 # save registers
sw $ra, ($sp) # push return address
sw $s0, 4($sp) # push s0
sw $s1, 8($sp) # push s1
sw $s2, 12($sp) # push s2
sw $s3, 16($sp) # push s3
sw $s4, 20($sp) # push s4
sw $s5, 24($sp) # push s5
move $s4, $a0 # save array handle into s4
move $s5, $a1 # save get fct ptr into s5
lw $s2, ($a0) # number of rows
lw $s3, 4($a0) # number of columns
move $s0, $0 # init row index
j printbmcL1 # loop through rows
printbmL1: move $a1, $s0
move $s1, $0 # init column index
j printbmcL2
printbmL2: move $a0, $s4
move $a2, $s1
jalr $s5
move $a0, $v0
li $v0, 1
syscall
la $a0, space
li $v0, 4
syscall
addi $s1, $s1, 1 # increment col index
printbmcL2: blt $s1, $s3, printbmL2 # gone through all column?
la $a0, endl
li $v0, 4
syscall
addi $s0, $s0, 1 # increment row index
printbmcL1: blt $s0, $s2, printbmL1 # gone through all rows?
lw $ra, ($sp) # pop return address
lw $s0, 4($sp) # pop s0
lw $s1, 8($sp) # pop s1
lw $s2, 12($sp) # pop s2
lw $s3, 16($sp) # pop s3
lw $s4, 20($sp) # pop s4
lw $s5, 24($sp) # pop s5
add $sp, $sp, 28
jr $ra # done