Analyzing Compiler Generated Machine Code

A Dr. Taylor Tutorial

On this page we will explore the process of generating machine code from one or more .c files.

Trivial C Program

The following C program, wk1.c, does nothing:

int main()
{
}

Even so, it produces the following .lss file:

wk1.elf:     file format elf32-avr

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         000000a2  00000000  00000000  00000054  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .stab         00000378  00000000  00000000  000000f8  2**2
                  CONTENTS, READONLY, DEBUGGING
  2 .stabstr      0000005f  00000000  00000000  00000470  2**0
                  CONTENTS, READONLY, DEBUGGING
  3 .debug_aranges 00000020  00000000  00000000  000004cf  2**0
                  CONTENTS, READONLY, DEBUGGING
  4 .debug_pubnames 0000001b  00000000  00000000  000004ef  2**0
                  CONTENTS, READONLY, DEBUGGING
  5 .debug_info   0000008a  00000000  00000000  0000050a  2**0
                  CONTENTS, READONLY, DEBUGGING
  6 .debug_abbrev 00000034  00000000  00000000  00000594  2**0
                  CONTENTS, READONLY, DEBUGGING
  7 .debug_line   00000055  00000000  00000000  000005c8  2**0
                  CONTENTS, READONLY, DEBUGGING
  8 .debug_frame  00000020  00000000  00000000  00000620  2**2
                  CONTENTS, READONLY, DEBUGGING
Disassembly of section .text:

00000000 <__vectors>:
   0:   0c 94 2a 00     jmp     0x54    ; 0x54 <__ctors_end>
   4:   0c 94 47 00     jmp     0x8e    ; 0x8e <__bad_interrupt>
   8:   0c 94 47 00     jmp     0x8e    ; 0x8e <__bad_interrupt>
   c:   0c 94 47 00     jmp     0x8e    ; 0x8e <__bad_interrupt>
  10:   0c 94 47 00     jmp     0x8e    ; 0x8e <__bad_interrupt>
  14:   0c 94 47 00     jmp     0x8e    ; 0x8e <__bad_interrupt>
  18:   0c 94 47 00     jmp     0x8e    ; 0x8e <__bad_interrupt>
  1c:   0c 94 47 00     jmp     0x8e    ; 0x8e <__bad_interrupt>
  20:   0c 94 47 00     jmp     0x8e    ; 0x8e <__bad_interrupt>
  24:   0c 94 47 00     jmp     0x8e    ; 0x8e <__bad_interrupt>
  28:   0c 94 47 00     jmp     0x8e    ; 0x8e <__bad_interrupt>
  2c:   0c 94 47 00     jmp     0x8e    ; 0x8e <__bad_interrupt>
  30:   0c 94 47 00     jmp     0x8e    ; 0x8e <__bad_interrupt>
  34:   0c 94 47 00     jmp     0x8e    ; 0x8e <__bad_interrupt>
  38:   0c 94 47 00     jmp     0x8e    ; 0x8e <__bad_interrupt>
  3c:   0c 94 47 00     jmp     0x8e    ; 0x8e <__bad_interrupt>
  40:   0c 94 47 00     jmp     0x8e    ; 0x8e <__bad_interrupt>
  44:   0c 94 47 00     jmp     0x8e    ; 0x8e <__bad_interrupt>
  48:   0c 94 47 00     jmp     0x8e    ; 0x8e <__bad_interrupt>
  4c:   0c 94 47 00     jmp     0x8e    ; 0x8e <__bad_interrupt>
  50:   0c 94 47 00     jmp     0x8e    ; 0x8e <__bad_interrupt>

00000054 <__ctors_end>:
  54:   11 24           eor     r1, r1
  56:   1f be           out     0x3f, r1        ; 63
  58:   cf e5           ldi     r28, 0x5F       ; 95
  5a:   d8 e0           ldi     r29, 0x08       ; 8
  5c:   de bf           out     0x3e, r29       ; 62
  5e:   cd bf           out     0x3d, r28       ; 61

00000060 <__do_copy_data>:
  60:   10 e0           ldi     r17, 0x00       ; 0
  62:   a0 e6           ldi     r26, 0x60       ; 96
  64:   b0 e0           ldi     r27, 0x00       ; 0
  66:   e2 ea           ldi     r30, 0xA2       ; 162
  68:   f0 e0           ldi     r31, 0x00       ; 0
  6a:   02 c0           rjmp    .+4             ; 0x70 <.do_copy_data_start>

0000006c <.do_copy_data_loop>:
  6c:   05 90           lpm     r0, Z+
  6e:   0d 92           st      X+, r0

00000070 <.do_copy_data_start>:
  70:   a0 36           cpi     r26, 0x60       ; 96
  72:   b1 07           cpc     r27, r17
  74:   d9 f7           brne    .-10            ; 0x6c <.do_copy_data_loop>

