Reputation: 9076
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
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