TechBitar
  • About
  • Projects
    • LuxBlaster
    • SensoDuino
    • ArduDroid: Simple Bluetooth control for Arduino and Android
    • TV Volume Loudness Guard
    • Geo Data Logger
    • Face Tracking with Arduino and OpenCV
    • Kinect Controls Servos Using Human Motion
    • Fast Line-following Robot
    • BridgeDuino
    • Universal IR Remote Control Station for Android
    • Bluetooth-controlled Pan-Tilt Servo
    • Modify The HC-05 Bluetooth Module Defaults Using AT Commands
    • Bluetooth Comm for Arduino and PC
    • GOduino: The Breadboard-friendly Robot Controller
    • How to Network Many Arduinos with Sensors using I2C
    • Your Android Phone Is A Sensors & Comm Nervana
  • Blog

The Assembly Code for Arduino's Blink Example

4/17/2014

 
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
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

    Author

    I enjoy electronics prototyping, cinema, and technology in general. 

    Archives

    April 2014
    March 2014
    November 2013

    Categories

    All
    Android
    Arduino
    Automobile
    Car
    Design
    Green
    Modular
    Safety
    Smartphone

    RSS Feed

Powered by Create your own unique website with customizable templates.