1.8. PRINTF() WITH SEVERAL ARGUMENTS
Listing 1.54: Optimizing GCC 4.4.5 (assembly output)
$LC0:
.ascii "a=%d; b=%d; c=%d\000"
main:
; function prologue:
lui $28,%hi(gnu_local_gp)
addiu $sp,$sp,-32
addiu $28,$28,%lo(gnu_local_gp)
sw $31,28($sp)
; load address of printf():
lw $25,%call16(printf)($28)
; load address of the text string and set 1st argument of printf():
lui $4,%hi($LC0)
addiu $4,$4,%lo($LC0)
; set 2nd argument of printf():
li $5,1 # 0x1
; set 3rd argument of printf():
li $6,2 # 0x2
; call printf():
jalr $25
; set 4th argument of printf() (branch delay slot):
li $7,3 # 0x3
; function epilogue:
lw $31,28($sp)
; set return value to 0:
move $2,$0
; return
j $31
addiu $sp,$sp,32 ; branch delay slot
Listing 1.55: Optimizing GCC 4.4.5 (IDA)
.text:00000000 main:
.text:00000000
.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, -0x20
.text:00000008 la $gp, (gnu_local_gp & 0xFFFF)
.text:0000000C sw $ra, 0x20+var_4($sp)
.text:00000010 sw $gp, 0x20+var_10($sp)
; load address of printf():
.text:00000014 lw $t9, (printf & 0xFFFF)($gp)
; load address of the text string and set 1st argument of printf():
.text:00000018 la $a0, $LC0 # "a=%d; b=%d; c=%d"
; set 2nd argument of printf():
.text:00000020 li $a1, 1
; set 3rd argument of printf():
.text:00000024 li $a2, 2
; call printf():
.text:00000028 jalr $t9
; set 4th argument of printf() (branch delay slot):
.text:0000002C li $a3, 3
; function epilogue:
.text:00000030 lw $ra, 0x20+var_4($sp)
; set return value to 0:
.text:00000034 move $v0, $zero
; return
.text:00000038 jr $ra
.text:0000003C addiu $sp, 0x20 ; branch delay slot
IDAhas coalesced pair ofLUIandADDIUinstructions into oneLApseudo instruction. That’s why there are
no instruction at address 0x1C: becauseLAoccupies8 bytes.