Arduino Assembly Language Listing of Compiled Sketch (Windows)

[updated on 1.10.22 for the 1.8.15 IDE version]

We will use the very basic blink sketch as an example:

void setup() {
  pinMode(13, OUTPUT);
}

void loop() {
  digitalWrite(13, HIGH);   // set the LED on
  delay(1000);              // wait for a second
  digitalWrite(13, LOW);    // set the LED off
  delay(1000);              // wait for a second
}

Use the following steps:

1. Compile the sketch inside the arduino IDE.
2. Go to your command prompt and navigate to the temporary compile folder. Mine was located here:

C:\Users\user\Documents\Arduino\Build

Note: Substitute your Windows Login ID for “Jim” in the above example, and the numbers after “build” will vary with each instance of compilation. Look for a folder that begins with “Build” which was created most recently inside of the “\Users\_your_id_here_\Documents\Arduino\” folder.

3. Enter the following command:

avr-objdump -S Blink.cpp.elf > list.txt

Note: “Blink.cpp.elf” is the name of your sketch with “.cpp.elf” appended to it, and “list.txt” is the name you choose for the file that will contain the assembly listing.

Note: avr-objdump.exe is located in the “\arduino-00xx\hardware\tools\avr\bin” folder and this folder must be in your PATH environment variable for this method to work.

9/3/2015 Note: Somewhere along the line of Adruino IDE updates, the temporary file folder structure has changed. While using IDE version 1.6.5, I noticed this new location for the output after compiling the example “blink” program:

C:\Users\James\AppData\Local\Temp\build4685747181797715506.tmp\sketch\Blink.cpp.elf

Here is the new temporary directory structure:
directory structure

Note the file contents of each of these folders.
The “sketch” folder:

09/02/2015 08:12 AM 987 Blink.cpp
09/02/2015 08:12 AM 1,152 Blink.cpp.d
09/02/2015 08:13 AM 13 Blink.cpp.eep
09/02/2015 08:13 AM 15,539 Blink.cpp.elf
09/02/2015 08:13 AM 2,918 Blink.cpp.hex
09/02/2015 08:12 AM 4,176 Blink.cpp.o
09/02/2015 08:13 AM 4,272 Blink.cpp.with_bootloader.hex

The “core” folder:

09/02/2015 08:12 AM 166 abi.cpp.d
09/02/2015 08:12 AM 2,996 abi.cpp.o
09/02/2015 08:12 AM 1,062 CDC.cpp.d
09/02/2015 08:12 AM 2,492 CDC.cpp.o
09/02/2015 08:13 AM 397,254 core.a
09/02/2015 08:12 AM 1,282 HardwareSerial.cpp.d
09/02/2015 08:12 AM 28,104 HardwareSerial.cpp.o
09/02/2015 08:12 AM 1,284 HardwareSerial0.cpp.d
09/02/2015 08:12 AM 21,136 HardwareSerial0.cpp.o
09/02/2015 08:12 AM 1,284 HardwareSerial1.cpp.d
09/02/2015 08:12 AM 2,516 HardwareSerial1.cpp.o
09/02/2015 08:12 AM 1,284 HardwareSerial2.cpp.d
09/02/2015 08:12 AM 2,516 HardwareSerial2.cpp.o
09/02/2015 08:12 AM 1,284 HardwareSerial3.cpp.d
09/02/2015 08:12 AM 2,516 HardwareSerial3.cpp.o
09/02/2015 08:12 AM 166 hooks.c.d
09/02/2015 08:12 AM 2,168 hooks.c.o
09/02/2015 08:12 AM 1,342 IPAddress.cpp.d
09/02/2015 08:12 AM 14,324 IPAddress.cpp.o
09/02/2015 08:12 AM 1,152 main.cpp.d
09/02/2015 08:12 AM 4,844 main.cpp.o
09/02/2015 08:12 AM 166 new.cpp.d
09/02/2015 08:12 AM 4,744 new.cpp.o
09/02/2015 08:12 AM 1,173 PluggableUSB.cpp.d
09/02/2015 08:12 AM 2,512 PluggableUSB.cpp.o
09/02/2015 08:12 AM 1,066 Print.cpp.d
09/02/2015 08:12 AM 56,260 Print.cpp.o
09/02/2015 08:12 AM 1,068 Stream.cpp.d
09/02/2015 08:12 AM 43,148 Stream.cpp.o
09/02/2015 08:12 AM 1,064 Tone.cpp.d
09/02/2015 08:12 AM 19,764 Tone.cpp.o
09/02/2015 08:12 AM 1,163 USBCore.cpp.d
09/02/2015 08:12 AM 2,500 USBCore.cpp.o
09/02/2015 08:12 AM 545 WInterrupts.c.d
09/02/2015 08:12 AM 6,768 WInterrupts.c.o
09/02/2015 08:12 AM 535 wiring.c.d
09/02/2015 08:12 AM 8,400 wiring.c.o
09/02/2015 08:12 AM 549 wiring_analog.c.d
09/02/2015 08:12 AM 6,356 wiring_analog.c.o
09/02/2015 08:12 AM 551 wiring_digital.c.d
09/02/2015 08:12 AM 13,172 wiring_digital.c.o
09/02/2015 08:12 AM 547 wiring_pulse.c.d
09/02/2015 08:12 AM 10,108 wiring_pulse.c.o
09/02/2015 08:12 AM 1,688 wiring_pulse.S.o
09/02/2015 08:12 AM 547 wiring_shift.c.d
09/02/2015 08:12 AM 6,948 wiring_shift.c.o
09/02/2015 08:12 AM 170 WMath.cpp.d
09/02/2015 08:12 AM 8,292 WMath.cpp.o
09/02/2015 08:13 AM 262 WString.cpp.d
09/02/2015 08:13 AM 115,472 WString.cpp.o

