1.15. SWITCH()/CASE/DEFAULT
Listing 1.161: Optimizing GCC 5.4.0 x86
1 .LC0:
2 .string "IF=%d KHz is not supportted, 3250 assumed\n"
3 f:
4 sub esp, 12
5 mov eax, DWORD PTR [esp+16]
6 cmp eax, 4000
7 je .L3
8 jg .L4
9 cmp eax, 3250
10 je .L5
11 cmp eax, 3500
12 jne .L2
13 mov BYTE PTR nco1, 56
14 mov BYTE PTR nco2, 0
15 add esp, 12
16 ret
17 .L4:
18 cmp eax, 5000
19 je .L7
20 cmp eax, 5380
21 jne .L2
22 mov BYTE PTR nco1, 86
23 mov BYTE PTR nco2, 20
24 add esp, 12
25 ret
26 .L2:
27 sub esp, 8
28 push eax
29 push OFFSET FLAT:.LC0
30 call printf
31 add esp, 16
32 .L5:
33 mov BYTE PTR nco1, 52
34 mov BYTE PTR nco2, 0
35 add esp, 12
36 ret
37 .L3:
38 mov BYTE PTR nco1, 64
39 mov BYTE PTR nco2, 0
40 add esp, 12
41 ret
42 .L7:
43 mov BYTE PTR nco1, 80
44 mov BYTE PTR nco2, 0
45 add esp, 12
46 ret
We can get to.L5label if there is number 3250 at function’s input. But we can get to this label from the
other side: we see that there are no jumps betweenprintf()call and.L5label.
Now we can understand whyswitch()statement is sometimes a source of bugs: one forgottenbreakwill
transform yourswitch()statement intofallthroughone, and several blocks will be executed instead of
single one.
1.15.5 Exercises.
Exercise #1
It’s possible to rework the C example in1.15.2 on page 166in such way that the compiler can produce
even smaller code, but will work just the same. Try to achieve it.