---
# System prepended metadata

title: 'Switch, Loop AVR實現方式'

---

# 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數值可以不連貫
:::