Screen Print

Here is the resulting assembly listing:

blink.cpp.elf:     file format elf32-avr

Disassembly of section .text:

00000000 <__vectors>:
	timer0_millis = m;
	timer0_overflow_count++;
}

unsigned long millis()
{
   0:	60 c0       	rjmp	.+192    	; 0xc2 <__ctors_end>
		SREG = oldSREG;
	}
}

int digitalRead(uint8_t pin)
{
   2:	00 00       	nop
   4:	79 c0       	rjmp	.+242    	; 0xf8 <__bad_interrupt>
   6:	00 00       	nop
   8:	77 c0       	rjmp	.+238    	; 0xf8 <__bad_interrupt>
   a:	00 00       	nop
   c:	75 c0       	rjmp	.+234    	; 0xf8 <__bad_interrupt>
   e:	00 00       	nop
  10:	73 c0       	rjmp	.+230    	; 0xf8 <__bad_interrupt>
  12:	00 00       	nop
  14:	71 c0       	rjmp	.+226    	; 0xf8 <__bad_interrupt>
  16:	00 00       	nop
  18:	6f c0       	rjmp	.+222    	; 0xf8 <__bad_interrupt>
  1a:	00 00       	nop
  1c:	6d c0       	rjmp	.+218    	; 0xf8 <__bad_interrupt>
  1e:	00 00       	nop
  20:	6b c0       	rjmp	.+214    	; 0xf8 <__bad_interrupt>
  22:	00 00       	nop
  24:	69 c0       	rjmp	.+210    	; 0xf8 <__bad_interrupt>
  26:	00 00       	nop
  28:	67 c0       	rjmp	.+206    	; 0xf8 <__bad_interrupt>
  2a:	00 00       	nop
  2c:	65 c0       	rjmp	.+202    	; 0xf8 <__bad_interrupt>
  2e:	00 00       	nop
  30:	63 c0       	rjmp	.+198    	; 0xf8 <__bad_interrupt>
  32:	00 00       	nop
  34:	61 c0       	rjmp	.+194    	; 0xf8 <__bad_interrupt>
  36:	00 00       	nop
  38:	5f c0       	rjmp	.+190    	; 0xf8 <__bad_interrupt>
  3a:	00 00       	nop
  3c:	5d c0       	rjmp	.+186    	; 0xf8 <__bad_interrupt>
  3e:	00 00       	nop
  40:	6f c0       	rjmp	.+222    	; 0x120 <__vector_16>
  42:	00 00       	nop
  44:	59 c0       	rjmp	.+178    	; 0xf8 <__bad_interrupt>
  46:	00 00       	nop
  48:	57 c0       	rjmp	.+174    	; 0xf8 <__bad_interrupt>
  4a:	00 00       	nop
  4c:	55 c0       	rjmp	.+170    	; 0xf8 <__bad_interrupt>
  4e:	00 00       	nop
  50:	53 c0       	rjmp	.+166    	; 0xf8 <__bad_interrupt>
  52:	00 00       	nop
  54:	51 c0       	rjmp	.+162    	; 0xf8 <__bad_interrupt>
  56:	00 00       	nop
  58:	4f c0       	rjmp	.+158    	; 0xf8 <__bad_interrupt>
  5a:	00 00       	nop
  5c:	4d c0       	rjmp	.+154    	; 0xf8 <__bad_interrupt>
  5e:	00 00       	nop
  60:	4b c0       	rjmp	.+150    	; 0xf8 <__bad_interrupt>
  62:	00 00       	nop
  64:	49 c0       	rjmp	.+146    	; 0xf8 <__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:	e0 ee       	ldi	r30, 0xE0	; 224
  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:	a0 30       	cpi	r26, 0x00	; 0
  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:	a0 e0       	ldi	r26, 0x00	; 0
  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:	a9 30       	cpi	r26, 0x09	; 9
  f0:	b1 07       	cpc	r27, r17
  f2:	e1 f7       	brne	.-8      	; 0xec <.do_clear_bss_loop>
  f4:	6f d1       	rcall	.+734    	; 0x3d4 <main>
  f6:	72 c1       	rjmp	.+740    	; 0x3dc <_exit>

000000f8 <__bad_interrupt>:
  f8:	83 cf       	rjmp	.-250    	; 0x0 <__vectors>

000000fa <loop>:
  pinMode(13, OUTPUT);
}

