foobar.cpp.elf: file format elf32-avr Disassembly of section .text: 00000000 <__vectors>: SREG = oldSREG; } } int digitalRead(uint8_t pin) { 0: 0c 94 61 00 jmp 0xc2 ; 0xc2 <__ctors_end> timer0_millis = m; timer0_overflow_count++; } unsigned long millis() { 4: 0c 94 7e 00 jmp 0xfc ; 0xfc <__bad_interrupt> 8: 0c 94 7e 00 jmp 0xfc ; 0xfc <__bad_interrupt> c: 0c 94 7e 00 jmp 0xfc ; 0xfc <__bad_interrupt> 10: 0c 94 7e 00 jmp 0xfc ; 0xfc <__bad_interrupt> 14: 0c 94 7e 00 jmp 0xfc ; 0xfc <__bad_interrupt> 18: 0c 94 7e 00 jmp 0xfc ; 0xfc <__bad_interrupt> 1c: 0c 94 7e 00 jmp 0xfc ; 0xfc <__bad_interrupt> 20: 0c 94 7e 00 jmp 0xfc ; 0xfc <__bad_interrupt> 24: 0c 94 7e 00 jmp 0xfc ; 0xfc <__bad_interrupt> 28: 0c 94 7e 00 jmp 0xfc ; 0xfc <__bad_interrupt> 2c: 0c 94 7e 00 jmp 0xfc ; 0xfc <__bad_interrupt> 30: 0c 94 7e 00 jmp 0xfc ; 0xfc <__bad_interrupt> 34: 0c 94 7e 00 jmp 0xfc ; 0xfc <__bad_interrupt> 38: 0c 94 7e 00 jmp 0xfc ; 0xfc <__bad_interrupt> 3c: 0c 94 7e 00 jmp 0xfc ; 0xfc <__bad_interrupt> 40: 0c 94 16 01 jmp 0x22c ; 0x22c <__vector_16> 44: 0c 94 7e 00 jmp 0xfc ; 0xfc <__bad_interrupt> 48: 0c 94 7e 00 jmp 0xfc ; 0xfc <__bad_interrupt> 4c: 0c 94 7e 00 jmp 0xfc ; 0xfc <__bad_interrupt> 50: 0c 94 7e 00 jmp 0xfc ; 0xfc <__bad_interrupt> 54: 0c 94 7e 00 jmp 0xfc ; 0xfc <__bad_interrupt> 58: 0c 94 7e 00 jmp 0xfc ; 0xfc <__bad_interrupt> 5c: 0c 94 7e 00 jmp 0xfc ; 0xfc <__bad_interrupt> 60: 0c 94 7e 00 jmp 0xfc ; 0xfc <__bad_interrupt> 64: 0c 94 7e 00 jmp 0xfc ; 0xfc <__bad_interrupt> 00000068 : 68: 00 00 00 00 24 00 27 00 2a 00 ....$.'.*. 00000072 : 72: 00 00 00 00 25 00 28 00 2b 00 ....%.(.+. 0000007c : 7c: 00 00 00 00 23 00 26 00 29 00 ....#.&.). 00000086 : 86: 04 04 04 04 04 04 04 04 02 02 02 02 02 02 03 03 ................ 96: 03 03 03 03 .... 0000009a : 9a: 01 02 04 08 10 20 40 80 01 02 04 08 10 20 01 02 ..... @...... .. aa: 04 08 10 20 ... 000000ae : ae: 00 00 00 07 00 02 01 00 00 03 04 06 00 00 00 00 ................ be: 00 00 00 00 .... 000000c2 <__ctors_end>: c2: 11 24 eor r1, r1 c4: 1f be out 0x3f, r1 ; 63 c6: cf ef ldi r28, 0xFF ; 255 c8: d8 e0 ldi r29, 0x08 ; 8 ca: de bf out 0x3e, r29 ; 62 cc: cd bf out 0x3d, r28 ; 61 000000ce <__do_copy_data>: ce: 11 e0 ldi r17, 0x01 ; 1 d0: a0 e0 ldi r26, 0x00 ; 0 d2: b1 e0 ldi r27, 0x01 ; 1 d4: e6 e3 ldi r30, 0x36 ; 54 d6: f3 e0 ldi r31, 0x03 ; 3 d8: 02 c0 rjmp .+4 ; 0xde <.do_copy_data_start> 000000da <.do_copy_data_loop>: da: 05 90 lpm r0, Z+ dc: 0d 92 st X+, r0 000000de <.do_copy_data_start>: de: a2 30 cpi r26, 0x02 ; 2 e0: b1 07 cpc r27, r17 e2: d9 f7 brne .-10 ; 0xda <.do_copy_data_loop> 000000e4 <__do_clear_bss>: e4: 11 e0 ldi r17, 0x01 ; 1 e6: a2 e0 ldi r26, 0x02 ; 2 e8: b1 e0 ldi r27, 0x01 ; 1 ea: 01 c0 rjmp .+2 ; 0xee <.do_clear_bss_start> 000000ec <.do_clear_bss_loop>: ec: 1d 92 st X+, r1 000000ee <.do_clear_bss_start>: ee: ab 30 cpi r26, 0x0B ; 11 f0: b1 07 cpc r27, r17 f2: e1 f7 brne .-8 ; 0xec <.do_clear_bss_loop> f4: 0e 94 0f 01 call 0x21e ; 0x21e
f8: 0c 94 99 01 jmp 0x332 ; 0x332 <_exit> 000000fc <__bad_interrupt>: fc: 0c 94 00 00 jmp 0 ; 0x0 <__vectors> 00000100 : if (foo != TEST_VALUE) digitalWrite(13, HIGH); } void loop(void) { } 100: 08 95 ret 00000102 : void loop(void); int foo = TEST_VALUE; void setup(void) { pinMode(13, OUTPUT); 102: 8d e0 ldi r24, 0x0D ; 13 104: 61 e0 ldi r22, 0x01 ; 1 106: 0e 94 91 00 call 0x122 ; 0x122 if (foo != TEST_VALUE) digitalWrite(13, HIGH); 10a: 80 91 00 01 lds r24, 0x0100 10e: 90 91 01 01 lds r25, 0x0101 112: 8f 5f subi r24, 0xFF ; 255 114: 9f 4f sbci r25, 0xFF ; 255 116: 21 f0 breq .+8 ; 0x120 118: 8d e0 ldi r24, 0x0D ; 13 11a: 61 e0 ldi r22, 0x01 ; 1 11c: 0e 94 b7 00 call 0x16e ; 0x16e 120: 08 95 ret 00000122 : #include "wiring_private.h" #include "pins_arduino.h" void pinMode(uint8_t pin, uint8_t mode) { uint8_t bit = digitalPinToBitMask(pin); 122: 48 2f mov r20, r24 124: 50 e0 ldi r21, 0x00 ; 0 126: ca 01 movw r24, r20 128: 86 56 subi r24, 0x66 ; 102 12a: 9f 4f sbci r25, 0xFF ; 255 12c: fc 01 movw r30, r24 12e: 24 91 lpm r18, Z+ uint8_t port = digitalPinToPort(pin); 130: 4a 57 subi r20, 0x7A ; 122 132: 5f 4f sbci r21, 0xFF ; 255 134: fa 01 movw r30, r20 136: 84 91 lpm r24, Z+ volatile uint8_t *reg; if (port == NOT_A_PIN) return; 138: 88 23 and r24, r24 13a: c1 f0 breq .+48 ; 0x16c // JWS: can I let the optimizer do this? reg = portModeRegister(port); 13c: e8 2f mov r30, r24 13e: f0 e0 ldi r31, 0x00 ; 0 140: ee 0f add r30, r30 142: ff 1f adc r31, r31 144: e8 59 subi r30, 0x98 ; 152 146: ff 4f sbci r31, 0xFF ; 255 148: a5 91 lpm r26, Z+ 14a: b4 91 lpm r27, Z+ if (mode == INPUT) { 14c: 66 23 and r22, r22 14e: 41 f4 brne .+16 ; 0x160 uint8_t oldSREG = SREG; 150: 9f b7 in r25, 0x3f ; 63 cli(); 152: f8 94 cli *reg &= ~bit; 154: 8c 91 ld r24, X 156: 20 95 com r18 158: 82 23 and r24, r18 15a: 8c 93 st X, r24 SREG = oldSREG; 15c: 9f bf out 0x3f, r25 ; 63 15e: 08 95 ret } else { uint8_t oldSREG = SREG; 160: 9f b7 in r25, 0x3f ; 63 cli(); 162: f8 94 cli *reg |= bit; 164: 8c 91 ld r24, X 166: 82 2b or r24, r18 168: 8c 93 st X, r24 SREG = oldSREG; 16a: 9f bf out 0x3f, r25 ; 63 16c: 08 95 ret 0000016e : } } void digitalWrite(uint8_t pin, uint8_t val) { uint8_t timer = digitalPinToTimer(pin); 16e: 48 2f mov r20, r24 170: 50 e0 ldi r21, 0x00 ; 0 172: ca 01 movw r24, r20 174: 82 55 subi r24, 0x52 ; 82 176: 9f 4f sbci r25, 0xFF ; 255 178: fc 01 movw r30, r24 17a: 24 91 lpm r18, Z+ uint8_t bit = digitalPinToBitMask(pin); 17c: ca 01 movw r24, r20 17e: 86 56 subi r24, 0x66 ; 102 180: 9f 4f sbci r25, 0xFF ; 255 182: fc 01 movw r30, r24 184: 34 91 lpm r19, Z+ uint8_t port = digitalPinToPort(pin); 186: 4a 57 subi r20, 0x7A ; 122 188: 5f 4f sbci r21, 0xFF ; 255 18a: fa 01 movw r30, r20 18c: 94 91 lpm r25, Z+ volatile uint8_t *out; if (port == NOT_A_PIN) return; 18e: 99 23 and r25, r25 190: 09 f4 brne .+2 ; 0x194 192: 44 c0 rjmp .+136 ; 0x21c // If the pin that support PWM output, we need to turn it off // before doing a digital write. if (timer != NOT_ON_TIMER) turnOffPWM(timer); 194: 22 23 and r18, r18 196: 51 f1 breq .+84 ; 0x1ec // //static inline void turnOffPWM(uint8_t timer) __attribute__ ((always_inline)); //static inline void turnOffPWM(uint8_t timer) static void turnOffPWM(uint8_t timer) { switch (timer) 198: 23 30 cpi r18, 0x03 ; 3 19a: 71 f0 breq .+28 ; 0x1b8 19c: 24 30 cpi r18, 0x04 ; 4 19e: 28 f4 brcc .+10 ; 0x1aa 1a0: 21 30 cpi r18, 0x01 ; 1 1a2: a1 f0 breq .+40 ; 0x1cc 1a4: 22 30 cpi r18, 0x02 ; 2 1a6: 11 f5 brne .+68 ; 0x1ec 1a8: 14 c0 rjmp .+40 ; 0x1d2 1aa: 26 30 cpi r18, 0x06 ; 6 1ac: b1 f0 breq .+44 ; 0x1da 1ae: 27 30 cpi r18, 0x07 ; 7 1b0: c1 f0 breq .+48 ; 0x1e2 1b2: 24 30 cpi r18, 0x04 ; 4 1b4: d9 f4 brne .+54 ; 0x1ec 1b6: 04 c0 rjmp .+8 ; 0x1c0 { #if defined(TCCR1A) && defined(COM1A1) case TIMER1A: cbi(TCCR1A, COM1A1); break; 1b8: 80 91 80 00 lds r24, 0x0080 1bc: 8f 77 andi r24, 0x7F ; 127 1be: 03 c0 rjmp .+6 ; 0x1c6 #endif #if defined(TCCR1A) && defined(COM1B1) case TIMER1B: cbi(TCCR1A, COM1B1); break; 1c0: 80 91 80 00 lds r24, 0x0080 1c4: 8f 7d andi r24, 0xDF ; 223 1c6: 80 93 80 00 sts 0x0080, r24 1ca: 10 c0 rjmp .+32 ; 0x1ec #if defined(TCCR2) && defined(COM21) case TIMER2: cbi(TCCR2, COM21); break; #endif #if defined(TCCR0A) && defined(COM0A1) case TIMER0A: cbi(TCCR0A, COM0A1); break; 1cc: 84 b5 in r24, 0x24 ; 36 1ce: 8f 77 andi r24, 0x7F ; 127 1d0: 02 c0 rjmp .+4 ; 0x1d6 #endif #if defined(TIMER0B) && defined(COM0B1) case TIMER0B: cbi(TCCR0A, COM0B1); break; 1d2: 84 b5 in r24, 0x24 ; 36 1d4: 8f 7d andi r24, 0xDF ; 223 1d6: 84 bd out 0x24, r24 ; 36 1d8: 09 c0 rjmp .+18 ; 0x1ec #endif #if defined(TCCR2A) && defined(COM2A1) case TIMER2A: cbi(TCCR2A, COM2A1); break; 1da: 80 91 b0 00 lds r24, 0x00B0 1de: 8f 77 andi r24, 0x7F ; 127 1e0: 03 c0 rjmp .+6 ; 0x1e8 #endif #if defined(TCCR2A) && defined(COM2B1) case TIMER2B: cbi(TCCR2A, COM2B1); break; 1e2: 80 91 b0 00 lds r24, 0x00B0 1e6: 8f 7d andi r24, 0xDF ; 223 1e8: 80 93 b0 00 sts 0x00B0, r24 // If the pin that support PWM output, we need to turn it off // before doing a digital write. if (timer != NOT_ON_TIMER) turnOffPWM(timer); out = portOutputRegister(port); 1ec: e9 2f mov r30, r25 1ee: f0 e0 ldi r31, 0x00 ; 0 1f0: ee 0f add r30, r30 1f2: ff 1f adc r31, r31 1f4: ee 58 subi r30, 0x8E ; 142 1f6: ff 4f sbci r31, 0xFF ; 255 1f8: a5 91 lpm r26, Z+ 1fa: b4 91 lpm r27, Z+ if (val == LOW) { 1fc: 66 23 and r22, r22 1fe: 41 f4 brne .+16 ; 0x210 uint8_t oldSREG = SREG; 200: 9f b7 in r25, 0x3f ; 63 cli(); 202: f8 94 cli *out &= ~bit; 204: 8c 91 ld r24, X 206: 30 95 com r19 208: 83 23 and r24, r19 20a: 8c 93 st X, r24 SREG = oldSREG; 20c: 9f bf out 0x3f, r25 ; 63 20e: 08 95 ret } else { uint8_t oldSREG = SREG; 210: 9f b7 in r25, 0x3f ; 63 cli(); 212: f8 94 cli *out |= bit; 214: 8c 91 ld r24, X 216: 83 2b or r24, r19 218: 8c 93 st X, r24 SREG = oldSREG; 21a: 9f bf out 0x3f, r25 ; 63 21c: 08 95 ret 0000021e
: #include int main(void) { init(); 21e: 0e 94 5e 01 call 0x2bc ; 0x2bc setup(); 222: 0e 94 81 00 call 0x102 ; 0x102 for (;;) loop(); 226: 0e 94 80 00 call 0x100 ; 0x100 22a: fd cf rjmp .-6 ; 0x226 0000022c <__vector_16>: volatile unsigned long timer0_overflow_count = 0; volatile unsigned long timer0_millis = 0; static unsigned char timer0_fract = 0; SIGNAL(TIMER0_OVF_vect) { 22c: 1f 92 push r1 22e: 0f 92 push r0 230: 0f b6 in r0, 0x3f ; 63 232: 0f 92 push r0 234: 11 24 eor r1, r1 236: 2f 93 push r18 238: 3f 93 push r19 23a: 8f 93 push r24 23c: 9f 93 push r25 23e: af 93 push r26 240: bf 93 push r27 // copy these to local variables so they can be stored in registers // (volatile variables must be read from memory on every access) unsigned long m = timer0_millis; 242: 80 91 06 01 lds r24, 0x0106 246: 90 91 07 01 lds r25, 0x0107 24a: a0 91 08 01 lds r26, 0x0108 24e: b0 91 09 01 lds r27, 0x0109 unsigned char f = timer0_fract; 252: 30 91 0a 01 lds r19, 0x010A m += MILLIS_INC; 256: 01 96 adiw r24, 0x01 ; 1 258: a1 1d adc r26, r1 25a: b1 1d adc r27, r1 f += FRACT_INC; 25c: 23 2f mov r18, r19 25e: 2d 5f subi r18, 0xFD ; 253 if (f >= FRACT_MAX) { 260: 2d 37 cpi r18, 0x7D ; 125 262: 20 f0 brcs .+8 ; 0x26c <__vector_16+0x40> f -= FRACT_MAX; 264: 2d 57 subi r18, 0x7D ; 125 m += 1; 266: 01 96 adiw r24, 0x01 ; 1 268: a1 1d adc r26, r1 26a: b1 1d adc r27, r1 } timer0_fract = f; 26c: 20 93 0a 01 sts 0x010A, r18 timer0_millis = m; 270: 80 93 06 01 sts 0x0106, r24 274: 90 93 07 01 sts 0x0107, r25 278: a0 93 08 01 sts 0x0108, r26 27c: b0 93 09 01 sts 0x0109, r27 timer0_overflow_count++; 280: 80 91 02 01 lds r24, 0x0102 284: 90 91 03 01 lds r25, 0x0103 288: a0 91 04 01 lds r26, 0x0104 28c: b0 91 05 01 lds r27, 0x0105 290: 01 96 adiw r24, 0x01 ; 1 292: a1 1d adc r26, r1 294: b1 1d adc r27, r1 296: 80 93 02 01 sts 0x0102, r24 29a: 90 93 03 01 sts 0x0103, r25 29e: a0 93 04 01 sts 0x0104, r26 2a2: b0 93 05 01 sts 0x0105, r27 } 2a6: bf 91 pop r27 2a8: af 91 pop r26 2aa: 9f 91 pop r25 2ac: 8f 91 pop r24 2ae: 3f 91 pop r19 2b0: 2f 91 pop r18 2b2: 0f 90 pop r0 2b4: 0f be out 0x3f, r0 ; 63 2b6: 0f 90 pop r0 2b8: 1f 90 pop r1 2ba: 18 95 reti 000002bc : void init() { // this needs to be called before setup() or some functions won't // work there sei(); 2bc: 78 94 sei // on the ATmega168, timer 0 is also used for fast hardware pwm // (using phase-correct PWM would mean that timer 0 overflowed half as often // resulting in different millis() behavior on the ATmega8 and ATmega168) #if defined(TCCR0A) && defined(WGM01) sbi(TCCR0A, WGM01); 2be: 84 b5 in r24, 0x24 ; 36 2c0: 82 60 ori r24, 0x02 ; 2 2c2: 84 bd out 0x24, r24 ; 36 sbi(TCCR0A, WGM00); 2c4: 84 b5 in r24, 0x24 ; 36 2c6: 81 60 ori r24, 0x01 ; 1 2c8: 84 bd out 0x24, r24 ; 36 // this combination is for the standard atmega8 sbi(TCCR0, CS01); sbi(TCCR0, CS00); #elif defined(TCCR0B) && defined(CS01) && defined(CS00) // this combination is for the standard 168/328/1280/2560 sbi(TCCR0B, CS01); 2ca: 85 b5 in r24, 0x25 ; 37 2cc: 82 60 ori r24, 0x02 ; 2 2ce: 85 bd out 0x25, r24 ; 37 sbi(TCCR0B, CS00); 2d0: 85 b5 in r24, 0x25 ; 37 2d2: 81 60 ori r24, 0x01 ; 1 2d4: 85 bd out 0x25, r24 ; 37 // enable timer 0 overflow interrupt #if defined(TIMSK) && defined(TOIE0) sbi(TIMSK, TOIE0); #elif defined(TIMSK0) && defined(TOIE0) sbi(TIMSK0, TOIE0); 2d6: ee e6 ldi r30, 0x6E ; 110 2d8: f0 e0 ldi r31, 0x00 ; 0 2da: 80 81 ld r24, Z 2dc: 81 60 ori r24, 0x01 ; 1 2de: 80 83 st Z, r24 // timers 1 and 2 are used for phase-correct hardware pwm // this is better for motors as it ensures an even waveform // note, however, that fast pwm mode can achieve a frequency of up // 8 MHz (with a 16 MHz clock) at 50% duty cycle TCCR1B = 0; 2e0: e1 e8 ldi r30, 0x81 ; 129 2e2: f0 e0 ldi r31, 0x00 ; 0 2e4: 10 82 st Z, r1 // set timer 1 prescale factor to 64 #if defined(TCCR1B) && defined(CS11) && defined(CS10) sbi(TCCR1B, CS11); 2e6: 80 81 ld r24, Z 2e8: 82 60 ori r24, 0x02 ; 2 2ea: 80 83 st Z, r24 sbi(TCCR1B, CS10); 2ec: 80 81 ld r24, Z 2ee: 81 60 ori r24, 0x01 ; 1 2f0: 80 83 st Z, r24 sbi(TCCR1, CS11); sbi(TCCR1, CS10); #endif // put timer 1 in 8-bit phase correct pwm mode #if defined(TCCR1A) && defined(WGM10) sbi(TCCR1A, WGM10); 2f2: e0 e8 ldi r30, 0x80 ; 128 2f4: f0 e0 ldi r31, 0x00 ; 0 2f6: 80 81 ld r24, Z 2f8: 81 60 ori r24, 0x01 ; 1 2fa: 80 83 st Z, r24 // set timer 2 prescale factor to 64 #if defined(TCCR2) && defined(CS22) sbi(TCCR2, CS22); #elif defined(TCCR2B) && defined(CS22) sbi(TCCR2B, CS22); 2fc: e1 eb ldi r30, 0xB1 ; 177 2fe: f0 e0 ldi r31, 0x00 ; 0 300: 80 81 ld r24, Z 302: 84 60 ori r24, 0x04 ; 4 304: 80 83 st Z, r24 // configure timer 2 for phase correct pwm (8-bit) #if defined(TCCR2) && defined(WGM20) sbi(TCCR2, WGM20); #elif defined(TCCR2A) && defined(WGM20) sbi(TCCR2A, WGM20); 306: e0 eb ldi r30, 0xB0 ; 176 308: f0 e0 ldi r31, 0x00 ; 0 30a: 80 81 ld r24, Z 30c: 81 60 ori r24, 0x01 ; 1 30e: 80 83 st Z, r24 #if defined(ADCSRA) // set a2d prescale factor to 128 // 16 MHz / 128 = 125 KHz, inside the desired 50-200 KHz range. // XXX: this will not work properly for other clock speeds, and // this code should use F_CPU to determine the prescale factor. sbi(ADCSRA, ADPS2); 310: ea e7 ldi r30, 0x7A ; 122 312: f0 e0 ldi r31, 0x00 ; 0 314: 80 81 ld r24, Z 316: 84 60 ori r24, 0x04 ; 4 318: 80 83 st Z, r24 sbi(ADCSRA, ADPS1); 31a: 80 81 ld r24, Z 31c: 82 60 ori r24, 0x02 ; 2 31e: 80 83 st Z, r24 sbi(ADCSRA, ADPS0); 320: 80 81 ld r24, Z 322: 81 60 ori r24, 0x01 ; 1 324: 80 83 st Z, r24 // enable a2d conversions sbi(ADCSRA, ADEN); 326: 80 81 ld r24, Z 328: 80 68 ori r24, 0x80 ; 128 32a: 80 83 st Z, r24 // here so they can be used as normal digital i/o; they will be // reconnected in Serial.begin() #if defined(UCSRB) UCSRB = 0; #elif defined(UCSR0B) UCSR0B = 0; 32c: 10 92 c1 00 sts 0x00C1, r1 #endif } 330: 08 95 ret 00000332 <_exit>: 332: f8 94 cli 00000334 <__stop_program>: 334: ff cf rjmp .-2 ; 0x334 <__stop_program>