mips: $v0 returns 0 instead of array pointer

0

Hey I am new to frame pointers, so I have a doubt that something is wrong with frame pointer primarily in count_sort_calculate_counts function. What I am trying to do here is to return an array of integers. Any idea how to store array as an array of unspecified length?

Result: line 112: Runtime exception at 0x004000c4: fetch address not aligned on word boundary 0x00000001

.data
list: .word 1, 3, 4, 2, 5, 6, 7, 9, 8, 0
size: .word 10
max_val: .word 10
snt: .asciiz ": "
nln: .asciiz "\n"

.text
main:
    la $a0, list
    la $a1, size
    lw $a1, 0($a1)
    jal count_sort
    
    move $a0, $v0
    la $a1, size
    lw $a1, 0($a1)
    jal print_list

# void count_sort (int *input, int i, int max_val) {
#   int *temp = (int *) malloc (max_val * sizeof(int));
#   count_sort_calculate_counts (input, temp, &i);
#   count_sort_fill_values (input, temp, i);
#   free(temp);

# $a0: address of list
# $a1: size of list
# $v0: address of sorted list

count_sort:
    # addi $sp, $sp, -4 # malloc(sizeof(int *address))
    # sw $ra, 0($sp) # address of count_sort
    la $s0, 0($ra) # address saved
    
    jal count_sort_calculate_counts # $v0 = count_sort_calculate_counts(...)
    
    move $a0, $v0 # input = temp
    move $a1, $v1 # size = max 
    addi $a1, $a1, 1 # size++
    jal count_sort_fill_values # $v0 = count_sort_fill_values(...)
    
    la $ra, 0($s0) # address resaved
    # lw $ra, 0($sp) # address of count_sort
    # addi $sp, $sp, 4 # free(address)
    jr $ra # return 

# void count_sort_calculate_counts (int *input, int *temp, int *i) {
#   for (int j = 0; j < *i; j++) {
#       temp[input[j]] = temp[input[j]] + 1;
#       // *(temp+*(input+j))++ 
#   }
# }     
    
# $a0: address of list
# $a1: address of size of list
# $v0: address of temp list
# $v1: max value of list

count_sort_calculate_counts: 
    addi $sp, $sp, -4 # malloc(sizeof(int *fp))
    sw $fp, 0($sp) # address of fp
    add $t0, $zero, $zero # j = 0
calc_for:   
    slt $t6, $t0, $a1 # $t6 = ($t0 < $a1) 
    beq $t6, $zero, calc_endfor # if ($t0 >= $a1) goto endfor
    
    sll $t1, $t0, 2 # $t1 = 4j
    add $t1, $a0, $t1 # $t1 = &input[j]
    lw $t1, 0($t1) # $t1 = input[j]
    
    sll $t2, $t1, 2 # $t2 = 4$t1
    sub $t3, $sp, $t2 # $t3 = &temp[input[j]]
    lw $t2, 0($t3) # $t2 = temp[input[j]]
    addi $t2, $t2, 1 # $t2++
    sw $t2, 0($t3) # $temp[input[j]] = $t2
    
    addi, $t0, $t0, 1 # j++
    j calc_for # goto for
calc_endfor:
    move $v1, $t1 # $v1 = input[j]
    lw $v0, 0($sp) # $fp regenerated
    addi $sp, $sp, 4 # free($fp)     
    jr $ra # return address of temp list 
    
# void count_sort_fill_values (int *input, int *temp, int i) {
#   int l = 0;
#   for (int j = 0; j < i; j++) {
#       for (int k = 0; k < temp[j]; k++) {
#           input[l] = j;           
#           l++;
#       }
#   }
# }

# $a0: address of temp list
# $a1: max value of list + 1
# $v0: address of sorted list
 
count_sort_fill_values:
    addi $sp, $sp, -4 # malloc(sizeof(int *fp))
    sw $fp, 0($sp) # fp saved
    add $t0, $zero, $zero # j = 0
    add $t1, $zero, $zero # l = 0
fill_for:   
    slt $t3, $t0, $a1 # $t3 = (j < i)
    beq $t3, $zero, fill_endfor # if (j >= i) goto endfor
    
    add $t2, $zero, $zero # k = 0
    sll $t4, $t0, 2 # j = 4j
    add $t4, $a0, $t4 # $t4 = &temp[j]
    lw $t4, 0($t4) # $t4 = temp[j]
fill_for_2: 
    slt $t5, $t2, $t4 # $t5 = (k < temp[j])
    beq $t5, $zero, fill_endfor_2 # if (k >= temp[j]) goto endfor_2
    
    sll $t6, $t1, 2 # l = 4*l
    sub $v0, $sp, $t6 # $v0 = $output[l] 
    sw $t0, 0($v0) # output[l] = j
    addi $t0, $t0, 1 # l++
    
    addi $t2, $t2, 1 # k++
    j fill_for_2 #goto for_2
fill_endfor_2:
    addi $t0, $t0, 1 # j++
    j fill_for # goto for
fill_endfor:
    lw $v0, 0($sp) # $v0 = fp
    addi $sp, $sp, 4 # free(fp)
    jr $ra # return

# void print_list (int *output, int i) {
#   for (int j = 0; j < i; j++) {
#       printf("%d ", output[j]);
#   }
# }
#
# $a0: address of sorted list
# $a1: size of list

print_list:
    move $s0, $a0 
    add $t0, $zero, $zero # j = 0
print_for:  slt $t1, $t0, $a1 # $t1 = (j < i)
    beq $t1, $zero, print_endfor # if (j >= i) goto endfor
    
    li $v0, 1 # print integer
    move $a0, $t0 # j to be printed
    syscall
    
    li $v0, 4 # print string
    la $a0, snt # sentence to be printed
    syscall
    
    sll $t1, $t0, 2 # $t1 = 4*j
    add $t1, $s0, $t1 # $t1 = &list[j]
    li $v0, 1 # print integer
    lw $a0, 0($t1) # list[j] to be printed
    syscall
    
    li $v0, 1 # print string
    la $a0, nln # newline to be printed
    syscall
    
    addi $t0, $t0, 1 # j++
print_endfor:
    jr $ra # return
assembly
mips
asked on Stack Overflow Dec 29, 2020 by pokerface • edited Dec 30, 2020 by pokerface

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0