void loop() {
  digitalWrite(13, HIGH);   // set the LED on
  fa:	8d e0       	ldi	r24, 0x0D	; 13
  fc:	61 e0       	ldi	r22, 0x01	; 1
  fe:	12 d1       	rcall	.+548    	; 0x324 <digitalWrite>
  delay(1000);              // wait for a second
 100:	68 ee       	ldi	r22, 0xE8	; 232
 102:	73 e0       	ldi	r23, 0x03	; 3
 104:	80 e0       	ldi	r24, 0x00	; 0
 106:	90 e0       	ldi	r25, 0x00	; 0
 108:	53 d0       	rcall	.+166    	; 0x1b0 <delay>
  digitalWrite(13, LOW);    // set the LED off
 10a:	8d e0       	ldi	r24, 0x0D	; 13
 10c:	60 e0       	ldi	r22, 0x00	; 0
 10e:	0a d1       	rcall	.+532    	; 0x324 <digitalWrite>
  delay(1000);              // wait for a second
 110:	68 ee       	ldi	r22, 0xE8	; 232
 112:	73 e0       	ldi	r23, 0x03	; 3
 114:	80 e0       	ldi	r24, 0x00	; 0
 116:	90 e0       	ldi	r25, 0x00	; 0
}
 118:	4b c0       	rjmp	.+150    	; 0x1b0 <delay>

0000011a <setup>:
void setup() {
  pinMode(13, OUTPUT);
 11a:	8d e0       	ldi	r24, 0x0D	; 13
 11c:	61 e0       	ldi	r22, 0x01	; 1
}
 11e:	dc c0       	rjmp	.+440    	; 0x2d8 <pinMode>

00000120 <__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)
{
 120:	1f 92       	push	r1
 122:	0f 92       	push	r0
 124:	0f b6       	in	r0, 0x3f	; 63
 126:	0f 92       	push	r0
 128:	11 24       	eor	r1, r1
 12a:	2f 93       	push	r18
 12c:	3f 93       	push	r19
 12e:	8f 93       	push	r24
 130:	9f 93       	push	r25
 132:	af 93       	push	r26
 134:	bf 93       	push	r27
	unsigned long m = timer0_millis;
 136:	80 91 04 01 	lds	r24, 0x0104
 13a:	90 91 05 01 	lds	r25, 0x0105
 13e:	a0 91 06 01 	lds	r26, 0x0106
 142:	b0 91 07 01 	lds	r27, 0x0107
	unsigned char f = timer0_fract;
 146:	30 91 08 01 	lds	r19, 0x0108

	m += MILLIS_INC;
 14a:	01 96       	adiw	r24, 0x01	; 1
 14c:	a1 1d       	adc	r26, r1
 14e:	b1 1d       	adc	r27, r1
	f += FRACT_INC;
 150:	23 2f       	mov	r18, r19
 152:	2d 5f       	subi	r18, 0xFD	; 253
	if (f >= FRACT_MAX) {
 154:	2d 37       	cpi	r18, 0x7D	; 125
 156:	20 f0       	brcs	.+8      	; 0x160 <__vector_16+0x40>
		f -= FRACT_MAX;
 158:	2d 57       	subi	r18, 0x7D	; 125
		m += 1;
 15a:	01 96       	adiw	r24, 0x01	; 1
 15c:	a1 1d       	adc	r26, r1
 15e:	b1 1d       	adc	r27, r1
	}

	timer0_fract = f;
 160:	20 93 08 01 	sts	0x0108, r18
	timer0_millis = m;
 164:	80 93 04 01 	sts	0x0104, r24
 168:	90 93 05 01 	sts	0x0105, r25
 16c:	a0 93 06 01 	sts	0x0106, r26
 170:	b0 93 07 01 	sts	0x0107, r27
	timer0_overflow_count++;
 174:	80 91 00 01 	lds	r24, 0x0100
 178:	90 91 01 01 	lds	r25, 0x0101
 17c:	a0 91 02 01 	lds	r26, 0x0102
 180:	b0 91 03 01 	lds	r27, 0x0103
 184:	01 96       	adiw	r24, 0x01	; 1
 186:	a1 1d       	adc	r26, r1
 188:	b1 1d       	adc	r27, r1
 18a:	80 93 00 01 	sts	0x0100, r24
 18e:	90 93 01 01 	sts	0x0101, r25
 192:	a0 93 02 01 	sts	0x0102, r26
 196:	b0 93 03 01 	sts	0x0103, r27
}
 19a:	bf 91       	pop	r27
 19c:	af 91       	pop	r26
 19e:	9f 91       	pop	r25
 1a0:	8f 91       	pop	r24
 1a2:	3f 91       	pop	r19
 1a4:	2f 91       	pop	r18
 1a6:	0f 90       	pop	r0
 1a8:	0f be       	out	0x3f, r0	; 63
 1aa:	0f 90       	pop	r0
 1ac:	1f 90       	pop	r1
 1ae:	18 95       	reti

