;**** A P P L I C A T I O N N O T E A V R 2 0 2 ************************
;*
;* Title: 16-bit Arithmetics
;* Version: 1.1
;* Last updated: 97.07.04
;* Target: AT90Sxxxx (All AVR Devices)
;*
;* Support E-mail: avr@atmel.com
;*
;* DESCRIPTION
;* This application note lists applications for the following
;* Add/Subtract/Compare operations:
;*
;* "add16" ADD 16+16
;* "adddi16" ADD 16+Immediate(16)
;* "sub16" SUB 16-16
;* "subi16" SUB 16-Immediate(16)
;* "cp16" COMPARE 16/16
;* "cpi16" COMPARE 16/Immediate
;* "neg16" NEGATION 16
;*
;***************************************************************************
.cseg
ldi r16,0x12 ;Set up some registers to show usage of
ldi r17,0x34 ;the subroutines below.
ldi r18,0x56 ;All expected results are presented as
ldi r19,0x78 ;comments
;***************************************************************************
;*
;* "add16" - Adding 16-bit registers
;*
;* This example adds the two pairs of register variables (add1l,add1h)
;* and (add2l,add2h) The result is placed in (add1l, add1h).
;*
;* Number of words :2
;* Number of cycles :2
;* Low registers used :None
;* High registers used :4
;*
;* Note: The sum and the addend share the same register. This causes the
;* addend to be overwritten by the sum.
;*
;***************************************************************************
;**** Register Variables
.def add1l = r16
.def add1h = r17
.def add2l = r18
.def add2h = r19
;***** Code
add16: add add1l, add2l ;Add low bytes
adc add1h, add2h ;Add high bytes with carry
;Expected result is 0xAC68
;***************************************************************************
;*
;* "addi16" - Adding 16-bit register with immediate
;*
;* This example adds a register variable (addi1l,addi1h) with an
;* immediate 16-bit number defined with .equ-statement. The result is
;* placed in (addi1l, addi1h).
;*
;* Number of words :2
;* Number of cycles :2
;* Low registers used :None
;* High registers used :2
;*
;* Note: The sum and the addend share the same register. This causes the
;* addend to be overwritten by the sum.
;*
;***************************************************************************
;***** Register Variables
.def addi1l = r16
.def addi1h = r17
;***** Immediate 16-bit number
.equ addi2 = 0x1234
;***** Code
addi16: subi add1l, low(-addi2) ;Add low byte ( x -(-y)) = x + y
sbci add1h, high(-addi2) ;Add high byte with carry
;Expected result is 0xBE9C
;***************************************************************************
;*
;* "sub16" - Subtracting 16-bit registers
;*
;* This example subtracts two pairs of register variables (sub1l,sub1h)
;* from (sub2l, sub2h) The result is stored in registers sub1l, sub1h.
;*
;* Number of words :2
;* Number of cycles :2
;* Low registers used :None
;* High registers used :4
;*
;* Note: The result and "sub1" share the same register. This causes "sub1"
;* to be overwritten by the result.
;*
;***************************************************************************
;***** Register Variables
.def sub1l = r16
.def sub1h = r17
.def sub2l = r18
.def sub2h = r19
;***** Code
sub16: sub sub1l,sub2l ;Subtract low bytes
sbc sub1h,sub2h ;Add high byte with carry
;Expected result is 0x4646
;***************************************************************************
;*
;* "subi16" - Subtracting immediate 16-bit number from a 16-bit register
;*
;* This example subtracts the immediate 16-bit number subi2 from the
;* 16-bit register (subi1l,subi1h) The result is placed in registers
;* subi1l, subi1h.
;*
;* Number of words :2
;* Number of cycles :2
;* Low registers used :None
;* High registers used :2
;*
;* Note: The result and "subi1" share the same register. This causes
;* "subi1" to be overwritten by the result.
;*
;***************************************************************************
;***** Register Variables
.def subi1l = r16
.def subi1h = r17
;***** Immediate 16-bit number
.equ subi2 = 0x1234
;***** Code
subi16: subi subi1l,low(subi2) ;Subtract low bytes
sbci subi1h,high(subi2) ;Subtract high byte with carry
;Expected result is 0x3412
;***************************************************************************
;*
;* "cp16" - Comparing two 16-bit numbers
;*
;* This example compares the register pairs (cp1l,cp1h) with the register
;* pairs (cp2l,cp2h) If they are equal the zero flag is set(one)
;* otherwise it is cleared(zero)
;*
;* Number of words :2
;* Number of cycles :2
;* Low registers used :None
;* High registers used :4
;*
;* Note: The contents of "cp1" will be overwritten.
;*
;***************************************************************************
;***** Register Variables
.def cp1l = r16
.def cp1h = r17
.def cp2l = r18
.def cp2h = r19
;***** Code
cp16: cp cp1l,cp2l ;Compare low byte
cpc cp1h,cp2h ;Compare high byte with carry from
;previous operation
ncp16:
;Expected result is Z=0
;***************************************************************************
;*
;* "cpi16" - Comparing 16-bit register with 16-bit immediate
;*
;* This example compares the register pairs (cpi1l,cpi1h) with the value
;* cpi2. If they are equal the zero flag is set(one), otherwise it is
;* cleared(zero). This is enabled by the AVR's zero propagation. Carry is
;* also set if the result is negative. This means that all conditional
;* branch instructions can be used after the comparison.
;*
;* Number of words :3
;* Number of cycles :3
;* Low registers used :None
;* High registers used :3
;*
;*
;***************************************************************************
;***** Register Variables
.def cp1l =r16
.def cp1h =r17
.def c_tmp=r18
.equ cp2 = 0x3412 ;Immediate to compare with
;***** Code
cpi16: cpi cp1l,low(cp2) ;Compare low byte
ldi c_tmp,high(cp2) ;
cpc cp1h,c_tmp ;Compare high byte
;Expected result is Z=1, C=
;***************************************************************************
;*
;* "neg16" - Negating 16-bit register
;*
;* This example negates the register pair (ng1l,ng1h) The result will
;* overwrite the register pair.
;*
;* Number of words :4
;* Number of cycles :4
;* Low registers used :None
;* High registers used :2
;*
;***************************************************************************
;***** Register Variables
.def ng1l = r16
.def ng1h = r17
;***** Code
ng16:
com ng1l ;Invert low byte ;Calculated by
com ng1h ;Invert high byte ;incverting all
subi ng1l,low(-1) ;Add 0x0001, low byte ;bits then adding
sbci ng1h,high(-1) ;Add high byte ;one (0x0001)
;Expected result is 0xCBEE
;***************************************************************************
;*
;* End of examples.
;*
;***************************************************************************
forever:rjmp forever