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