Assembly Language for Beginners

(nextflipdebug2) #1

1.15. SWITCH()/CASE/DEFAULT


case.


A special function is present here in order to deal with the table and pass control,
named__ARM_common_switch8_thumb. It starts withBX PC, whose function is to switch the processor to
ARM-mode. Then you see the function for table processing.


It is too advanced to describe it here now, so let’s omit it.


It is interesting to note that the function uses theLRregister as a pointer to the table.


Indeed, after calling of this function,LRcontains the address after
BL __ARM_common_switch8_thumbinstruction, where the table starts.


Itisalsoworthnotingthatthecodeisgeneratedasaseparatefunctioninordertoreuseit, sothecompiler
doesn’t generate the same code for every switch() statement.


IDAsuccessfully perceived it as a service function and a table, and added comments to the labels like
jumptable 000000FA case 0.


MIPS


Listing 1.156: Optimizing GCC 4.4.5 (IDA)

f:
lui $gp, (gnu_local_gp >> 16)
; jump to loc_24 if input value is lesser than 5:
sltiu $v0, $a0, 5
bnez $v0, loc_24
la $gp, (
gnu_local_gp & 0xFFFF) ; branch delay slot
; input value is greater or equal to 5.
; print "something unknown" and finish:
lui $a0, ($LC5 >> 16) # "something unknown"
lw $t9, (puts & 0xFFFF)($gp)
or $at, $zero ; NOP
jr $t9
la $a0, ($LC5 & 0xFFFF) # "something unknown" ; branch delay slot


loc_24: # CODE XREF: f+8
; load address of jumptable
; LA is pseudoinstruction, LUI and ADDIU pair are there in fact:
la $v0, off_120
; multiply input value by 4:
sll $a0, 2
; sum up multiplied value and jumptable address:
addu $a0, $v0, $a0
; load element from jumptable:
lw $v0, 0($a0)
or $at, $zero ; NOP
; jump to the address we got in jumptable:
jr $v0
or $at, $zero ; branch delay slot, NOP


sub_44: # DATA XREF: .rodata:0000012C
; print "three" and finish
lui $a0, ($LC3 >> 16) # "three"
lw $t9, (puts & 0xFFFF)($gp)
or $at, $zero ; NOP
jr $t9
la $a0, ($LC3 & 0xFFFF) # "three" ; branch delay slot


sub_58: # DATA XREF: .rodata:00000130
; print "four" and finish
lui $a0, ($LC4 >> 16) # "four"
lw $t9, (puts & 0xFFFF)($gp)
or $at, $zero ; NOP
jr $t9
la $a0, ($LC4 & 0xFFFF) # "four" ; branch delay slot


sub_6C: # DATA XREF: .rodata:off_120
; print "zero" and finish

Free download pdf