Search code examples
mipsmips32

MIPS "lui" Operator and Register $1


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:

  1. Note that SPIM used register $1 for the replacement. Could it have used any other register? Why?

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 

Solution

  • 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.