Assembly Language for Beginners

(nextflipdebug2) #1

1.15. SWITCH()/CASE/DEFAULT


b .L32
.L35:
adrp x0, .LC14 ; "two"
add x0, x0, :lo12:.LC14
bl puts
b .L32
.L38:
adrp x0, .LC15 ; "something unknown"
add x0, x0, :lo12:.LC15
bl puts
nop
.L32:
ldp x29, x30, [sp], 32
ret


The type of the input value isint, hence registerW0is used to hold it instead of the wholeX0register.


The string pointers are passed toputs()using anADRP/ADDinstructions pair just like it was demonstrated
in the “Hello, world!” example:1.5.4 on page 24.


ARM64: Optimizing GCC (Linaro) 4.9


f12:
cmp w0, 1
beq .L31
cmp w0, 2
beq .L32
cbz w0, .L35
; default case
adrp x0, .LC15 ; "something unknown"
add x0, x0, :lo12:.LC15
b puts
.L35:
adrp x0, .LC12 ; "zero"
add x0, x0, :lo12:.LC12
b puts
.L32:
adrp x0, .LC14 ; "two"
add x0, x0, :lo12:.LC14
b puts
.L31:
adrp x0, .LC13 ; "one"
add x0, x0, :lo12:.LC13
b puts


Better optimized piece of code. CBZ(Compare and Branch on Zero) instruction does jump ifW0is zero.
There is also a direct jump toputs()instead of calling it, like it was explained before:1.15.1 on page 154.


MIPS


Listing 1.151: Optimizing GCC 4.4.5 (IDA)

f:
lui $gp, (__gnu_local_gp >> 16)
; is it 1?
li $v0, 1
beq $a0, $v0, loc_60
la $gp, (__gnu_local_gp & 0xFFFF) ; branch delay slot
; is it 2?
li $v0, 2
beq $a0, $v0, loc_4C
or $at, $zero ; branch delay slot, NOP
; jump, if not equal to 0:
bnez $a0, loc_38
or $at, $zero ; branch delay slot, NOP
; zero case:

Free download pdf