In SPIM (MIPS simulator):
lw $4, 0x10010000($0)
is automatically corrected to be
lui $1, 4097
lw $4, 0($1)
...since address 0x10010000 is 32 bits and the immediate value of "lw" could only hold 16 bits.
Homework Question:
Answer: Yes, it could have used any register as long as it's free.
Too easy??
Full program (note: $a0 is alias for $4):
[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] 3c011001 lui $1, 4097 ; 2: lw $a0, 0x10010000($0)
[00400028] 8c240000 lw $4, 0($1)
[0040002c] 20020001 addi $2, $0, 1 ; 3: addi $v0, $0, 1
[00400030] 0000000c syscall ; 4: syscall
[00400034] 2002000b addi $2, $0, 11 ; 6: addi $v0, $0, 11 # service #11
[00400038] 2004000a addi $4, $0, 10 ; 7: add $a0, $0, '\n' # printChar
[0040003c] 0000000c syscall ; 8: syscall # do print
[00400040] 3c011001 lui $1, 4097 ; 10: lb $a0, SIZE($0)
[00400044] 80240004 lb $4, 4($1)
[00400048] 20020001 addi $2, $0, 1 ; 11: addi $v0, $0, 1
[0040004c] 0000000c syscall ; 12: syscall
[00400050] 03e00008 jr $31 ; 13: jr $ra
The alternative name for $1
is $at
, as in Assembler Temporary. So even though any register would do, it helps if both the assembler and you follow the convention that the assembler uses $at
for things like these, and that you never use $at
. If the assembler just picked a register at random it might overwrite something that you wanted to keep.