00000076 <__do_clear_bss>:
  76:   10 e0           ldi     r17, 0x00       ; 0
  78:   a0 e6           ldi     r26, 0x60       ; 96
  7a:   b0 e0           ldi     r27, 0x00       ; 0
  7c:   01 c0           rjmp    .+2             ; 0x80 <.do_clear_bss_start>

0000007e <.do_clear_bss_loop>:
  7e:   1d 92           st      X+, r1

00000080 <.do_clear_bss_start>:
  80:   a0 36           cpi     r26, 0x60       ; 96
  82:   b1 07           cpc     r27, r17
  84:   e1 f7           brne    .-8             ; 0x7e <.do_clear_bss_loop>
  86:   0e 94 49 00     call    0x92            ; 0x92 <main>
  8a:   0c 94 50 00     jmp     0xa0            ; 0xa0 <_exit>

0000008e <__bad_interrupt>:
  8e:   0c 94 00 00     jmp     0               ; 0x0 <__vectors>

00000092 <main>:
  92:   cf 93           push    r28
  94:   df 93           push    r29
  96:   cd b7           in      r28, 0x3d       ; 61
  98:   de b7           in      r29, 0x3e       ; 62
  9a:   df 91           pop     r29
  9c:   cf 91           pop     r28
  9e:   08 95           ret

000000a0 <_exit>:
  a0:   ff cf           rjmp    .-2             ; 0xa0 <_exit>

Vectors

ctors_end

00000054 <__ctors_end>:
  54:   11 24           eor     r1, r1
  56:   1f be           out     0x3f, r1        ; 63  SREG
  58:   cf e5           ldi     r28, 0x5F       ; 95
  5a:   d8 e0           ldi     r29, 0x08       ; 8
  5c:   de bf           out     0x3e, r29       ; 62  SPH
  5e:   cd bf           out     0x3d, r28       ; 61  SPL

do_copy_data

Initializes X and Z registers for copying data from program memory into data memory.

00000060 <__do_copy_data>:
  60:   10 e0           ldi     r17, 0x00       ; 0
  62:   a0 e6           ldi     r26, 0x60       ; 96
  64:   b0 e0           ldi     r27, 0x00       ; 0
  66:   e2 ea           ldi     r30, 0xA2       ; 162
  68:   f0 e0           ldi     r31, 0x00       ; 0
  6a:   02 c0           rjmp    .+4             ; 0x70 <.do_copy_data_start>

do_clear_bss

Empty main and Beyond

00000092 <main>:
  92:   cf 93           push    r28
  94:   df 93           push    r29
  96:   cd b7           in      r28, 0x3d       ; 61
  98:   de b7           in      r29, 0x3e       ; 62
  9a:   df 91           pop     r29
  9c:   cf 91           pop     r28
  9e:   08 95           ret

000000a0 <_exit>:
  a0:   ff cf           rjmp    .-2             ; 0xa0 <_exit>

Non-Trivial C Program

#include <avr/io.h>
  
int y[4];
  
int main()
{
  char word[] = "funness";
  int x[3];
  int i = 1;
  PORTB = x[i];
  for(i=0; i<3; ++i)
  {
    x[i] = PINB;
  }
  for(i=0; i<3; ++i)
  {
    PORTB = x[3-i];
  }
  return 0;
}

Below are parts of the listing file generated with no compiler optimization.

Data Copy

00000060 <__do_copy_data>:
  60:   10 e0           ldi     r17, 0x00       ; 0
  62:   a0 e6           ldi     r26, 0x60       ; 96
  64:   b0 e0           ldi     r27, 0x00       ; 0
  66:   ee ea           ldi     r30, 0xAE       ; 174
  68:   f1 e0           ldi     r31, 0x01       ; 1
  6a:   02 c0           rjmp    .+4             ; 0x70 <.do_copy_data_start>

0000006c <.do_copy_data_loop>:
  6c:   05 90           lpm     r0, Z+
  6e:   0d 92           st      X+, r0

00000070 <.do_copy_data_start>:
  70:   a8 36           cpi     r26, 0x68       ; 104
  72:   b1 07           cpc     r27, r17
  74:   d9 f7           brne    .-10            ; 0x6c <.do_copy_data_loop>

Clearing Data Area for Uninitialized Global/Static Variables

00000076 <__do_clear_bss>:
  76:   10 e0           ldi     r17, 0x00       ; 0
  78:   a8 e6           ldi     r26, 0x68       ; 104
  7a:   b0 e0           ldi     r27, 0x00       ; 0
  7c:   01 c0           rjmp    .+2             ; 0x80 <.do_clear_bss_start>

