The amount of behind the scenes work performed to make the Arduino IDE a friendly tool is amazing. As an example, this is the Arduino Blink demo code bundled in the IDE version 1.05 and below is the generated assembly code.
To view the generated assembly code by your Arduino IDE for your sketches follow the instructions in this guide
To view the generated assembly code by your Arduino IDE for your sketches follow the instructions in this guide
Code Editor
This is the assembly code generated by the Arduino IDE 1.05 for Arduino Uno (atmega328p)
Disassembly of section .text: 00000000 <__vectors>: timer0_millis = m; timer0_overflow_count++; } unsigned long millis() { 0: 0c 94 61 00 jmp 0xc2 ; 0xc2 <__ctors_end> SREG = oldSREG; } int digitalRead(uint8_t pin) { 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 9d 00 jmp 0x13a ; 0x13a <__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 <port_to_mode_PGM>: 68: 00 00 00 00 24 00 27 00 2a 00 ....$.'.*. 00000072 <port_to_output_PGM>: 72: 00 00 00 00 25 00 28 00 2b 00 ....%.(.+. 0000007c <port_to_input_PGM>: 7c: 00 00 00 00 23 00 26 00 29 00 ....#.&.). 00000086 <digital_pin_to_port_PGM>: 86: 04 04 04 04 04 04 04 04 02 02 02 02 02 02 03 03 ................ 96: 03 03 03 03 .... 0000009a <digital_pin_to_bit_mask_PGM>: 9a: 01 02 04 08 10 20 40 80 01 02 04 08 10 20 01 02 ..... @...... .. aa: 04 08 10 20 ... 000000ae <digital_pin_to_timer_PGM>: 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: ea e3 ldi r30, 0x3A ; 58 d6: f4 e0 ldi r31, 0x04 ; 4 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 0c 02 call 0x418 ; 0x418 <main> f8: 0c 94 1b 02 jmp 0x436 ; 0x436 <_exit> 000000fc <__bad_interrupt>: fc: 0c 94 00 00 jmp 0 ; 0x0 <__vectors> 00000100 <loop>: 100: 80 91 00 01 lds r24, 0x0100 104: 61 e0 ldi r22, 0x01 ; 1 106: 0e 94 b8 01 call 0x370 ; 0x370 <digitalWrite> 10a: 68 ee ldi r22, 0xE8 ; 232 10c: 73 e0 ldi r23, 0x03 ; 3 10e: 80 e0 ldi r24, 0x00 ; 0 110: 90 e0 ldi r25, 0x00 ; 0 112: 0e 94 e5 00 call 0x1ca ; 0x1ca <delay> 116: 80 91 00 01 lds r24, 0x0100 11a: 60 e0 ldi r22, 0x00 ; 0 11c: 0e 94 b8 01 call 0x370 ; 0x370 <digitalWrite> 120: 68 ee ldi r22, 0xE8 ; 232 122: 73 e0 ldi r23, 0x03 ; 3 124: 80 e0 ldi r24, 0x00 ; 0 126: 90 e0 ldi r25, 0x00 ; 0 128: 0e 94 e5 00 call 0x1ca ; 0x1ca <delay> 12c: 08 95 ret 0000012e <setup>: 12e: 80 91 00 01 lds r24, 0x0100 132: 61 e0 ldi r22, 0x01 ; 1 134: 0e 94 79 01 call 0x2f2 ; 0x2f2 <pinMode> 138: 08 95 ret 0000013a <__vector_16>: #if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined (__AVR_ATtiny84__) ISR(TIM0_OVF_vect) #else ISR(TIMER0_OVF_vect) #endif { 13a: 1f 92 push r1 13c: 0f 92 push r0 13e: 0f b6 in r0, 0x3f ; 63 140: 0f 92 push r0 142: 11 24 eor r1, r1 144: 2f 93 push r18 146: 3f 93 push r19 148: 8f 93 push r24 14a: 9f 93 push r25 14c: af 93 push r26 14e: 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; 150: 80 91 06 01 lds r24, 0x0106 154: 90 91 07 01 lds r25, 0x0107 158: a0 91 08 01 lds r26, 0x0108 15c: b0 91 09 01 lds r27, 0x0109 unsigned char f = timer0_fract; 160: 30 91 0a 01 lds r19, 0x010A m += MILLIS_INC; 164: 01 96 adiw r24, 0x01 ; 1 166: a1 1d adc r26, r1 168: b1 1d adc r27, r1 f += FRACT_INC; 16a: 23 2f mov r18, r19 16c: 2d 5f subi r18, 0xFD ; 253 if (f >= FRACT_MAX) { 16e: 2d 37 cpi r18, 0x7D ; 125 170: 20 f0 brcs .+8 ; 0x17a <__vector_16+0x40> f -= FRACT_MAX; 172: 2d 57 subi r18, 0x7D ; 125 m += 1; 174: 01 96 adiw r24, 0x01 ; 1 176: a1 1d adc r26, r1 178: b1 1d adc r27, r1 } timer0_fract = f; 17a: 20 93 0a 01 sts 0x010A, r18 timer0_millis = m; 17e: 80 93 06 01 sts 0x0106, r24 182: 90 93 07 01 sts 0x0107, r25 186: a0 93 08 01 sts 0x0108, r26 18a: b0 93 09 01 sts 0x0109, r27 timer0_overflow_count++; 18e: 80 91 02 01 lds r24, 0x0102 192: 90 91 03 01 lds r25, 0x0103 196: a0 91 04 01 lds r26, 0x0104 19a: b0 91 05 01 lds r27, 0x0105 19e: 01 96 adiw r24, 0x01 ; 1 1a0: a1 1d adc r26, r1 1a2: b1 1d adc r27, r1 1a4: 80 93 02 01 sts 0x0102, r24 1a8: 90 93 03 01 sts 0x0103, r25 1ac: a0 93 04 01 sts 0x0104, r26 1b0: b0 93 05 01 sts 0x0105, r27 } 1b4: bf 91 pop r27 1b6: af 91 pop r26 1b8: 9f 91 pop r25 1ba: 8f 91 pop r24 1bc: 3f 91 pop r19 1be: 2f 91 pop r18 1c0: 0f 90 pop r0 1c2: 0f be out 0x3f, r0 ; 63 1c4: 0f 90 pop r0 1c6: 1f 90 pop r1 1c8: 18 95 reti 000001ca <delay>: return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond()); } void delay(unsigned long ms) { 1ca: 9b 01 movw r18, r22 1cc: ac 01 movw r20, r24 return m; } unsigned long micros() { unsigned long m; uint8_t oldSREG = SREG, t; 1ce: 7f b7 in r23, 0x3f ; 63 cli(); 1d0: f8 94 cli m = timer0_overflow_count; 1d2: 80 91 02 01 lds r24, 0x0102 1d6: 90 91 03 01 lds r25, 0x0103 1da: a0 91 04 01 lds r26, 0x0104 1de: b0 91 05 01 lds r27, 0x0105 #if defined(TCNT0) t = TCNT0; 1e2: 66 b5 in r22, 0x26 ; 38 #error TIMER 0 not defined #endif #ifdef TIFR0 if ((TIFR0 & _BV(TOV0)) && (t < 255)) 1e4: a8 9b sbis 0x15, 0 ; 21 1e6: 05 c0 rjmp .+10 ; 0x1f2 <delay+0x28> 1e8: 6f 3f cpi r22, 0xFF ; 255 1ea: 19 f0 breq .+6 ; 0x1f2 <delay+0x28> m++; 1ec: 01 96 adiw r24, 0x01 ; 1 1ee: a1 1d adc r26, r1 1f0: b1 1d adc r27, r1 #else if ((TIFR & _BV(TOV0)) && (t < 255)) m++; #endif SREG = oldSREG; 1f2: 7f bf out 0x3f, r23 ; 63 return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond()); } void delay(unsigned long ms) { uint16_t start = (uint16_t)micros(); 1f4: ba 2f mov r27, r26 1f6: a9 2f mov r26, r25 1f8: 98 2f mov r25, r24 1fa: 88 27 eor r24, r24 1fc: 86 0f add r24, r22 1fe: 91 1d adc r25, r1 200: a1 1d adc r26, r1 202: b1 1d adc r27, r1 204: 62 e0 ldi r22, 0x02 ; 2 206: 88 0f add r24, r24 208: 99 1f adc r25, r25 20a: aa 1f adc r26, r26 20c: bb 1f adc r27, r27 20e: 6a 95 dec r22 210: d1 f7 brne .-12 ; 0x206 <delay+0x3c> 212: bc 01 movw r22, r24 214: 2d c0 rjmp .+90 ; 0x270 <delay+0xa6> return m; } unsigned long micros() { unsigned long m; uint8_t oldSREG = SREG, t; 216: ff b7 in r31, 0x3f ; 63 cli(); 218: f8 94 cli m = timer0_overflow_count; 21a: 80 91 02 01 lds r24, 0x0102 21e: 90 91 03 01 lds r25, 0x0103 222: a0 91 04 01 lds r26, 0x0104 226: b0 91 05 01 lds r27, 0x0105 #if defined(TCNT0) t = TCNT0; 22a: e6 b5 in r30, 0x26 ; 38 #error TIMER 0 not defined #endif #ifdef TIFR0 if ((TIFR0 & _BV(TOV0)) && (t < 255)) 22c: a8 9b sbis 0x15, 0 ; 21 22e: 05 c0 rjmp .+10 ; 0x23a <delay+0x70> 230: ef 3f cpi r30, 0xFF ; 255 232: 19 f0 breq .+6 ; 0x23a <delay+0x70> m++; 234: 01 96 adiw r24, 0x01 ; 1 236: a1 1d adc r26, r1 238: b1 1d adc r27, r1 #else if ((TIFR & _BV(TOV0)) && (t < 255)) m++; #endif SREG = oldSREG; 23a: ff bf out 0x3f, r31 ; 63 void delay(unsigned long ms) { uint16_t start = (uint16_t)micros(); while (ms > 0) { if (((uint16_t)micros() - start) >= 1000) { 23c: ba 2f mov r27, r26 23e: a9 2f mov r26, r25 240: 98 2f mov r25, r24 242: 88 27 eor r24, r24 244: 8e 0f add r24, r30 246: 91 1d adc r25, r1 248: a1 1d adc r26, r1 24a: b1 1d adc r27, r1 24c: e2 e0 ldi r30, 0x02 ; 2 24e: 88 0f add r24, r24 250: 99 1f adc r25, r25 252: aa 1f adc r26, r26 254: bb 1f adc r27, r27 256: ea 95 dec r30 258: d1 f7 brne .-12 ; 0x24e <delay+0x84> 25a: 86 1b sub r24, r22 25c: 97 0b sbc r25, r23 25e: 88 5e subi r24, 0xE8 ; 232 260: 93 40 sbci r25, 0x03 ; 3 262: c8 f2 brcs .-78 ; 0x216 <delay+0x4c> ms--; 264: 21 50 subi r18, 0x01 ; 1 266: 30 40 sbci r19, 0x00 ; 0 268: 40 40 sbci r20, 0x00 ; 0 26a: 50 40 sbci r21, 0x00 ; 0 start += 1000; 26c: 68 51 subi r22, 0x18 ; 24 26e: 7c 4f sbci r23, 0xFC ; 252 void delay(unsigned long ms) { uint16_t start = (uint16_t)micros(); while (ms > 0) { 270: 21 15 cp r18, r1 272: 31 05 cpc r19, r1 274: 41 05 cpc r20, r1 276: 51 05 cpc r21, r1 278: 71 f6 brne .-100 ; 0x216 <delay+0x4c> if (((uint16_t)micros() - start) >= 1000) { ms--; start += 1000; } } } 27a: 08 95 ret 0000027c <init>: void init() { // this needs to be called before setup() or some functions won't // work there sei(); 27c: 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); 27e: 84 b5 in r24, 0x24 ; 36 280: 82 60 ori r24, 0x02 ; 2 282: 84 bd out 0x24, r24 ; 36 sbi(TCCR0A, WGM00); 284: 84 b5 in r24, 0x24 ; 36 286: 81 60 ori r24, 0x01 ; 1 288: 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); 28a: 85 b5 in r24, 0x25 ; 37 28c: 82 60 ori r24, 0x02 ; 2 28e: 85 bd out 0x25, r24 ; 37 sbi(TCCR0B, CS00); 290: 85 b5 in r24, 0x25 ; 37 292: 81 60 ori r24, 0x01 ; 1 294: 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); 296: ee e6 ldi r30, 0x6E ; 110 298: f0 e0 ldi r31, 0x00 ; 0 29a: 80 81 ld r24, Z 29c: 81 60 ori r24, 0x01 ; 1 29e: 80 83 st Z, r24 // 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 #if defined(TCCR1B) && defined(CS11) && defined(CS10) TCCR1B = 0; 2a0: e1 e8 ldi r30, 0x81 ; 129 2a2: f0 e0 ldi r31, 0x00 ; 0 2a4: 10 82 st Z, r1 // set timer 1 prescale factor to 64 sbi(TCCR1B, CS11); 2a6: 80 81 ld r24, Z 2a8: 82 60 ori r24, 0x02 ; 2 2aa: 80 83 st Z, r24 #if F_CPU >= 8000000L sbi(TCCR1B, CS10); 2ac: 80 81 ld r24, Z 2ae: 81 60 ori r24, 0x01 ; 1 2b0: 80 83 st Z, r24 sbi(TCCR1, CS10); #endif #endif // put timer 1 in 8-bit phase correct pwm mode #if defined(TCCR1A) && defined(WGM10) sbi(TCCR1A, WGM10); 2b2: e0 e8 ldi r30, 0x80 ; 128 2b4: f0 e0 ldi r31, 0x00 ; 0 2b6: 80 81 ld r24, Z 2b8: 81 60 ori r24, 0x01 ; 1 2ba: 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); 2bc: e1 eb ldi r30, 0xB1 ; 177 2be: f0 e0 ldi r31, 0x00 ; 0 2c0: 80 81 ld r24, Z 2c2: 84 60 ori r24, 0x04 ; 4 2c4: 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); 2c6: e0 eb ldi r30, 0xB0 ; 176 2c8: f0 e0 ldi r31, 0x00 ; 0 2ca: 80 81 ld r24, Z 2cc: 81 60 ori r24, 0x01 ; 1 2ce: 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); 2d0: ea e7 ldi r30, 0x7A ; 122 2d2: f0 e0 ldi r31, 0x00 ; 0 2d4: 80 81 ld r24, Z 2d6: 84 60 ori r24, 0x04 ; 4 2d8: 80 83 st Z, r24 sbi(ADCSRA, ADPS1); 2da: 80 81 ld r24, Z 2dc: 82 60 ori r24, 0x02 ; 2 2de: 80 83 st Z, r24 sbi(ADCSRA, ADPS0); 2e0: 80 81 ld r24, Z 2e2: 81 60 ori r24, 0x01 ; 1 2e4: 80 83 st Z, r24 // enable a2d conversions sbi(ADCSRA, ADEN); 2e6: 80 81 ld r24, Z 2e8: 80 68 ori r24, 0x80 ; 128 2ea: 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; 2ec: 10 92 c1 00 sts 0x00C1, r1 #endif } 2f0: 08 95 ret 000002f2 <pinMode>: #define ARDUINO_MAIN #include "wiring_private.h" #include "pins_arduino.h" void pinMode(uint8_t pin, uint8_t mode) { 2f2: cf 93 push r28 2f4: df 93 push r29 uint8_t bit = digitalPinToBitMask(pin); 2f6: 48 2f mov r20, r24 2f8: 50 e0 ldi r21, 0x00 ; 0 2fa: ca 01 movw r24, r20 2fc: 86 56 subi r24, 0x66 ; 102 2fe: 9f 4f sbci r25, 0xFF ; 255 300: fc 01 movw r30, r24 302: 34 91 lpm r19, Z+ uint8_t port = digitalPinToPort(pin); 304: 4a 57 subi r20, 0x7A ; 122 306: 5f 4f sbci r21, 0xFF ; 255 308: fa 01 movw r30, r20 30a: 84 91 lpm r24, Z+ volatile uint8_t *reg, *out; if (port == NOT_A_PIN) return; 30c: 88 23 and r24, r24 30e: 69 f1 breq .+90 ; 0x36a <pinMode+0x78> // JWS: can I let the optimizer do this? reg = portModeRegister(port); 310: 90 e0 ldi r25, 0x00 ; 0 312: 88 0f add r24, r24 314: 99 1f adc r25, r25 316: fc 01 movw r30, r24 318: e8 59 subi r30, 0x98 ; 152 31a: ff 4f sbci r31, 0xFF ; 255 31c: a5 91 lpm r26, Z+ 31e: b4 91 lpm r27, Z+ out = portOutputRegister(port); 320: fc 01 movw r30, r24 322: ee 58 subi r30, 0x8E ; 142 324: ff 4f sbci r31, 0xFF ; 255 326: c5 91 lpm r28, Z+ 328: d4 91 lpm r29, Z+ if (mode == INPUT) { 32a: 66 23 and r22, r22 32c: 51 f4 brne .+20 ; 0x342 <pinMode+0x50> uint8_t oldSREG = SREG; 32e: 2f b7 in r18, 0x3f ; 63 cli(); 330: f8 94 cli *reg &= ~bit; 332: 8c 91 ld r24, X 334: 93 2f mov r25, r19 336: 90 95 com r25 338: 89 23 and r24, r25 33a: 8c 93 st X, r24 *out &= ~bit; 33c: 88 81 ld r24, Y 33e: 89 23 and r24, r25 340: 0b c0 rjmp .+22 ; 0x358 <pinMode+0x66> SREG = oldSREG; } else if (mode == INPUT_PULLUP) { 342: 62 30 cpi r22, 0x02 ; 2 344: 61 f4 brne .+24 ; 0x35e <pinMode+0x6c> uint8_t oldSREG = SREG; 346: 2f b7 in r18, 0x3f ; 63 cli(); 348: f8 94 cli *reg &= ~bit; 34a: 8c 91 ld r24, X 34c: 93 2f mov r25, r19 34e: 90 95 com r25 350: 89 23 and r24, r25 352: 8c 93 st X, r24 *out |= bit; 354: 88 81 ld r24, Y 356: 83 2b or r24, r19 358: 88 83 st Y, r24 SREG = oldSREG; 35a: 2f bf out 0x3f, r18 ; 63 35c: 06 c0 rjmp .+12 ; 0x36a <pinMode+0x78> } else { uint8_t oldSREG = SREG; 35e: 9f b7 in r25, 0x3f ; 63 cli(); 360: f8 94 cli *reg |= bit; 362: 8c 91 ld r24, X 364: 83 2b or r24, r19 366: 8c 93 st X, r24 SREG = oldSREG; 368: 9f bf out 0x3f, r25 ; 63 } } 36a: df 91 pop r29 36c: cf 91 pop r28 36e: 08 95 ret 00000370 <digitalWrite>: } } void digitalWrite(uint8_t pin, uint8_t val) { uint8_t timer = digitalPinToTimer(pin); 370: 48 2f mov r20, r24 372: 50 e0 ldi r21, 0x00 ; 0 374: ca 01 movw r24, r20 376: 82 55 subi r24, 0x52 ; 82 378: 9f 4f sbci r25, 0xFF ; 255 37a: fc 01 movw r30, r24 37c: 24 91 lpm r18, Z+ uint8_t bit = digitalPinToBitMask(pin); 37e: ca 01 movw r24, r20 380: 86 56 subi r24, 0x66 ; 102 382: 9f 4f sbci r25, 0xFF ; 255 384: fc 01 movw r30, r24 386: 94 91 lpm r25, Z+ uint8_t port = digitalPinToPort(pin); 388: 4a 57 subi r20, 0x7A ; 122 38a: 5f 4f sbci r21, 0xFF ; 255 38c: fa 01 movw r30, r20 38e: 34 91 lpm r19, Z+ volatile uint8_t *out; if (port == NOT_A_PIN) return; 390: 33 23 and r19, r19 392: 09 f4 brne .+2 ; 0x396 <digitalWrite+0x26> 394: 40 c0 rjmp .+128 ; 0x416 <digitalWrite+0xa6> // 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); 396: 22 23 and r18, r18 398: 51 f1 breq .+84 ; 0x3ee <digitalWrite+0x7e> // //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) 39a: 23 30 cpi r18, 0x03 ; 3 39c: 71 f0 breq .+28 ; 0x3ba <digitalWrite+0x4a> 39e: 24 30 cpi r18, 0x04 ; 4 3a0: 28 f4 brcc .+10 ; 0x3ac <digitalWrite+0x3c> 3a2: 21 30 cpi r18, 0x01 ; 1 3a4: a1 f0 breq .+40 ; 0x3ce <digitalWrite+0x5e> 3a6: 22 30 cpi r18, 0x02 ; 2 3a8: 11 f5 brne .+68 ; 0x3ee <digitalWrite+0x7e> 3aa: 14 c0 rjmp .+40 ; 0x3d4 <digitalWrite+0x64> 3ac: 26 30 cpi r18, 0x06 ; 6 3ae: b1 f0 breq .+44 ; 0x3dc <digitalWrite+0x6c> 3b0: 27 30 cpi r18, 0x07 ; 7 3b2: c1 f0 breq .+48 ; 0x3e4 <digitalWrite+0x74> 3b4: 24 30 cpi r18, 0x04 ; 4 3b6: d9 f4 brne .+54 ; 0x3ee <digitalWrite+0x7e> 3b8: 04 c0 rjmp .+8 ; 0x3c2 <digitalWrite+0x52> { #if defined(TCCR1A) && defined(COM1A1) case TIMER1A: cbi(TCCR1A, COM1A1); break; 3ba: 80 91 80 00 lds r24, 0x0080 3be: 8f 77 andi r24, 0x7F ; 127 3c0: 03 c0 rjmp .+6 ; 0x3c8 <digitalWrite+0x58> #endif #if defined(TCCR1A) && defined(COM1B1) case TIMER1B: cbi(TCCR1A, COM1B1); break; 3c2: 80 91 80 00 lds r24, 0x0080 3c6: 8f 7d andi r24, 0xDF ; 223 3c8: 80 93 80 00 sts 0x0080, r24 3cc: 10 c0 rjmp .+32 ; 0x3ee <digitalWrite+0x7e> #if defined(TCCR2) && defined(COM21) case TIMER2: cbi(TCCR2, COM21); break; #endif #if defined(TCCR0A) && defined(COM0A1) case TIMER0A: cbi(TCCR0A, COM0A1); break; 3ce: 84 b5 in r24, 0x24 ; 36 3d0: 8f 77 andi r24, 0x7F ; 127 3d2: 02 c0 rjmp .+4 ; 0x3d8 <digitalWrite+0x68> #endif #if defined(TIMER0B) && defined(COM0B1) case TIMER0B: cbi(TCCR0A, COM0B1); break; 3d4: 84 b5 in r24, 0x24 ; 36 3d6: 8f 7d andi r24, 0xDF ; 223 3d8: 84 bd out 0x24, r24 ; 36 3da: 09 c0 rjmp .+18 ; 0x3ee <digitalWrite+0x7e> #endif #if defined(TCCR2A) && defined(COM2A1) case TIMER2A: cbi(TCCR2A, COM2A1); break; 3dc: 80 91 b0 00 lds r24, 0x00B0 3e0: 8f 77 andi r24, 0x7F ; 127 3e2: 03 c0 rjmp .+6 ; 0x3ea <digitalWrite+0x7a> #endif #if defined(TCCR2A) && defined(COM2B1) case TIMER2B: cbi(TCCR2A, COM2B1); break; 3e4: 80 91 b0 00 lds r24, 0x00B0 3e8: 8f 7d andi r24, 0xDF ; 223 3ea: 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); 3ee: e3 2f mov r30, r19 3f0: f0 e0 ldi r31, 0x00 ; 0 3f2: ee 0f add r30, r30 3f4: ff 1f adc r31, r31 3f6: ee 58 subi r30, 0x8E ; 142 3f8: ff 4f sbci r31, 0xFF ; 255 3fa: a5 91 lpm r26, Z+ 3fc: b4 91 lpm r27, Z+ uint8_t oldSREG = SREG; 3fe: 2f b7 in r18, 0x3f ; 63 cli(); 400: f8 94 cli if (val == LOW) { 402: 66 23 and r22, r22 404: 21 f4 brne .+8 ; 0x40e <digitalWrite+0x9e> *out &= ~bit; 406: 8c 91 ld r24, X 408: 90 95 com r25 40a: 89 23 and r24, r25 40c: 02 c0 rjmp .+4 ; 0x412 <digitalWrite+0xa2> } else { *out |= bit; 40e: 8c 91 ld r24, X 410: 89 2b or r24, r25 412: 8c 93 st X, r24 } SREG = oldSREG; 414: 2f bf out 0x3f, r18 ; 63 416: 08 95 ret 00000418 <main>: #include <Arduino.h> int main(void) 418: cf 93 push r28 41a: df 93 push r29 { init(); 41c: 0e 94 3e 01 call 0x27c ; 0x27c <init> #if defined(USBCON) USBDevice.attach(); #endif setup(); 420: 0e 94 97 00 call 0x12e ; 0x12e <setup> for (;;) { loop(); if (serialEventRun) serialEventRun(); 424: c0 e0 ldi r28, 0x00 ; 0 426: d0 e0 ldi r29, 0x00 ; 0 #endif setup(); for (;;) { loop(); 428: 0e 94 80 00 call 0x100 ; 0x100 <loop> if (serialEventRun) serialEventRun(); 42c: 20 97 sbiw r28, 0x00 ; 0 42e: e1 f3 breq .-8 ; 0x428 <main+0x10> 430: 0e 94 00 00 call 0 ; 0x0 <__vectors> 434: f9 cf rjmp .-14 ; 0x428 <main+0x10> 00000436 <_exit>: 436: f8 94 cli 00000438 <__stop_program>: 438: ff cf rjmp .-2 ; 0x438 <__stop_program