Program Mechanics

A Dr. Taylor Tutorial

Simple Program

Here is a very simple program that adds two numbers together (23+52):

; Sample program that adds two numbers.
; t a y l o r@msoe.edu, 3-14-2007
; Modification log:
; t a y l o r@msoe.edu, 12-11-2008: Added .equ and .def

.nolist
.include "m32def.inc"    ; Include the appropriate register definition file
.list

.equ start = 0x2A        ; Assign label start to starting memory address for program
.def val1 = r20          ; Assign alias val1 to register 20
.def val2 = r21          ; Assign alias val2 to register 21

.dseg                    ; DATA SEGMENT
.org 0x60                ; Set SRAM address to hex 60, this is right after I/O
result:
       .byte 1           ; Reserve 1 byte in SRAM to store the resulting sum

.cseg                    ; CODE SEGMENT
.org 0                   ; Set the RESET vector to
       rjmp start        ; The beginning of our code

.org start               ; Set Program Counter to hex 2A, end of Interrupt Jump Table
       ldi  val1, 23     ; Initialize first value (in r20)
       ldi  val2, 52     ; Initialize second value (in r21)
       add  val1, val2   ; Add two numbers
       sts result, val1  ; Store the result in SRAM

stop:
       rjmp stop         ; Loop forever here (so that it doesn't continue
                         ; executing whatever is stored in program memory
                         ; after this.

Program Components

The assembler recognizes the following items:

Program Sections

A program consists of:

Listing File

The listing file for the simple program is shown below:

AVRASM ver. 2.1.0  C:\Atmel\Projects\wk2lec3a\wk2lec3a.asm Wed Mar 14 14:57:38 2007

C:\Atmel\Projects\wk2lec3a\wk2lec3a.asm(5): Including file 'C:\Atmel\AVRTools\AvrAssembler2\Appnotes\m32def.inc'
                 
                 
                 ; t a y l o r@msoe.edu, 3-14-2007
                 
                 .list
                 
                 .dseg                    ; DATA SEGMENT
                 .org 0x60                ; Set SRAM address to hex 60, this is right after I/O
                 result:
000060                  .byte 1           ; Reserve 1 byte in SRAM to store the resulting sum
                 
                 .cseg                    ; CODE SEGMENT
                 .org 0                   ; Set the RESET vector to
000000 c029             rjmp start        ; The beginning of our code
                 
                 .org 0x2A                ; Set Program Counter to hex 2A, end of Interrupt Jump Table
                 start:
00002a e147             ldi  r20, 23      ; Initialize r20 with first value
00002b e354             ldi  r21, 52      ; Initialize r21 with second value
00002c 0f45             add  r20, r21     ; Add two numbers
00002d 9340 0060        sts result, r20   ; Store the result in SRAM
                 
                 stop:
00002f cfff             rjmp stop         ; Loop forever here (so that it doesn't continue
                                          ; executing whatever is stored in program memory
                                          ; after this.


RESOURCE USE INFORMATION
------------------------

Notice:
The register and instruction counts are symbol table hit counts,
and hence implicitly used resources are not counted, eg, the
'lpm' instruction without operands implicitly uses r0 and z,
none of which are counted.

x,y,z are separate entities in the symbol table and are
counted separately from r26..r31 here.

.dseg memory usage only counts static data declared with .byte

ATmega32 register use summary:
r0 :   0 r1 :   0 r2 :   0 r3 :   0 r4 :   0 r5 :   0 r6 :   0 r7 :   0 
r8 :   0 r9 :   0 r10:   0 r11:   0 r12:   0 r13:   0 r14:   0 r15:   0 
r16:   0 r17:   0 r18:   0 r19:   0 r20:   3 r21:   2 r22:   0 r23:   0 
r24:   0 r25:   0 r26:   0 r27:   0 r28:   0 r29:   0 r30:   0 r31:   0 
x  :   0 y  :   0 z  :   0 
Registers used: 2 out of 35 (5.7%)

ATmega32 instruction use summary:
adc   :   0 add   :   1 adiw  :   0 and   :   0 andi  :   0 asr   :   0 
bclr  :   0 bld   :   0 brbc  :   0 brbs  :   0 brcc  :   0 brcs  :   0 
break :   0 breq  :   0 brge  :   0 brhc  :   0 brhs  :   0 brid  :   0 
brie  :   0 brlo  :   0 brlt  :   0 brmi  :   0 brne  :   0 brpl  :   0 
brsh  :   0 brtc  :   0 brts  :   0 brvc  :   0 brvs  :   0 bset  :   0 
bst   :   0 call  :   0 cbi   :   0 cbr   :   0 clc   :   0 clh   :   0 
cli   :   0 cln   :   0 clr   :   0 cls   :   0 clt   :   0 clv   :   0 
clz   :   0 com   :   0 cp    :   0 cpc   :   0 cpi   :   0 cpse  :   0 
dec   :   0 eor   :   0 fmul  :   0 fmuls :   0 fmulsu:   0 icall :   0 
ijmp  :   0 in    :   0 inc   :   0 jmp   :   0 ld    :   0 ldd   :   0 
ldi   :   2 lds   :   0 lpm   :   0 lsl   :   0 lsr   :   0 mov   :   0 
movw  :   0 mul   :   0 muls  :   0 mulsu :   0 neg   :   0 nop   :   0 
or    :   0 ori   :   0 out   :   0 pop   :   0 push  :   0 rcall :   0 
ret   :   0 reti  :   0 rjmp  :   2 rol   :   0 ror   :   0 sbc   :   0 
sbci  :   0 sbi   :   0 sbic  :   0 sbis  :   0 sbiw  :   0 sbr   :   0 
sbrc  :   0 sbrs  :   0 sec   :   0 seh   :   0 sei   :   0 sen   :   0 
ser   :   0 ses   :   0 set   :   0 sev   :   0 sez   :   0 sleep :   0 
spm   :   0 st    :   0 std   :   0 sts   :   1 sub   :   0 subi  :   0 
swap  :   0 tst   :   0 wdr   :   0 
Instructions used: 4 out of 111 (3.6%)

ATmega32 memory use summary [bytes]:
Segment   Begin    End      Code   Data   Used    Size   Use%
---------------------------------------------------------------
[.cseg] 0x000000 0x000060     14      0     14   32768   0.0%
[.dseg] 0x000060 0x000061      0      1      1    2048   0.0%
[.eseg] 0x000000 0x000000      0      0      0    1024   0.0%

Assembly complete, 0 errors, 0 warnings

Sample Programs

Sum of Two 16-Bit Numbers

We could modify the sample program above to add two 16-bit numbers as follows:

; Sample program that adds two 16-bit numbers.
;  313 + 8000 = 8313
; t a y l o r@msoe.edu, 3-14-2007

.nolist
.include "m32def.inc"    ; Include the appropriate register definition file
.list

.dseg                    ; DATA SEGMENT
.org 0x60                ; Set SRAM address to hex 60, this is right after I/O
result:
       .byte 2           ; Reserve 2 bytes in SRAM to store the resulting sum

.cseg                    ; CODE SEGMENT
.org 0                   ; Set the RESET vector to
       rjmp start        ; The beginning of our code

.org 0x2A                ; Set Program Counter to hex 2A, end of IJT
start:
       ldi  r21, 0x01    ; Initialize r21 with high byte of first value
       ldi  r20, 0x39    ; Initialize r20 with low byte of first value
       ldi  r23, 0x1F    ; Initialize r23 with high byte of second value
       ldi  r22, 0x40    ; Initialize r22 with low byte of second value
       add  r20, r22     ; Add low byte of the two numbers
       adc  r21, r23     ; Add high byte of the two numbers
       sts result+1, r21 ; Store high byte of the result in SRAM
       sts result, r20   ; Store low byte of the result in SRAM

stop:
       rjmp stop         ; Loop forever here (so that it doesn't continue
                         ; executing whatever is stored in program memory
                         ; after this.

Note:

Sum of Five Numbers Part I

This example uses direct addressing mode to calculate the sum of five 8-bit numbers.

; Sample program that calculates the sum of five numbers.
; The sum of the five numbers must be less than 256.
; This program uses direct addressing, which is NOT the best
; way to do this.
; t a y l o r@msoe.edu, 3-14-2007

.nolist                    ; Ignore what follows when generating the list file
.include "m32def.inc"      ; Include the appropriate register definition file
.list                      ; Include what follows when generating the list file

.equ n1 = 0x01
.equ n2 = 0x02
.equ n3 = 0x03
.equ n4 = 0x04
.equ n5 = 0x05

.def temp = r16            ; Use r16 as a temporary register
.def sum = r20             ; Use r20 to store the sum of the five numbers
.def addend = r21          ; Use r21 to store the value to be added to the sum

.dseg                      ; DATA SEGMENT 
.org 0x60                  ; Set SRAM address to hex 60, this is right after I/O 
nums  :   
       .byte 5             ; Reserve 5 bytes in SRAM for the five numbers
result:
       .byte 1             ; Reserve 1 byte in SRAM to store the resulting sum

.cseg                      ; CODE SEGMENT
.org 0                     ; Set the RESET vector to
       rjmp start          ; The beginning of our code

.org 0x2A                  ; Set Program Counter to hex 2A, end of Interrupt Jump Table
start:
       ldi  temp, n1       ; Initialize data memory with values to be summed
       sts  nums, temp
       ldi  temp, n2
       sts  nums+1, temp
       ldi  temp, n3
       sts  nums+2, temp
       ldi  temp, n4
       sts  nums+3, temp
       ldi  temp, n5
       sts  nums+4, temp

       lds  sum, nums      ; Load first number to sum register
       lds  addend, nums+1 ; Load second number to addend register
       add  sum, addend    ; Add addend to cummulative sum
       lds  addend, nums+2 ; Load third number to addend register
       add  sum, addend    ; Add addend to cummulative sum
       lds  addend, nums+3 ; Load third number to addend register
       add  sum, addend    ; Add addend to cummulative sum
       lds  addend, nums+4 ; Load third number to addend register
       add  sum, addend    ; Add addend to cummulative sum

       sts result, sum     ; Store sum in result memory location
stop:
       rjmp stop

Sum of Five Numbers Part II

; Sample program that calculates the sum of five (or whatever) numbers.
; The sum of the numbers must be less than 256.
; This program uses indirect addressing
; t a y l o r@msoe.edu, 3-14-2007

.nolist                    ; Ignore what follows when generating the list file
.include "m32def.inc"      ; Include the appropriate register definition file
.list                      ; Include what follows when generating the list file

.equ bvalue = 0x01         ; Starting value for numbers to sum
.equ num = 5               ; Number of values to sum

.def temp = r16            ; Use r16 as a temporary register
.def sum = r20             ; Use r20 to store the sum of the five numbers
.def addend = r21          ; Use r21 to store the value to be added to the sum
.def counter = r22         ; Use r22 as a counter

.dseg                      ; DATA SEGMENT 
.org 0x60                  ; Set SRAM address to hex 60, this is right after I/O 
nums:   
       .byte num           ; Reserve 5 bytes in SRAM for the five numbers
result:
       .byte 1             ; Reserve 1 byte in SRAM to store the resulting sum

.cseg                      ; CODE SEGMENT
.org 0                     ; Set the RESET vector to
       rjmp start          ; The beginning of our code

.org 0x2A                  ; Set Program Counter to hex 2A, end of IJT
start:
                           ; Initialize X register with 0x0060
       ldi  r27, 0x0       ; Place 0x00 in high byte of X register
       ldi  r26, nums      ; Place 0x60 in low byte of X register
       ldi  temp, bvalue   ; Initialize data memory with beginning value
                           ; of the numbers to be summed
       ldi  counter, num   ; Initialize counter to repeat loop 5 times

iloop:                     ; Start of initialization loop
       st   X+, temp       ; Store value in data memory
       inc  temp           ; Increments temp register by one
       dec  counter        ; Decrement counter
       brne iloop          ; Repeat loop if counter not zero

                           ; Initialize X register with 0x0060
       ldi  r27, 0x0       ; Place 0x00 in high byte of X register
       ldi  r26, nums      ; Place 0x60 in low byte of X register
       ld   sum, X+        ; Load first number to sum and advance X to next number
       ldi  counter, num-1 ; Initialize counter to repeat loop 4 times

sloop:
       ld   addend, X+     ; Load second number to addend register and inc X
       add  sum, addend    ; Add addend to cummulative sum
       dec  counter        ; Decrement counter
       brne sloop          ; Repeat loop if counter not zero

       sts result, sum     ; Store sum in result memory location
stop:
       rjmp stop

Instead of

       ldi  r27, 0x0       ; Place 0x00 in high byte of X register
       ldi  r26, nums      ; Place 0x60 in low byte of X register

we could write the more readable:

       ldi  XH, HIGH(nums) ; Place 0x00 in high byte of X register
       ldi  XL, LOW(nums)  ; Place 0x60 in low byte of X register

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.