0000007e <.do_clear_bss_loop>:
  7e:   1d 92           st      X+, r1

00000080 <.do_clear_bss_start>:
  80:   a0 37           cpi     r26, 0x72       ; 114
  82:   b1 07           cpc     r27, r17
  84:   e1 f7           brne    .-8             ; 0x7e <.do_clear_bss_loop>
  86:   0e 94 49 00     call    0x92            ; 0x92 <main>
  8a:   0c 94 d6 00     jmp     0x1ac           ; 0x1ac <_exit>

Main

The main function is much more exciting now. Here are few things to keep in mind when view this code:

00000092 <main>:
  92:   cf 93           push    r28
  94:   df 93           push    r29
  96:   cd b7           in      r28, 0x3d       ; 61
  98:   de b7           in      r29, 0x3e       ; 62
  9a:   65 97           sbiw    r28, 0x15       ; 21
  9c:   0f b6           in      r0, 0x3f        ; 63
  9e:   f8 94           cli
  a0:   de bf           out     0x3e, r29       ; 62
  a2:   0f be           out     0x3f, r0        ; 63
  a4:   cd bf           out     0x3d, r28       ; 61
  a6:   ae 01           movw    r20, r28
  a8:   4d 5f           subi    r20, 0xFD       ; 253
  aa:   5f 4f           sbci    r21, 0xFF       ; 255
  ac:   5a 8b           std     Y+18, r21       ; 0x12
  ae:   49 8b           std     Y+17, r20       ; 0x11
  b0:   80 e6           ldi     r24, 0x60       ; 96
  b2:   90 e0           ldi     r25, 0x00       ; 0
  b4:   9c 8b           std     Y+20, r25       ; 0x14
  b6:   8b 8b           std     Y+19, r24       ; 0x13
  b8:   98 e0           ldi     r25, 0x08       ; 8
  ba:   9d 8b           std     Y+21, r25       ; 0x15
  bc:   eb 89           ldd     r30, Y+19       ; 0x13
  be:   fc 89           ldd     r31, Y+20       ; 0x14
  c0:   00 80           ld      r0, Z
  c2:   4b 89           ldd     r20, Y+19       ; 0x13
  c4:   5c 89           ldd     r21, Y+20       ; 0x14
  c6:   4f 5f           subi    r20, 0xFF       ; 255
  c8:   5f 4f           sbci    r21, 0xFF       ; 255
  ca:   5c 8b           std     Y+20, r21       ; 0x14
  cc:   4b 8b           std     Y+19, r20       ; 0x13
  ce:   e9 89           ldd     r30, Y+17       ; 0x11
  d0:   fa 89           ldd     r31, Y+18       ; 0x12
  d2:   00 82           st      Z, r0
  d4:   49 89           ldd     r20, Y+17       ; 0x11
  d6:   5a 89           ldd     r21, Y+18       ; 0x12
  d8:   4f 5f           subi    r20, 0xFF       ; 255
  da:   5f 4f           sbci    r21, 0xFF       ; 255
  dc:   5a 8b           std     Y+18, r21       ; 0x12
  de:   49 8b           std     Y+17, r20       ; 0x11
  e0:   5d 89           ldd     r21, Y+21       ; 0x15
  e2:   51 50           subi    r21, 0x01       ; 1
  e4:   5d 8b           std     Y+21, r21       ; 0x15
  e6:   8d 89           ldd     r24, Y+21       ; 0x15
  e8:   88 23           and     r24, r24
  ea:   41 f7           brne    .-48            ; 0xbc <main+0x2a>
  ec:   81 e0           ldi     r24, 0x01       ; 1
  ee:   90 e0           ldi     r25, 0x00       ; 0
  f0:   9a 83           std     Y+2, r25        ; 0x02
  f2:   89 83           std     Y+1, r24        ; 0x01
  f4:   a8 e3           ldi     r26, 0x38       ; 56
  f6:   b0 e0           ldi     r27, 0x00       ; 0
  f8:   89 81           ldd     r24, Y+1        ; 0x01
  fa:   9a 81           ldd     r25, Y+2        ; 0x02
  fc:   9c 01           movw    r18, r24
  fe:   22 0f           add     r18, r18
 100:   33 1f           adc     r19, r19
 102:   ce 01           movw    r24, r28
 104:   01 96           adiw    r24, 0x01       ; 1
 106:   82 0f           add     r24, r18
 108:   93 1f           adc     r25, r19
 10a:   fc 01           movw    r30, r24
 10c:   3a 96           adiw    r30, 0x0a       ; 10
 10e:   80 81           ld      r24, Z
 110:   91 81           ldd     r25, Z+1        ; 0x01
 112:   8c 93           st      X, r24
 114:   1a 82           std     Y+2, r1         ; 0x02
 116:   19 82           std     Y+1, r1         ; 0x01
 118:   16 c0           rjmp    .+44            ; 0x146 <main+0xb4>
 11a:   29 81           ldd     r18, Y+1        ; 0x01
 11c:   3a 81           ldd     r19, Y+2        ; 0x02
 11e:   e6 e3           ldi     r30, 0x36       ; 54
 120:   f0 e0           ldi     r31, 0x00       ; 0
 122:   80 81           ld      r24, Z
 124:   48 2f           mov     r20, r24
 126:   50 e0           ldi     r21, 0x00       ; 0
 128:   22 0f           add     r18, r18
 12a:   33 1f           adc     r19, r19
 12c:   ce 01           movw    r24, r28
 12e:   01 96           adiw    r24, 0x01       ; 1
 130:   82 0f           add     r24, r18
 132:   93 1f           adc     r25, r19
 134:   fc 01           movw    r30, r24
 136:   3a 96           adiw    r30, 0x0a       ; 10
 138:   51 83           std     Z+1, r21        ; 0x01
 13a:   40 83           st      Z, r20
 13c:   89 81           ldd     r24, Y+1        ; 0x01
 13e:   9a 81           ldd     r25, Y+2        ; 0x02
 140:   01 96           adiw    r24, 0x01       ; 1
 142:   9a 83           std     Y+2, r25        ; 0x02
 144:   89 83           std     Y+1, r24        ; 0x01
 146:   89 81           ldd     r24, Y+1        ; 0x01
 148:   9a 81           ldd     r25, Y+2        ; 0x02
 14a:   83 30           cpi     r24, 0x03       ; 3
 14c:   91 05           cpc     r25, r1
 14e:   2c f3           brlt    .-54            ; 0x11a <main+0x88>
 150:   1a 82           std     Y+2, r1         ; 0x02
 152:   19 82           std     Y+1, r1         ; 0x01
 154:   1b c0           rjmp    .+54            ; 0x18c <main+0xfa>
 156:   a8 e3           ldi     r26, 0x38       ; 56
 158:   b0 e0           ldi     r27, 0x00       ; 0
 15a:   23 e0           ldi     r18, 0x03       ; 3
 15c:   30 e0           ldi     r19, 0x00       ; 0
 15e:   89 81           ldd     r24, Y+1        ; 0x01
 160:   9a 81           ldd     r25, Y+2        ; 0x02
 162:   f9 01           movw    r30, r18
 164:   e8 1b           sub     r30, r24
 166:   f9 0b           sbc     r31, r25
 168:   cf 01           movw    r24, r30
 16a:   9c 01           movw    r18, r24
 16c:   22 0f           add     r18, r18
 16e:   33 1f           adc     r19, r19
 170:   ce 01           movw    r24, r28
 172:   01 96           adiw    r24, 0x01       ; 1
 174:   82 0f           add     r24, r18
 176:   93 1f           adc     r25, r19
 178:   fc 01           movw    r30, r24
 17a:   3a 96           adiw    r30, 0x0a       ; 10
 17c:   80 81           ld      r24, Z
 17e:   91 81           ldd     r25, Z+1        ; 0x01
 180:   8c 93           st      X, r24
 182:   89 81           ldd     r24, Y+1        ; 0x01
 184:   9a 81           ldd     r25, Y+2        ; 0x02
 186:   01 96           adiw    r24, 0x01       ; 1
 188:   9a 83           std     Y+2, r25        ; 0x02
 18a:   89 83           std     Y+1, r24        ; 0x01
 18c:   89 81           ldd     r24, Y+1        ; 0x01
 18e:   9a 81           ldd     r25, Y+2        ; 0x02
 190:   83 30           cpi     r24, 0x03       ; 3
 192:   91 05           cpc     r25, r1
 194:   04 f3           brlt    .-64            ; 0x156 <main+0xc4>
 196:   80 e0           ldi     r24, 0x00       ; 0
 198:   90 e0           ldi     r25, 0x00       ; 0
 19a:   65 96           adiw    r28, 0x15       ; 21
 19c:   0f b6           in      r0, 0x3f        ; 63
 19e:   f8 94           cli
 1a0:   de bf           out     0x3e, r29       ; 62
 1a2:   0f be           out     0x3f, r0        ; 63
 1a4:   cd bf           out     0x3d, r28       ; 61
 1a6:   df 91           pop     r29
 1a8:   cf 91           pop     r28
 1aa:   08 95           ret

Exercise for Students

Recompile the same program with the highest level of optimization (-0s) and see how things change. Is this what you would expect?

Tutorials for Other Courses

Additional Links

Site Mirror

This is a mirror to be used when http://myweb.msoe.edu/taylor/, (EDU instead of US) is not available.