Tagc
Tagc

Reputation: 9076

Dynamic allocation for arrays in MIPS

Our team is trying to create a compiler that's fed code and produces MIPS assembly from it.

To tackle array declaration at the global scope, we create a label for the array in .text and reserve 4 bytes to hold the address pointing to the start of the array in memory.

    .text
arr:    .space 4
    .data
...
li $t0, N         # (where N = number of elements in arr)
li $v0, 9         # Load system instruction to allocate dynamic memory
li $t1, 4         # 4 bytes per element
mult $t0, $t1     # Calculates how big the allocated memory has to be in bytes.
mflo $a0          # Loads this value into $a0
syscall           # Allocates memory and returns address into $v0
la $s0, arr       # load address of arr into $s0
sw $v0, ($s0)     # Save allocated memory address into the space reserved in .text

However, the last instruction doesn't seem to be working properly for us.

This image shows exactly where the error occurs and the state of the registers at that time. I'm unsure why it's causing an error.

Edit: some more information on the error produced, updated to encompass the modified instructions at the end

[00400000] 8fa40000  lw $4, 0($29)            ; 183: lw $a0 0($sp) # argc 
[00400004] 27a50004  addiu $5, $29, 4         ; 184: addiu $a1 $sp 4 # argv 
[00400008] 24a60004  addiu $6, $5, 4          ; 185: addiu $a2 $a1 4 # envp 
[0040000c] 00041080  sll $2, $4, 2            ; 186: sll $v0 $a0 2 
[00400010] 00c23021  addu $6, $6, $2          ; 187: addu $a2 $a2 $v0 
[00400014] 0c100009  jal 0x00400024 [main]    ; 188: jal main 
[00400018] 00000000  nop                      ; 189: nop 
[0040001c] 3402000a  ori $2, $0, 10           ; 191: li $v0 10 
[00400020] 0000000c  syscall                  ; 192: syscall # syscall 10 (exit) 
[00400024] 34080003  ori $8, $0, 3            ; 9: li $t0, 3 # Load immediate value into register $t0 
[00400028] 34020009  ori $2, $0, 9            ; 10: li $v0, 9 
[0040002c] 34090004  ori $9, $0, 4            ; 11: li $t1, 4 
[00400030] 01090018  mult $8, $9              ; 12: mult $t0, $t1 
[00400034] 00002012  mflo $4                  ; 13: mflo $a0 
[00400038] 0000000c  syscall                  ; 14: syscall 
[0040003c] 3c101001  lui $16, 4097 [arr0]     ; 15: la $s0, arr0 
[00400040] ae020000  sw $2, 0($16)            ; 16: sw $v0, ($s0)


PC       = 400040
EPC      = 40003c
Cause    = 1c
BadVAddr = 1004002f
Status   = 3000ff12

Upvotes: 1

Views: 14674

Answers (1)

Sunil Bojanapally
Sunil Bojanapally

Reputation: 12658

The last instruction sw $v0, arr0($0) = MEM[$0 + arr0] = $v0 which isn't correct. However you'll be given the amount of memory requested and it is needed to save that memory pointer in a register until scope of program. The assignment might look like this,

arr:    .space 4

syscall             # Allocates memory and returns address into $v0
la     $s0, arr     # arr is pointer address
st     $v0, 0($s0)  # start base address of array

Now arr is base address of 4 bytes of memory holding the address of memory content. For good practice it is important to de-allocate the memory assigned back to OS as,

li      $v0,10      # return back to OS
syscall     

Upvotes: 3

Related Questions