I've read through some Q&As about this error on here, but I still don't understand what it means. I have a code in which I try to calculate p(n, r) and I keep getting this error: "line 26: Runtime exception at 0x00400044: fetch address not aligned on word boundary 0x00000006". I don't understand how it's not aligned since to my own knowledge, I haven't manipulated the address.
# n and r are assumed to be integers and n > r
.data
textN: .asciiz "enter n: "
textR: .asciiz "enter r: "
.text
main:
li $v0, 4
la $a0, textN
syscall
li $v0, 6
syscall
move $t0, $v0
li $v0, 4
la $a0, textR
syscall
li $v0, 5
syscall
move $t1, $v0
move $a0, $t0
jal Factorial
la $t7, ($v0)
l.s $f0, ($t7) #line 26
sub $a0, $t0, $t1
jal Factorial
la $t7, ($v0)
l.s $f1, ($t7)
div.s $f12, $f0, $f1
li $v0, 2
syscall
jr $ra
Factorial:
beq $a0, 1, Exception
subi $sp, $sp, 8
sw $t0, ($sp)
sw $t1, 4($sp)
move $t0, $a0
move $v0, $a0
Loop:
subi $t0, $t0, 1
beq $t0, $zero, Exit
sub $t1, $a0, $t0
mul $v0, $v0, $t1
Exit:
lw $t0, ($sp)
lw $t1, 4($sp)
addi $sp, $sp, 8
jr $ra
Exception:
addi $v0, $v0, 1
jr $ra
At first, I hadn't included the la instruction and line 26 was l.s $f0, ($v0). I assumed that the current update to line 26 and 27 was what was missing, but the error I'm receiving has remained unchanged.
I think you're a bit confused about what parentheses really mean.
li $t0,8
move $t1,$t0 ;copy the number 8 from $t0 into $t1.
lw $t2,($t0) ;load the four bytes at memory address 0x00000008 into $t2
Essentially, parentheses around a register are the pointer star *
in C, and la $t0, myLabel
is the same as typename* ptr = &myLabel;
. (I used li
in the example above because a memory address is a number itself, but that's not usually what you would do if you really were dereferencing a pointer.)
Your function factorial
is intended to return an int
, so you don't want to dereference that value. Assembly has no type safety at all, and lets you treat any register as a pointer to memory at any time.
The actual source of your error message, however, has to do with a limitation of the MIPS CPU. Your input value for the factorial function was 3, right? I could tell by the error message. Rather than trying to copy the number 6 to $f1
(which wouldn't work for other reasons) you were trying to load the 4 bytes at memory address 0x00000006
. This won't work, because MIPS can't use lw
or sw
to read/write 32-bit values at memory addresses that aren't aligned, i.e. not a multiple of 4. Trying to do so will result in a runtime error. But it's clear that's not what you wanted to do anyway.