CHAPTER 6.PRINTF()WITH SEVERAL ARGUMENTS CHAPTER 6.PRINTF()WITH SEVERAL ARGUMENTS
Optimizing GCC 4.4.5
Only the first 4 arguments are passed in the $A0 ...$A3 registers, the rest are passed via the stack. This is the O32 calling
convention (which is the most common one in the MIPS world). Other calling conventions (like N32) may use the registers
for different purposes.
SW abbreviates “Store Word” (from register to memory). MIPS lacks instructions for storing a value into memory, so an
instruction pair has to be used instead (LI/SW).
Listing 6.16: Optimizing GCC 4.4.5 (assembly output)
$LC0:
.ascii "a=%d; b=%d; c=%d; d=%d; e=%d; f=%d; g=%d; h=%d\012\000"
main:
; function prologue:
lui $28,%hi(gnu_local_gp)
addiu $sp,$sp,-56
addiu $28,$28,%lo(gnu_local_gp)
sw $31,52($sp)
; pass 5th argument in stack:
li $2,4 # 0x4
sw $2,16($sp)
; pass 6th argument in stack:
li $2,5 # 0x5
sw $2,20($sp)
; pass 7th argument in stack:
li $2,6 # 0x6
sw $2,24($sp)
; pass 8th argument in stack:
li $2,7 # 0x7
lw $25,%call16(printf)($28)
sw $2,28($sp)
; pass 1st argument in $a0:
lui $4,%hi($LC0)
; pass 9th argument in stack:
li $2,8 # 0x8
sw $2,32($sp)
addiu $4,$4,%lo($LC0)
; pass 2nd argument in $a1:
li $5,1 # 0x1
; pass 3rd argument in $a2:
li $6,2 # 0x2
; call printf():
jalr $25
; pass 4th argument in $a3 (branch delay slot):
li $7,3 # 0x3
; function epilogue:
lw $31,52($sp)
; set return value to 0:
move $2,$0
; return
j $31
addiu $sp,$sp,56 ; branch delay slot
Listing 6.17: Optimizing GCC 4.4.5 (IDA)
.text:00000000 main:
.text:00000000
.text:00000000 var_28 = -0x28
.text:00000000 var_24 = -0x24
.text:00000000 var_20 = -0x20
.text:00000000 var_1C = -0x1C
.text:00000000 var_18 = -0x18
.text:00000000 var_10 = -0x10
.text:00000000 var_4 = -4
.text:00000000
; function prologue:
.text:00000000 lui $gp, (gnu_local_gp >> 16)
.text:00000004 addiu $sp, -0x38
.text:00000008 la $gp, (gnu_local_gp & 0xFFFF)