000001b0 <delay>:

	return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond());
}

void delay(unsigned long ms)
{
 1b0:	9b 01       	movw	r18, r22
 1b2:	ac 01       	movw	r20, r24
	return m;
}

unsigned long micros() {
	unsigned long m;
	uint8_t oldSREG = SREG, t;
 1b4:	7f b7       	in	r23, 0x3f	; 63

	cli();
 1b6:	f8 94       	cli
	m = timer0_overflow_count;
 1b8:	80 91 00 01 	lds	r24, 0x0100
 1bc:	90 91 01 01 	lds	r25, 0x0101
 1c0:	a0 91 02 01 	lds	r26, 0x0102
 1c4:	b0 91 03 01 	lds	r27, 0x0103
#if defined(TCNT0)
	t = TCNT0;
 1c8:	66 b5       	in	r22, 0x26	; 38
	#error TIMER 0 not defined
#endif

#ifdef TIFR0
	if ((TIFR0 & _BV(TOV0)) && (t < 255))
 1ca:	a8 9b       	sbis	0x15, 0	; 21
 1cc:	05 c0       	rjmp	.+10     	; 0x1d8 <delay+0x28>
 1ce:	6f 3f       	cpi	r22, 0xFF	; 255
 1d0:	19 f0       	breq	.+6      	; 0x1d8 <delay+0x28>
		m++;
 1d2:	01 96       	adiw	r24, 0x01	; 1
 1d4:	a1 1d       	adc	r26, r1
 1d6:	b1 1d       	adc	r27, r1
#else
	if ((TIFR & _BV(TOV0)) && (t < 255))
		m++;
#endif

	SREG = oldSREG;
 1d8:	7f bf       	out	0x3f, r23	; 63
	return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond());
}

void delay(unsigned long ms)
{
	uint16_t start = (uint16_t)micros();
 1da:	ba 2f       	mov	r27, r26
 1dc:	a9 2f       	mov	r26, r25
 1de:	98 2f       	mov	r25, r24
 1e0:	88 27       	eor	r24, r24
 1e2:	86 0f       	add	r24, r22
 1e4:	91 1d       	adc	r25, r1
 1e6:	a1 1d       	adc	r26, r1
 1e8:	b1 1d       	adc	r27, r1
 1ea:	62 e0       	ldi	r22, 0x02	; 2
 1ec:	88 0f       	add	r24, r24
 1ee:	99 1f       	adc	r25, r25
 1f0:	aa 1f       	adc	r26, r26
 1f2:	bb 1f       	adc	r27, r27
 1f4:	6a 95       	dec	r22
 1f6:	d1 f7       	brne	.-12     	; 0x1ec <delay+0x3c>
 1f8:	bc 01       	movw	r22, r24
 1fa:	2d c0       	rjmp	.+90     	; 0x256 <delay+0xa6>
	return m;
}

