CHAPTER 8. ACCESSING PASSED ARGUMENTS CHAPTER 8. ACCESSING PASSED ARGUMENTS
8.4 MIPS
Listing 8.10: Optimizing GCC 4.4.5
.text:00000000 f:
; $a0=a
; $a1=b
; $a2=c
.text:00000000 mult $a1, $a0
.text:00000004 mflo $v0
.text:00000008 jr $ra
.text:0000000C addu $v0, $a2, $v0 ; branch delay slot
; result in $v0 upon return
.text:00000010 main:
.text:00000010
.text:00000010 var_10 = -0x10
.text:00000010 var_4 = -4
.text:00000010
.text:00000010 lui $gp, (gnu_local_gp >> 16)
.text:00000014 addiu $sp, -0x20
.text:00000018 la $gp, (gnu_local_gp & 0xFFFF)
.text:0000001C sw $ra, 0x20+var_4($sp)
.text:00000020 sw $gp, 0x20+var_10($sp)
; set c:
.text:00000024 li $a2, 3
; set a:
.text:00000028 li $a0, 1
.text:0000002C jal f
; set b:
.text:00000030 li $a1, 2 ; branch delay slot
; result in $v0 now
.text:00000034 lw $gp, 0x20+var_10($sp)
.text:00000038 lui $a0, ($LC0 >> 16)
.text:0000003C lw $t9, (printf & 0xFFFF)($gp)
.text:00000040 la $a0, ($LC0 & 0xFFFF)
.text:00000044 jalr $t9
; take result of f() function and pass it as a second argument to printf():
.text:00000048 move $a1, $v0 ; branch delay slot
.text:0000004C lw $ra, 0x20+var_4($sp)
.text:00000050 move $v0, $zero
.text:00000054 jr $ra
.text:00000058 addiu $sp, 0x20 ; branch delay slot
The first four function arguments are passed in four registers prefixed by A-.
There are two special registers in MIPS: HI and LO which are filled with the 64-bit result of the multiplication during the
execution of theMULTinstruction. These registers are accessible only by using theMFLOandMFHIinstructions. MFLO
here takes the low-part of the multiplication result and stores it into $V0. So the high 32-bit part of the multiplication
result is dropped (the HI register content is not used). Indeed: we work with 32-bitintdata types here.
Finally,ADDU(“Add Unsigned”) adds the value of the third argument to the result.
There are two different addition instructions in MIPS:ADDandADDU. The difference between them is not related to signed-
ness, but to exceptions.ADDcan raise an exception on overflow, which is sometimes useful^5 and supported in AdaPL, for
instance.ADDUdoes not raise exceptions on overflow. Since C/C++ does not support this, in our example we seeADDU
instead ofADD.
The 32-bit result is left in $V0.
There is a new instruction for us inmain():JAL(“Jump and Link”). The difference between JAL and JALR is that a relative
offset is encoded in the first instruction, while JALR jumps to the absolute address stored in a register (“Jump and Link
Register”). Bothf()andmain()functions are located in the same object file, so the relative address off()is known and
fixed.