# Switch, Loop AVR實現方式
###### tags:
## if else
```c=
int ifelse(int x){
int w = 1;
if (x == 3){
x -= 2;
x += w * 3;
}
else if (x == 4){
x += w * 3;
}
else if (x == 1 || x == 2){
x += 3;
}
else if (x == 100){
x = w;
}
else{
x = 0;
}
return x;
}
```
反組譯後
```raw=
00000266 <ifelse>:
266: 28 2f mov r18, r24
268: 39 2f mov r19, r25
26a: 23 30 cpi r18, 0x03 ; 3
26c: 31 05 cpc r19, r1
26e: 71 f0 breq .+28 ; 0x28c <ifelse+0x26>
270: 24 30 cpi r18, 0x04 ; 4
272: 31 05 cpc r19, r1
274: 71 f0 breq .+28 ; 0x292 <ifelse+0x2c>
276: c9 01 movw r24, r18
278: 01 97 sbiw r24, 0x01 ; 1
27a: 82 30 cpi r24, 0x02 ; 2
27c: 91 05 cpc r25, r1
27e: 60 f0 brcs .+24 ; 0x298 <ifelse+0x32>
280: 24 36 cpi r18, 0x64 ; 100
282: 31 05 cpc r19, r1
284: 59 f0 breq .+22 ; 0x29c <ifelse+0x36>
286: 90 e0 ldi r25, 0x00 ; 0
288: 80 e0 ldi r24, 0x00 ; 0
28a: 08 95 ret
28c: c9 01 movw r24, r18
28e: 01 96 adiw r24, 0x01 ; 1
290: 08 95 ret
292: c9 01 movw r24, r18
294: 03 96 adiw r24, 0x03 ; 3
296: 08 95 ret
298: 04 96 adiw r24, 0x04 ; 4
29a: 08 95 ret
29c: 81 e0 ldi r24, 0x01 ; 1
29e: 90 e0 ldi r25, 0x00 ; 0
2a0: 08 95 ret
```
:::info
26a 對輸入x(r18、r19)直接進行常數比較
26e 則是針對比較結果是否相等進行分支,若成立則PC跳至28c位置
若否則進行下一次比較
:::
## switch case
```c=
int switch_x(int x){
int w = 1;
switch(x){
case 1:
case 2:
x += 3;
break;
case 3:
x -= 2;
/*fall through*/
case 4:
x += w * 3;
break;
case 100:
x = w;
break;
default:
x = 0;
}
return x;
}
```
反組譯後
```raw=
0000021a <switch_x>:
21a: 28 2f mov r18, r24
21c: 39 2f mov r19, r25
21e: 24 30 cpi r18, 0x04 ; 4
220: 31 05 cpc r19, r1
222: 49 f0 breq .+18 ; 0x236 <switch_x+0x1c>
224: a4 f4 brge .+40 ; 0x24e <switch_x+0x34>
226: 23 30 cpi r18, 0x03 ; 3
228: 31 05 cpc r19, r1
22a: 44 f0 brlt .+16 ; 0x23c <switch_x+0x22>
22c: 23 30 cpi r18, 0x03 ; 3
22e: 31 05 cpc r19, r1
230: 59 f4 brne .+22 ; 0x248 <switch_x+0x2e>
232: 22 50 subi r18, 0x02 ; 2
234: 31 09 sbc r19, r1
236: c9 01 movw r24, r18
238: 03 96 adiw r24, 0x03 ; 3
23a: 08 95 ret
23c: 12 16 cp r1, r18
23e: 13 06 cpc r1, r19
240: 64 f0 brlt .+24 ; 0x25a <switch_x+0x40>
242: 90 e0 ldi r25, 0x00 ; 0
244: 80 e0 ldi r24, 0x00 ; 0
246: 08 95 ret
248: 90 e0 ldi r25, 0x00 ; 0
24a: 80 e0 ldi r24, 0x00 ; 0
24c: 08 95 ret
24e: 24 36 cpi r18, 0x64 ; 100
250: 31 05 cpc r19, r1
252: 31 f4 brne .+12 ; 0x260 <switch_x+0x46>
254: 81 e0 ldi r24, 0x01 ; 1
256: 90 e0 ldi r25, 0x00 ; 0
258: 08 95 ret
25a: c9 01 movw r24, r18
25c: 03 96 adiw r24, 0x03 ; 3
25e: 08 95 ret
260: 90 e0 ldi r25, 0x00 ; 0
262: 80 e0 ldi r24, 0x00 ; 0
264: 08 95 ret
```
:::info
switch case的實現方式邏輯上大致為比較(cpc、cpi)輸入x(r18及r19)
並對結果進行分支(breq、brge、brlt、brne...etc)
與電腦的switch case實現方式不同,在AVR上實現方式基本和if else一樣,不會有jump table,因此case數值可以不連貫
:::