unsigned long micros() {
	unsigned long m;
	uint8_t oldSREG = SREG, t;
 1fc:	ff b7       	in	r31, 0x3f	; 63

	cli();
 1fe:	f8 94       	cli
	m = timer0_overflow_count;
 200:	80 91 00 01 	lds	r24, 0x0100
 204:	90 91 01 01 	lds	r25, 0x0101
 208:	a0 91 02 01 	lds	r26, 0x0102
 20c:	b0 91 03 01 	lds	r27, 0x0103
#if defined(TCNT0)
	t = TCNT0;
 210:	e6 b5       	in	r30, 0x26	; 38
	#error TIMER 0 not defined
#endif

#ifdef TIFR0
	if ((TIFR0 & _BV(TOV0)) && (t < 255))
 212:	a8 9b       	sbis	0x15, 0	; 21
 214:	05 c0       	rjmp	.+10     	; 0x220 <delay+0x70>
 216:	ef 3f       	cpi	r30, 0xFF	; 255
 218:	19 f0       	breq	.+6      	; 0x220 <delay+0x70>
		m++;
 21a:	01 96       	adiw	r24, 0x01	; 1
 21c:	a1 1d       	adc	r26, r1
 21e:	b1 1d       	adc	r27, r1
#else
	if ((TIFR & _BV(TOV0)) && (t < 255))
		m++;
#endif

	SREG = oldSREG;
 220:	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) {
 222:	ba 2f       	mov	r27, r26
 224:	a9 2f       	mov	r26, r25
 226:	98 2f       	mov	r25, r24
 228:	88 27       	eor	r24, r24
 22a:	8e 0f       	add	r24, r30
 22c:	91 1d       	adc	r25, r1
 22e:	a1 1d       	adc	r26, r1
 230:	b1 1d       	adc	r27, r1
 232:	e2 e0       	ldi	r30, 0x02	; 2
 234:	88 0f       	add	r24, r24
 236:	99 1f       	adc	r25, r25
 238:	aa 1f       	adc	r26, r26
 23a:	bb 1f       	adc	r27, r27
 23c:	ea 95       	dec	r30
 23e:	d1 f7       	brne	.-12     	; 0x234 <delay+0x84>
 240:	86 1b       	sub	r24, r22
 242:	97 0b       	sbc	r25, r23
 244:	88 5e       	subi	r24, 0xE8	; 232
 246:	93 40       	sbci	r25, 0x03	; 3
 248:	c8 f2       	brcs	.-78     	; 0x1fc <delay+0x4c>
			ms--;
 24a:	21 50       	subi	r18, 0x01	; 1
 24c:	30 40       	sbci	r19, 0x00	; 0
 24e:	40 40       	sbci	r20, 0x00	; 0
 250:	50 40       	sbci	r21, 0x00	; 0
			start += 1000;
 252:	68 51       	subi	r22, 0x18	; 24
 254:	7c 4f       	sbci	r23, 0xFC	; 252

void delay(unsigned long ms)
{
	uint16_t start = (uint16_t)micros();

	while (ms > 0) {
 256:	21 15       	cp	r18, r1
 258:	31 05       	cpc	r19, r1
 25a:	41 05       	cpc	r20, r1
 25c:	51 05       	cpc	r21, r1
 25e:	71 f6       	brne	.-100    	; 0x1fc <delay+0x4c>
		if (((uint16_t)micros() - start) >= 1000) {
			ms--;
			start += 1000;
		}
	}
}
 260:	08 95       	ret

00000262 <init>:

void init()
{
	// this needs to be called before setup() or some functions won't
	// work there
	sei();
 262:	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);
 264:	84 b5       	in	r24, 0x24	; 36
 266:	82 60       	ori	r24, 0x02	; 2
 268:	84 bd       	out	0x24, r24	; 36
	sbi(TCCR0A, WGM00);
 26a:	84 b5       	in	r24, 0x24	; 36
 26c:	81 60       	ori	r24, 0x01	; 1
 26e:	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);
 270:	85 b5       	in	r24, 0x25	; 37
 272:	82 60       	ori	r24, 0x02	; 2
 274:	85 bd       	out	0x25, r24	; 37
	sbi(TCCR0B, CS00);
 276:	85 b5       	in	r24, 0x25	; 37
 278:	81 60       	ori	r24, 0x01	; 1
 27a:	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);
 27c:	ee e6       	ldi	r30, 0x6E	; 110
 27e:	f0 e0       	ldi	r31, 0x00	; 0
 280:	80 81       	ld	r24, Z
 282:	81 60       	ori	r24, 0x01	; 1
 284:	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;
 286:	e1 e8       	ldi	r30, 0x81	; 129
 288:	f0 e0       	ldi	r31, 0x00	; 0
 28a:	10 82       	st	Z, r1

	// set timer 1 prescale factor to 64
#if defined(TCCR1B) && defined(CS11) && defined(CS10)
	sbi(TCCR1B, CS11);
 28c:	80 81       	ld	r24, Z
 28e:	82 60       	ori	r24, 0x02	; 2
 290:	80 83       	st	Z, r24
	sbi(TCCR1B, CS10);
 292:	80 81       	ld	r24, Z
 294:	81 60       	ori	r24, 0x01	; 1
 296:	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);
 298:	e0 e8       	ldi	r30, 0x80	; 128
 29a:	f0 e0       	ldi	r31, 0x00	; 0
 29c:	80 81       	ld	r24, Z
 29e:	81 60       	ori	r24, 0x01	; 1
 2a0:	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);
 2a2:	e1 eb       	ldi	r30, 0xB1	; 177
 2a4:	f0 e0       	ldi	r31, 0x00	; 0
 2a6:	80 81       	ld	r24, Z
 2a8:	84 60       	ori	r24, 0x04	; 4
 2aa:	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);
 2ac:	e0 eb       	ldi	r30, 0xB0	; 176
 2ae:	f0 e0       	ldi	r31, 0x00	; 0
 2b0:	80 81       	ld	r24, Z
 2b2:	81 60       	ori	r24, 0x01	; 1
 2b4:	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);
 2b6:	ea e7       	ldi	r30, 0x7A	; 122
 2b8:	f0 e0       	ldi	r31, 0x00	; 0
 2ba:	80 81       	ld	r24, Z
 2bc:	84 60       	ori	r24, 0x04	; 4
 2be:	80 83       	st	Z, r24
	sbi(ADCSRA, ADPS1);
 2c0:	80 81       	ld	r24, Z
 2c2:	82 60       	ori	r24, 0x02	; 2
 2c4:	80 83       	st	Z, r24
	sbi(ADCSRA, ADPS0);
 2c6:	80 81       	ld	r24, Z
 2c8:	81 60       	ori	r24, 0x01	; 1
 2ca:	80 83       	st	Z, r24

	// enable a2d conversions
	sbi(ADCSRA, ADEN);
 2cc:	80 81       	ld	r24, Z
 2ce:	80 68       	ori	r24, 0x80	; 128
 2d0:	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;
 2d2:	10 92 c1 00 	sts	0x00C1, r1
#endif
}
 2d6:	08 95       	ret

000002d8 <pinMode>:
#include "wiring_private.h"
#include "pins_arduino.h"

void pinMode(uint8_t pin, uint8_t mode)
{
	uint8_t bit = digitalPinToBitMask(pin);
 2d8:	48 2f       	mov	r20, r24
 2da:	50 e0       	ldi	r21, 0x00	; 0
 2dc:	ca 01       	movw	r24, r20
 2de:	86 56       	subi	r24, 0x66	; 102
 2e0:	9f 4f       	sbci	r25, 0xFF	; 255
 2e2:	fc 01       	movw	r30, r24
 2e4:	24 91       	lpm	r18, Z+
	uint8_t port = digitalPinToPort(pin);
 2e6:	4a 57       	subi	r20, 0x7A	; 122
 2e8:	5f 4f       	sbci	r21, 0xFF	; 255
 2ea:	fa 01       	movw	r30, r20
 2ec:	84 91       	lpm	r24, Z+
	volatile uint8_t *reg;

	if (port == NOT_A_PIN) return;
 2ee:	88 23       	and	r24, r24
 2f0:	c1 f0       	breq	.+48     	; 0x322 <pinMode+0x4a>

	// JWS: can I let the optimizer do this?
	reg = portModeRegister(port);
 2f2:	e8 2f       	mov	r30, r24
 2f4:	f0 e0       	ldi	r31, 0x00	; 0
 2f6:	ee 0f       	add	r30, r30
 2f8:	ff 1f       	adc	r31, r31
 2fa:	e8 59       	subi	r30, 0x98	; 152
 2fc:	ff 4f       	sbci	r31, 0xFF	; 255
 2fe:	a5 91       	lpm	r26, Z+
 300:	b4 91       	lpm	r27, Z+

	if (mode == INPUT) {
 302:	66 23       	and	r22, r22
 304:	41 f4       	brne	.+16     	; 0x316 <pinMode+0x3e>
		uint8_t oldSREG = SREG;
 306:	9f b7       	in	r25, 0x3f	; 63
                cli();
 308:	f8 94       	cli
		*reg &= ~bit;
 30a:	8c 91       	ld	r24, X
 30c:	20 95       	com	r18
 30e:	82 23       	and	r24, r18
 310:	8c 93       	st	X, r24
		SREG = oldSREG;
 312:	9f bf       	out	0x3f, r25	; 63
 314:	08 95       	ret
	} else {
		uint8_t oldSREG = SREG;
 316:	9f b7       	in	r25, 0x3f	; 63
                cli();
 318:	f8 94       	cli
		*reg |= bit;
 31a:	8c 91       	ld	r24, X
 31c:	82 2b       	or	r24, r18
 31e:	8c 93       	st	X, r24
		SREG = oldSREG;
 320:	9f bf       	out	0x3f, r25	; 63
 322:	08 95       	ret

00000324 <digitalWrite>:
	}
}

void digitalWrite(uint8_t pin, uint8_t val)
{
	uint8_t timer = digitalPinToTimer(pin);
 324:	48 2f       	mov	r20, r24
 326:	50 e0       	ldi	r21, 0x00	; 0
 328:	ca 01       	movw	r24, r20
 32a:	82 55       	subi	r24, 0x52	; 82
 32c:	9f 4f       	sbci	r25, 0xFF	; 255
 32e:	fc 01       	movw	r30, r24
 330:	24 91       	lpm	r18, Z+
	uint8_t bit = digitalPinToBitMask(pin);
 332:	ca 01       	movw	r24, r20
 334:	86 56       	subi	r24, 0x66	; 102
 336:	9f 4f       	sbci	r25, 0xFF	; 255
 338:	fc 01       	movw	r30, r24
 33a:	34 91       	lpm	r19, Z+
	uint8_t port = digitalPinToPort(pin);
 33c:	4a 57       	subi	r20, 0x7A	; 122
 33e:	5f 4f       	sbci	r21, 0xFF	; 255
 340:	fa 01       	movw	r30, r20
 342:	94 91       	lpm	r25, Z+
	volatile uint8_t *out;

	if (port == NOT_A_PIN) return;
 344:	99 23       	and	r25, r25
 346:	09 f4       	brne	.+2      	; 0x34a <digitalWrite+0x26>
 348:	44 c0       	rjmp	.+136    	; 0x3d2 <digitalWrite+0xae>

	// 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);
 34a:	22 23       	and	r18, r18
 34c:	51 f1       	breq	.+84     	; 0x3a2 <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)
 34e:	23 30       	cpi	r18, 0x03	; 3
 350:	71 f0       	breq	.+28     	; 0x36e <digitalWrite+0x4a>
 352:	24 30       	cpi	r18, 0x04	; 4
 354:	28 f4       	brcc	.+10     	; 0x360 <digitalWrite+0x3c>
 356:	21 30       	cpi	r18, 0x01	; 1
 358:	a1 f0       	breq	.+40     	; 0x382 <digitalWrite+0x5e>
 35a:	22 30       	cpi	r18, 0x02	; 2
 35c:	11 f5       	brne	.+68     	; 0x3a2 <digitalWrite+0x7e>
 35e:	14 c0       	rjmp	.+40     	; 0x388 <digitalWrite+0x64>
 360:	26 30       	cpi	r18, 0x06	; 6
 362:	b1 f0       	breq	.+44     	; 0x390 <digitalWrite+0x6c>
 364:	27 30       	cpi	r18, 0x07	; 7
 366:	c1 f0       	breq	.+48     	; 0x398 <digitalWrite+0x74>
 368:	24 30       	cpi	r18, 0x04	; 4
 36a:	d9 f4       	brne	.+54     	; 0x3a2 <digitalWrite+0x7e>
 36c:	04 c0       	rjmp	.+8      	; 0x376 <digitalWrite+0x52>
	{
		#if defined(TCCR1A) && defined(COM1A1)
		case TIMER1A:   cbi(TCCR1A, COM1A1);    break;
 36e:	80 91 80 00 	lds	r24, 0x0080
 372:	8f 77       	andi	r24, 0x7F	; 127
 374:	03 c0       	rjmp	.+6      	; 0x37c <digitalWrite+0x58>
		#endif
		#if defined(TCCR1A) && defined(COM1B1)
		case TIMER1B:   cbi(TCCR1A, COM1B1);    break;
 376:	80 91 80 00 	lds	r24, 0x0080
 37a:	8f 7d       	andi	r24, 0xDF	; 223
 37c:	80 93 80 00 	sts	0x0080, r24
 380:	10 c0       	rjmp	.+32     	; 0x3a2 <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;
 382:	84 b5       	in	r24, 0x24	; 36
 384:	8f 77       	andi	r24, 0x7F	; 127
 386:	02 c0       	rjmp	.+4      	; 0x38c <digitalWrite+0x68>
		#endif

		#if defined(TIMER0B) && defined(COM0B1)
		case  TIMER0B:  cbi(TCCR0A, COM0B1);    break;
 388:	84 b5       	in	r24, 0x24	; 36
 38a:	8f 7d       	andi	r24, 0xDF	; 223
 38c:	84 bd       	out	0x24, r24	; 36
 38e:	09 c0       	rjmp	.+18     	; 0x3a2 <digitalWrite+0x7e>
		#endif
		#if defined(TCCR2A) && defined(COM2A1)
		case  TIMER2A:  cbi(TCCR2A, COM2A1);    break;
 390:	80 91 b0 00 	lds	r24, 0x00B0
 394:	8f 77       	andi	r24, 0x7F	; 127
 396:	03 c0       	rjmp	.+6      	; 0x39e <digitalWrite+0x7a>
		#endif
		#if defined(TCCR2A) && defined(COM2B1)
		case  TIMER2B:  cbi(TCCR2A, COM2B1);    break;
 398:	80 91 b0 00 	lds	r24, 0x00B0
 39c:	8f 7d       	andi	r24, 0xDF	; 223
 39e:	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);
 3a2:	e9 2f       	mov	r30, r25
 3a4:	f0 e0       	ldi	r31, 0x00	; 0
 3a6:	ee 0f       	add	r30, r30
 3a8:	ff 1f       	adc	r31, r31
 3aa:	ee 58       	subi	r30, 0x8E	; 142
 3ac:	ff 4f       	sbci	r31, 0xFF	; 255
 3ae:	a5 91       	lpm	r26, Z+
 3b0:	b4 91       	lpm	r27, Z+

	if (val == LOW) {
 3b2:	66 23       	and	r22, r22
 3b4:	41 f4       	brne	.+16     	; 0x3c6 <digitalWrite+0xa2>
		uint8_t oldSREG = SREG;
 3b6:	9f b7       	in	r25, 0x3f	; 63
                cli();
 3b8:	f8 94       	cli
		*out &= ~bit;
 3ba:	8c 91       	ld	r24, X
 3bc:	30 95       	com	r19
 3be:	83 23       	and	r24, r19
 3c0:	8c 93       	st	X, r24
		SREG = oldSREG;
 3c2:	9f bf       	out	0x3f, r25	; 63
 3c4:	08 95       	ret
	} else {
		uint8_t oldSREG = SREG;
 3c6:	9f b7       	in	r25, 0x3f	; 63
                cli();
 3c8:	f8 94       	cli
		*out |= bit;
 3ca:	8c 91       	ld	r24, X
 3cc:	83 2b       	or	r24, r19
 3ce:	8c 93       	st	X, r24
		SREG = oldSREG;
 3d0:	9f bf       	out	0x3f, r25	; 63
 3d2:	08 95       	ret

000003d4 <main>:
#include <WProgram.h>

int main(void)
{
	init();
 3d4:	46 df       	rcall	.-372    	; 0x262 <init>

	setup();
 3d6:	a1 de       	rcall	.-702    	; 0x11a <setup>

	for (;;)
		loop();
 3d8:	90 de       	rcall	.-736    	; 0xfa <loop>
 3da:	fe cf       	rjmp	.-4      	; 0x3d8 <main+0x4>

000003dc <_exit>:
 3dc:	f8 94       	cli

000003de <__stop_program>:
 3de:	ff cf       	rjmp	.-2      	; 0x3de <__stop_program>

Avr-objdump.exe options:


Usage: avr-objdump
Display information from object .
At least one of the following switches must be given:
-a, --archive-headers Display archive header information
-f, --file-headers Display the contents of the overall file header
-p, --private-headers Display object format specific file header contents
-h, --[section-]headers Display the contents of the section headers
-x, --all-headers Display the contents of all headers
-d, --disassemble Display assembler contents of executable sections
-D, --disassemble-all Display assembler contents of all sections
-S, --source Intermix source code with disassembly
-s, --full-contents Display the full contents of all sections requested
-g, --debugging Display debug information in object file
-e, --debugging-tags Display debug information using ctags style
-G, --stabs Display (in raw form) any STABS info in the file
-W, --dwarf Display DWARF info in the file
-t, --syms Display the contents of the symbol table(s)
-T, --dynamic-syms Display the contents of the dynamic symbol table
-r, --reloc Display the relocation entries in the file
-R, --dynamic-reloc Display the dynamic relocation entries in the file
@ Read options from
-v, --version Display this program's version number
-i, --info List object formats and architectures supported
-H, --help Display this information

About Jim Eli

µC experimenter
This entry was posted in Uncategorized and tagged , , , , , . Bookmark the permalink.

5 Responses to Arduino Assembly Language Listing of Compiled Sketch (Windows)

  1. carlos feldman says:

    In versions up to .24 you may get this listings just by clicjing shift before the compile button. Sadly seems not to be working in version 1

  2. Julian.Waran says:

    Good technique, still works with Arduino IDE version1.8.7

  3. Hi,
    i wonder something inside this disassembly file. Where is the stack pointer initialize?

    • Jim Eli says:

      Register 0x3e and 0x3d are the SPH and SPL respectfully. So right here:

      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

      • embedded4ever says:

        Thanks for quick reply!

        I read in some forums that the software reset is unsafe. The stack pointer could start from the wrong place, but now the stack pointer sets itself to the relevant address at the beginning without leaving it to us. Is it true?

Leave a comment