AVR Assembler Tutorial
AVR Assembler Tutorial
Avr-Asm-Tutorial
http://www.avr-asm-tutorial.net
Content
Why learning Assembler?..........................................................................................................................1 Short and easy.......................................................................................................................................1 Fast and quick........................................................................................................................................1 Assembler is easy to learn.....................................................................................................................1 AT90Sxxxx are ideal for learning assembler........................................................................................1 Test it!....................................................................................................................................................1 Hardware for AVR-Assembler-Programming...........................................................................................2 The ISP-Interface of the AVR-processor family...................................................................................2 Programmer for the PC-Parallel-Port....................................................................................................2 Experimental board with a AT90S2313................................................................................................3 Ready-to-use commercial programming boards for the AVR-family...................................................4 Tools for AVR assembly programing........................................................................................................5 The editor..............................................................................................................................................5 The assembler........................................................................................................................................6 Programming the chips..........................................................................................................................7 Simulation in the studio.........................................................................................................................7 Register......................................................................................................................................................9 What is a register?.................................................................................................................................9 Different registers................................................................................................................................10 Pointer-register....................................................................................................................................10 Recommendation for the use of registers............................................................................................11 Ports.........................................................................................................................................................12 What is a Port?....................................................................................................................................12 Details of relevant ports in the AVR...................................................................................................13 The status register as the most used port.............................................................................................13 Port details...........................................................................................................................................14 SRAM..................................................................................................................................................15 Using SRAM in AVR assembler language.........................................................................................15 What is SRAM?...................................................................................................................................15 For what purposes can I use SRAM?..................................................................................................15 How to use SRAM?.............................................................................................................................15 Use of SRAM as stack.........................................................................................................................16 Defining SRAM as stack................................................................................................................16 Use of the stack...............................................................................................................................17 Bugs with the stack operation.........................................................................................................17 Jumping and Branching............................................................................................................................19 Controlling sequential execution of the program................................................................................19 What happens during a reset?.........................................................................................................19 Linear program execution and branches..............................................................................................20 Timing during program execution.......................................................................................................20 Macros and program execution...........................................................................................................21 Subroutines..........................................................................................................................................21 Interrupts and program execution........................................................................................................23 Calculations..............................................................................................................................................25 Number systems in assembler.............................................................................................................25 Positive whole numbers (bytes, words, etc.)..................................................................................25 Signed numbers (integers)..............................................................................................................25 Binary Coded Digits, BCD.............................................................................................................25 Packed BCDs..................................................................................................................................26 Numbers in ASCII-format..............................................................................................................26 Bit manipulations................................................................................................................................26 Shift and rotate....................................................................................................................................27 Adding, subtracting and comparing....................................................................................................28 Format conversion for numbers...........................................................................................................29 Multiplication......................................................................................................................................30 Decimal multiplication...................................................................................................................30 Binary multiplication......................................................................................................................30
Avr-Asm-Tutorial
http://www.avr-asm-tutorial.net
AVR-Assembler program...............................................................................................................31 Binary rotation................................................................................................................................32 Multiplication in the studio.............................................................................................................32 Division...............................................................................................................................................34 Decimal division.............................................................................................................................34 Binary division...............................................................................................................................34 Program steps during division........................................................................................................35 Division in the simulator................................................................................................................35 Number conversion.............................................................................................................................37 Decimal Fractions................................................................................................................................37 Linear conversions..........................................................................................................................37 Example 1: 8-bit-AD-converter with fixed decimal output............................................................38 Example 2: 10-bit-AD-converter with fixed decimal output..........................................................40 Annex.......................................................................................................................................................41 Commands sorted by function.............................................................................................................41 Command list in alphabetic order.......................................................................................................43 Assembler directives.......................................................................................................................43 Commands......................................................................................................................................43 Port details...........................................................................................................................................45 Status-Register, Accumulator flags................................................................................................45 Stackpointer....................................................................................................................................45 SRAM and External Interrupt control............................................................................................45 External Interrupt Control...............................................................................................................46 Timer Interrupt Control..................................................................................................................46 Timer/Counter 0..............................................................................................................................47 Timer/Counter 1..............................................................................................................................48 Watchdog-Timer.............................................................................................................................49 EEPROM........................................................................................................................................49 Serial Peripheral Interface SPI........................................................................................................50 UART.............................................................................................................................................51 Analog Comparator........................................................................................................................51 I/O Ports..........................................................................................................................................52 Ports, alphabetic order.........................................................................................................................52 List of abbreviations............................................................................................................................53
Avr-Asm-Tutorial
http://www.avr-asm-tutorial.net
Test it!
,e patient doing your !irst steps: ! you are !amiliar with another ;high-level< language: !orget it !or the !irst time. ,ehind every assembler language there is a $ertain hardware $on$ept. 2ost o! the spe$ial !eatures o! other $omputer languages don't ma%e any sense in assembler. The !irst !ive $ommands are not easy to learn, then your learning speed rises !ast. A!ter you had your !irst lines: grab the instru$tion set list and lay ba$% in the bathtub, wondering what all the other $ommands are li%e. =on't try to program a mega-ma$hine to start with. This does not ma%e sense in any $omputer language, and 9ust produ$es !rustration. 8omment your subroutines and store them in a spe$ial dire$tory, i! debugged: you will need them again in a short time. >ave su$$ess:
Avr-Asm-Tutorial
http://www.avr-asm-tutorial.net
+8?: A $lo$% signal that shi!ts the bits to be written to the memory into an internal shi!t register, and that shi!ts out the bits to be read !rom another internal shi!t register, 25+ : The data signal that sends the bits to be written to the A74, 2 +5: The data signal that re$eives the bits read !rom the A74.
These three signal pins are internally $onne$ted to the programming ma$hine only i! you $hange the 43+3T ;sometimes also $alled 4+T or restart< pin to *ero. 5therwise, during normal operation o! the A74, these pins are programmable /5 lines li%e all the others. ! you li%e to use these pins !or other purposes during normal operation, and !or insystem-programming, you'll have to ta%e $are, that these two purposes do not $on!li$t. 6sually you then de$ouple these by resistors or by use o! a multiple(er. What is ne$essary in your $ase, depends !rom your use o! the pins in the normal operation mode. &ou're lu$%y, i! you $an use them !or in- system-programming e($lusively. )ot ne$essary, but re$ommendable !or in-system-programming is, that you supply the programming hardware out o! the supply voltage o! your system. That ma%es it easy, and requires two additional lines between the programmer and the A74 board. @)= is the $ommon ground, 7T@ ;target voltage< the supply voltage ;usually A.0 volts<. This adds up to B lines between the programmer and the A74 board. The resulting +1B $onne$tion is, as de!ined by A23/, is shown on the le!t. +tandards always have alternative standards, that were used earlier. This is the te$hni$al basis that $onstitutes the adaptor industry. n our $ase the alternative standard was designed as +110 and was used on the +T?200 board. t's still a very widespread standard, and even the +T?A00 is still equipped with it. +110 has an additional signal to drive a red /3=. This /3= signals that the programmer is doing his 9ob. A good idea. Cust $onne$t the /3= to a resistor and $lamp it the positive supply voltage.
Avr-Asm-Tutorial
http://www.avr-asm-tutorial.net
The ne$essary program algorithm is done by the +1 so!tware, that is available !rom AT23/'s so!tware download page.
a small voltage supply !or $onne$tion to an A8 trans!ormer and a voltage regulator A7/1A, a GTA/ $lo$% generator ;here with a 10 2$s/s, all other !requen$ies below the ma(imum !or the 2F1F will also wor%<, the ne$essary parts !or a sa!e reset during supply voltage swit$hing, the +1-1rogramming- nter!a$e ;here with a +1101 )-$onne$tor<.
+o that's what you need to start with. 8onne$t other peripheral add-ons to the numerous !ree /5 pins o! the 2F1F. The easiest output devi$e $an be a /3=, $onne$ted via a resistor to the positive supply voltage. With that, you $an start writing your !irst assembler program swit$hing the /3= on and o!!.
Avr-Asm-Tutorial
http://www.avr-asm-tutorial.net
+o$%ets !or programming most o! the A74 types, serial und parallel programming, +1B1 )- and +1101 )-$onne$tor !or e(ternal n-+ystem-1rogramming, programmable os$illator !requen$y and suplly voltages, plug-in swit$hes and /3=s, a plugged 4+2F28-$onne$tor ;6A4T<, a serial #lash-331452, a$$ess to all ports via a 10-pin $onne$tor.
3(periments $an start with the also supplied AT-0+HA1A. The board is $onne$ted to the 18 using a serial port ;852(< and is $ontrolled by later versions o! A74 studio, available !rom AT23/'s webpage. This $overs all hardware requirements that the beginner might have.
Avr-Asm-Tutorial
http://www.avr-asm-tutorial.net
the editor, the assembler program, the $hip programing inter!a$e, and the simulator.
The ne$essary so!tware tools are IAT23/ and available on the webpage o! AT23/ !or download. The s$reenshots here are IAT23/. t should be mentioned that there are di!!erent versions o! the so!tware and some o! the s$reenshots are sub9e$t to $hange with the used version. +ome windows or menues loo% di!!erent in di!!erent versions. The basi$ !un$tions are mainly un$hanged. 4e!er to the programer's handboo%, this page 9ust provides an overview !or the beginner's !irst steps and is not written !or the assembly programing e(pert.
The editor
Assembler programs are written with a editor. The editor 9ust has to be able to $reate and edit A+8 te(t !iles. +o, basi$ally, any simple editor does it. re$ommend the use o! a more advan$ed editor, either WA74A+2IAT23/ or the editor written by Tan +illi%saar ;s$reenshot see below<. An assembly program written with WA74A+2I goes li%e this. Cust install WA74A+2I and start the program:
)ow we type in our dire$tives and assembly $ommands in the WA74A+2 editor window, together with some $omments ;starting with J<. That should loo% li%e this:
)ow store the program te(t, named to something.asm into a dedi$ated dire$tory, using the !ile menue. The assembly program is $omplete now. ! you li%e editing a little more in a sophisti$ated manner you $an use the e($ellent editor written by Tan +illi%saar. This editor tools is designed !or A74s and available !or !ree !rom Tan's webpage. n this editor our program loo%s li%e this:
Avr-Asm-Tutorial
http://www.avr-asm-tutorial.net
The editor re$ogni*es $ommands automati$ally and uses di!!erent $olors ;synta( highlighting< to signal user $onstants and typing errors in those $ommands ;in bla$%<. +toring the $ode in an .asm !ile provides nearly the same te(t !ile.
The assembler
)ow we have to translate this $ode to a ma$hine-oriented !orm well understood by the A74 $hip. =oing this is $alled assembling, whi$h means $olle$ting the right $ommand words. ! you use WA74A+2I 9ust $li$% assemble on the menue. The result is shown here: The assembler reports the $omplete translation with no errors. ! errors o$$ur these are noti!ied. Assembling resulted in one word o! $ode whi$h resulted !rom the $ommand we used. Assembling our single asm-te(t !ile now has produ$ed !our other !iles ;not all apply here<. The !irst o! these !our new !iles, T3+T.331, holds the $ontent that should be written to the 331452 o! the A74. This is not very interesting in our $ase, be$ause we didn't program any $ontent !or the 331452. The assembler has there!ore deleted this !ile when he $ompleted the assembly run.
The se$ond !ile, T3+T.>3G, is more relevant be$ause this !ile holds the $ommands later programmed into the A74 $hip. This !ile loo%s li%e this. The he( numbers are written in a spe$ial A+8 !orm, together with adress in!ormations and a $he$%sum !or ea$h line. This !orm is $alled ntel-he(-!ormat, and it is very old. The !orm is well understood by the programing so!tware. The third !ile, T3+T.5,C, will be introdu$ed later, this !ile is needed to simulate an A74. ts !ormat is he(ade$imal and de!ined by AT23/. 6sing a he(-editor its $ontent loo%s li%e this. Attention: This !ile !ormat is not $ompatible with the programer so!tware, don't use this !ile to program the A74 ;a very $ommon error when starting<. The !ourth !ile, T3+T./+T, is a te(t !ile. =isplay its $ontent with a simple editor. The !ollowing results. The program with all its adresses, $omands and error messages are displayed in a readable !orm. &ou will need that !ile in some $ases to debug errors.
Avr-Asm-Tutorial
http://www.avr-asm-tutorial.net
5pen the !ile T3+T1.5,C that results by assembling T3+T1.asm. &ou are as%ed whi$h options you li%e to use ;i! not, you $an $hange these using the menue item + 26/AT54 51T 5)+<. The !ollowing options will be sele$ted: n the devi$e sele$tion se$tion we sele$t the desired $hip type. The $orre$t !requen$y should be sele$ted i! you li%e to simulate $orre$t timings.
n order to view the $ontent o! some registers and what the pro$essor's status is we sele$t 7 3W 14583++54 and 43@ +T34+. The display should now loo% li%e this.
Avr-Asm-Tutorial
http://www.avr-asm-tutorial.net
The pro$essor window displays all values li%e the $ommand $ounter, the !lags and the timing in!ormation ;here: 1 2>* $lo$%<. The stop wat$h $an be used to measure the ne$essary time !or going through routines et$.
)ow we start the program e(e$ution. We use the single step opportunity ;T4A83 )T5 or #11<. 6sing @5 would result in $ontinous e(e$tion and not mu$h would be seen due to the high speed o! simulation. A!ter the !irst e(e$uted step the pro$essor window should loo% li%e this. The program $ounter is at step 1, the $y$le $ounter at 2 ;4C21 needed two $y$les<. At 1 2>* $lo$% two mi$rose$onds have been wasted, the !lags and pointer registers are not $hanged. The sour$e te(t window displays a pointer on the ne(t $ommand that will be e(e$uted. 1ressing #11 again e(e$utes the ne(t $ommand, register mp ;K41B< will be set to 0(##. )ow the register window should highlite this $hange. 4egister 41B's new value is displayed in red letters. We $an $hange the value o! a register at any time to test what happens then. )ow step F is e(e$uted, output to the dire$tion register o! 1ort ,. To display this we open a new /5 view window and sele$t 1ort ,. The display should loo% li%e this. The =ata =ire$tion 4egister in the /5-view window o! 1ort , now shows the new value. The values $ould be $hanged manually, i! desired, pin by pin. The ne(t two steps are simulated using #11. They are not displayed here. +etting the output ports to one with the $ommand /= mp,0(## and 56T 154T,,mp results in the !ollowing pi$ture in the /5 view. )ow the output port bits are all one, the /5 view shows this. That is our short trip through the simulator so!tware world. The simulator is $apable to mu$h more, so it should be applied e(tensively in $ases o! design errors. 7isit the di!!erent menue items, there is mu$h more than showed here.
Avr-Asm-Tutorial
http://www.avr-asm-tutorial.net
Register
What is a register?
4egisters are spe$ial storages with H bits $apa$ity and they loo% li%e this:
,it D
,it B
,it A
,it E
,it F
,it 2
,it 1
,it 0
)ote the numeration o! these bits: the least signi!i$ant bit starts with *ero ;20 K 1<. A register $an either store numbers !rom 0 to 2AA ;positive number, no negative values<, or numbers !rom -12H to L12D ;whole number with a sign bit in bit D<, or a value representing an A+8 -$oded $hara$ter ;e.g. 'A'<, or 9ust eight single bits that do not have something to do with ea$h other ;e.g. !or eight single !lags used to signal eight di!!erent yes/no de$isions<. The spe$ial $hara$ter o! registers, $ompared to other storage sites, is that
they $an be used dire$tly in assembler $ommands, operations with their $ontent require only a single $ommand word, they are $onne$ted dire$tly to the $entral pro$essing unit $alled the a$$umulator, they are sour$e and target !or $al$ulations.
There are F2 registers in an A74. They are originally named 40 to 4F1, but you $an $hoose to name them to more meaning!ul names using an assembler dire$tive. An e(ample:
.DEF MyPreferredRegister = R16
Assembler dire$tives always start with a dot in $olumn 1 o! the te(t. nstru$tions do )3734 start in $olumn 1, they are always pre$eeded by a Tab- or blan% $hara$ter: )ote that assembler dire$tives li%e this are only meaning!ul !or the assembler but do not produ$e any $ode that is e(e$utable in the A74 target $hip. nstead o! using the register name 41B we $an now use our own name 2y1re!erred4egister, i! we want to use 41B within a $ommand. +o we write a little bit more te(t ea$h time we use this register, but we have an asso$iation what might be the $ontent o! this register. 6sing the $ommand line
LDI MyPreferredRegister, 150
whi$h means: load the number 1A0 immediately to the register 41B, /oa= mmediate. This loads a !i(ed value or a $onstant to that register. #ollowing the assembly or translation o! this $ode the program storage written to the A74 $hip loo%s li%e this:
000000 E906
The load $ommand $ode as well as the target register ;41B< as well as the value o! the $onstant ;1A0< is part o! the he( value 3-0B, even i! you don't see this dire$tly. =on't be a!raid: you don't have to remember this $oding be$ause the assembler %nows how to translate all this to yield 3-0B. Within one $ommand two di!!erent registers $an play a role. The easiest $ommand o! this type is the $opy $ommand 257. t $opies the $ontent o! one register to another register. /i%e this:
.DEF MyPreferredRegister = R16 .DEF AnotherRegister = R15 LDI MyPreferredRegister, 150 MO AnotherRegister, MyPreferredRegister
The !irst two lines o! this monster program are dire$tives that de!ine the new names o! the registers 41B and 41A !or the assembler. Again, these lines do not produ$e any $ode !or the A74. The $ommand lines with /= and 257 produ$e $ode:
000000 E906 000001 !F01
The $ommands write 1A0 into register 41B and $opy its $ontent to the target register 41A. 2154TA)T )5T3: The first register is always the target register where the result is written to! ;This is un!ortunately di!!erent !rom what one e(pe$ts or !rom how we spea%. t is a simple $onvention that was on$e de!ined that way to $on!use the beginners learning assembler. That is why assembler is that $ompli$ated.<
Avr-Asm-Tutorial
10
http://www.avr-asm-tutorial.net
Different registers
The beginner might want to write the above $ommands li%e this:
.DEF AnotherRegister = R15 LDI AnotherRegister, 150
And: you lost. 5nly the registers !rom 41B to 4F1 load a $onstant immediately with the /= $ommand, 40 to 41A don't do that. This restri$tion is not very !ine, but $ould not be avoided during $onstru$tion o! the $ommand set !or the A74s. There is one e($eption !rom that rule: setting a register to Mero. This $ommand
"LR MyPreferredRegister
is valid !or all registers. ,esides the /= $ommand you will !ind this register $lass restri$tion with the !ollowing additional $ommands:
A)= 4(,? J ,it-And o! register 4( with a $onstant value ?, 8,4 4(,2 J 8lear all bits in register 4( that are set to one within the $onstant mas% value 2, 81 4(,? J 8ompare the $ontent o! the register 4( with a $onstant value ?, +,8 4(,? J +ubtra$t the $onstant ? and the $urrent value o! the $arry !lag !rom the $ontent o! register 4( and store the result in register 4(, +,4 4(,2 J +et all bits in register 4( to one, that are one in the $onstant mas% 2, +34 4( J +et all bits in register 4( to one ;equal to /= 4(,2AA<, +6, 4(,? J +ubtra$t the $onstant ? !rom the $ontent o! register 4( and store the result in register 4(.
n all these $ommands the register must be between 41B and 4F1: ! you plan to use these $ommands you should sele$t one o! these registers !or that operation. t is easier to program. This is an additional reason why you should use the dire$tive to de!ine a register's name, be$ause you $an easier $hange the registers lo$ation a!terwards.
Pointer-register
A very spe$ial e(tra role is de!ined !or the register pairs 42B:42D, 42H:42- and 4F0:4F1. The role is so important that these pairs have e(tra names in A74 assembler: G, & and M. These pairs are 1B-bit pointer registers, able to point to adresses with ma(. 1B-bit into +4A2 lo$ations ;G, & or M< or into lo$ations in program memory ;M<. The lower byte o! the 1B-bit-adress is lo$ated in the lower register, the higher byte in the upper register. ,oth parts have their own names, e.g. the higher byte o! M is named M> ;K4F1<, the lower ,yte is M/ ;K4F0<. These names are de!ined in the standard header !ile !or the $hips. =ividing these 1B-bit-pointernames into two di!!erent bytes is done li%e !ollows:
.E#$ Adress = RAME%D & RAME%D is the highest 16'(it )dress in *RAM LDI +,,,I-,.Adress/ & *et the M*0 LDI +L,LO1.Adress/ & *et the L*0
A$$esses via pointers are programmed with spe$ially designed $ommands. 4ead a$$ess is named /= ;/oa=<, write a$$ess named +T ;+Tore<, e.g. with the G-pointer:
Pointer G GL -G
4ead/Write !rom/to adress G and in$rement the pointer a!terwards by /= 41,GL or +T GL,41 one =e$rement the pointer by one and read/write !rom/to the new adress /= 41,-G or +T -G,41 a!terwards
+imiliarly you $an use & and M !or that purpose. There is only one $ommand !or the read a$$ess to the program storage. t is de!ined !or the pointer pair M and it is named /12 ;/oad !rom 1rogram 2emory<. The $ommand $opies the byte at adress M in the program memory to the register 40. As the program memory is organised word-wise ;one $ommand on one adress $onsists o! 1B bits or two bytes or one word< the least signi!i$ant bit sele$ts the lower or higher byte ;0Klower byte, 1K higher byte<. ,e$ause o! this the original adress must be multiplied by 2 and a$$ess is limited to 1A-bit or F2 %, program memory. /i%e this:
11
http://www.avr-asm-tutorial.net
#ollowing this $ommand the adress must be in$remented to point to the ne(t byte in program memory. As this is used very o!ten a spe$ial pointer in$rementation $ommand has been de!ined to do this:
ADI1 2L,1 LPM
A= W means A=d mmediate Word and a ma(imum o! BF $an be added this way. )ote that the assembler e(pe$ts the lower o! the pointer register pair M/ as !irst parameter. This is somewhat $on!using as addition is done as 1B-bit- operation. The $omplement $ommand, subtra$ting a $onstant value o! between 0 and BF !rom a 1B-bit pointer register is named +, W, +ubtra$t mmediate Word. ;+u,tra$t mmediate Word<. A= W and +, W are possible !or the pointer register pairs G, & and M and !or the register pair 42A:42E, that does not have an e(tra name and does not allow a$$ess to +4A2 or program memory lo$ations. 42A:42E is ideal !or handling 1B-bit values. >ow to insert that table o! values in the program memory" This is done with the assembler dire$tives .=, and .=W. With that you $an insert bytewise or wordwise lists o! values. ,ytewise organised lists loo% li%e this:
.D0 1!4,55,66,79 & ) 8ist of fo9r (ytes .D0 :;his is ) te<t. : & ) 8ist of (yte =h)r)=ters
&ou should always pla$e an even number o! bytes on ea$h single line. 5therwise the assembler will add a *ero byte at the end, whi$h might be unwanted. The similiar list o! words loo%s li%e this:
.D1 1!455,6679 & ) 8ist of t>o >ords
nstead o! $onstants you $an also pla$e labels ;9ump targets< on that list, li%e that:
L)(e81? @ ... here )re soAe =oAA)nds ... B L)(e8!? @ ... here )re soAe Aore =oAA)nds ... B ;)(8e? .D1 L)(e81,L)(e8! & ) >ord>ise 8ist of 8)(e8s
/abels A/WA&+ start in $olumn 1:. )ote that reading the labels with /12 !irst yields the lower byte o! the word. A very spe$ial appli$ation !or the pointer registers is the a$$ess to the registers themselves. The registers are lo$ated in the !irst F2 bytes o! the $hip's adress spa$e ;at adress 0(0000 to 0(001#<. This a$$ess is only meaning!ul i! you have to $opy the register's $ontent to +4A2 or 331452 or read these values !rom there ba$% into the registers. 2ore $ommon !or the use o! pointers is the a$$ess to tables with !i(ed values in the program memory spa$e. >ere is, as an e(ample, a table with 10 di!!erent 1B-bit values, where the !i!th table value is read to 42A:42E:
My;)(8e? .D1 0<1!45,0<!455,0<4556,0<5567,0<5667 & ;he t)(8e C)89es, >ord>ise .D1 0<6679,0<679A,0<79A0,0<9A0",0<A0"D & org)nised Re)d5? LDI 2,,,I-,.My;)(8e3!/ & Adress of t)(8e to Dointer 2 LDI 2L,LO1.My;)(8e3!/ & A98tiD8ied (y ! for (yte>ise )==ess ADI1 2L,10 & Point to fifth C)89e in t)(8e LPM & Re)d 8e)st signifi=)nt (yte froA Drogr)A AeAory MO R!5,R0 & "oDy L*0 to 16'(it register ADI1 2L,1 & Point to M*0 in Drogr)A AeAory LPM & Re)d M*0 of t)(8e C)89e MO R!5,R0 & "oDy M*0 to 16'(it register
This is only an e(ample. &ou $an $al$ulate the table adress in M !rom some input value, leading to the respe$tive table values. Tables $an be organised byte- or $hara$ter-wise, too.
=e!ine names !or registers with the .=3# dire$tive, never use them with their dire$t name 4(. ! you need pointer a$$ess reserve 42B to 4F1 !or that purpose. 1B-bit-$ounter are best lo$ated 42A:42E. ! you need to read !rom the program memory, e.g. !i(ed tables, reserve M ;4F1:4F0< and 40 !or that purpose. ! you plan to have a$$ess to single bits within $ertain registers ;e.g. !or testing !lags<, use 41B to 42F !or that purpose.
Avr-Asm-Tutorial
12
http://www.avr-asm-tutorial.net
Ports
What is a Port?
1orts in the A74 are gates !rom the $entral pro$essing unit to internal and e(ternal hard- and so!tware $omponents. The 816 $ommuni$ates with these $omponents, reads !rom them or writes to them, e.g. to the timers or the parallel ports. The most used port is the !lag register, where results o! previous operations are written to and bran$h $onditions are read !rom. There are BE di!!erent ports, whi$h are not physi$ally available in all di!!erent A74 types. =epending on the storage spa$e and other internal hardware the di!!erent ports are either available and a$$essable or not. Whi$h o! these ports $an be used is listed in the data sheets !or the pro$essor type. 1orts have a !i(ed address, over whi$h the 816 $ommuni$ates. The address is independent !rom the type o! A74. +o e.g. the port adress o! port , is always 0(1H ;0( stands !or he(ade$imal notation<. &ou don't have to remember these port adresses, they have $onvenient aliases. These names are de!ined in the in$lude !iles ;header !iles< !or the di!!erent A74 types, that are provided !rom the produ$er. The in$lude !iles have a line de!ining port ,'s address as !ollows:
.E#$ POR;0, 0<17
+o we 9ust have to remember the name o! port ,, not its lo$ation in the /5 spa$e o! the $hip. The in$lude !ile HA1Ade!.in$ is involved by the assembler dire$tive
.I%"L$DE :"?E*oAe>hereE7515def.in=:
and the registers o! the HA1A are all de!ined then and easily a$$essable. 1orts usually are organised as H-bit numbers, but $an also hold up to H single bits that don't have mu$h to do with ea$h other. ! these single bits have a meaning they have their own name asso$iated in the in$lude !ile, e.g. to enable manipulation o! a single bit. =ue to that name $onvention you don't have to remember these bit positions. These names are de!ined in the data sheets and are given in the in$lude !ile, too. They are provided here in the port tables. As an e(ample the 286 @eneral 8ontrol 4egister, $alled 28684, $onsists o! a number o! single $ontrol bits that $ontrol the general property o! the $hip ;see the des$ription in 28684 in detail<. t is a port, !ully pa$%ed with H $ontrol bits with their own names ; +800, +801, ...<. Those who want to send their A74 to a deep sleep need to %now !rom the data sheet how to set the respe$tive bits. /i%e this:
.DEF MyPreferredRegister = R16 LDI MyPreferredRegister, 0(00100000 O$; M"$"R, MyPreferredRegister *LEEP
The 5ut $ommand brings the $ontent o! my pre!erred register, a +leep-3nable-,it $alled +3, to the port 28684 and sets the A74 immediately to sleep, i! there is a +/331 instru$tion e(e$uted. As all the other bits o! 28684 are also set by the above instru$tions and the +leep 2ode bit +2 was set to *ero, a mode $alled hal!-sleep will result: no !urther $ommand e(e$ution will be per!ormed but the $hip still rea$ts to timer and other hardware interrupts. These e(ternal events interrupt the big sleep o! the 816 i! they !eel they should noti!y the 816. 4eading a port's $ontent is in most $ases possible using the ) $ommand. The !ollowing sequen$e
.DEF MyPreferredRegister = R16 I% MyPreferredRegister, M"$"R
reads the bits in port 28684 to the register. As many ports have unde!ined and unused bits in $ertain ports, these bits always read ba$% as *eros. 2ore o!ten than reading all H bits o! a port one must rea$t to a $ertain status o! a port. n that $ase we don't need to read the whole port and isolate the relevant bit. 8ertain $ommands provide an opportunity to e(e$ute $ommands depending on the level o! a $ertain bit ;see the C621 se$tion<. +etting or $learing $ertain bits o! a port is also possible without reading and writing the other bits in the port. The two $ommands are +, ;+et ,it /o< and 8, ;8lear ,it /o<. 3(e$ution is li%e this:
.E#$ A=tiCe0it=0 & ;he (it th)t is to (e =h)nged *0I Port0, A=tiCe0it & ;he (it >i88 (e set to one "0I Port0, A=tiCe(it & ;he (it >i88 (e =8e)red to Fero
These two instru$tions have a limitation: only ports with an adress smaller than 0(20 $an be handled, ports above $annot be a$$essed that way. #or the more e(oti$ programmer: the ports $an be a$$essed using +4A2 a$$ess $ommands, e.g. +T and /=. Cust add 0(20 to the port's adress ;the !irst F2 addresses are the registers:< and a$$ess the port that way. /i%e demonstrated here:
.DEF MyPreferredRegister = R16 LDI 2,,,I-,.POR;0G4!/
1F
http://www.avr-asm-tutorial.net
That only ma%es sense in $ertain $ases, but it is possible. t is the reason why the !irst address lo$ation o! the +4A2 is always 0(B0.
Avr-Asm-Tutorial
1E
http://www.avr-asm-tutorial.net
Bit M
Calculation A==, A=8, A= W, =38, )8, +6,, +6, , +,8, +,8 , +, W A==, A=8, A= W, +6,, +6, , +,8, +,8 , +, W A==, A=8, A= W, =38, )8, +6,, +6, , +,8, +,8 , +, W A==, A=8, A= W, =38, )8, +6,, +6, , +,8, +,8 , +, W +, W
Logic
Compare
Bits
Shift
Other 8/4
A)=, A)= , 54, 81, 818, 54 , 354, 852, 81 )3@, +,4, 8,4 852, )3@ 81, 818, 81
,8/4 M, A+4, /+/, ,+3T M, 8/M, /+4, 45/, +3M, T+T 454 ,8/4 8, ,+3T 8, 8/8, +38 A+4, /+/, /+4, 45/, 454
A)=, A)= , 54, 81, 818, 54 , 354, 852, 81 )3@, +,4, 8,4 A)=, A)= , 54, 81, 818, 54 , 354, 852, 81 )3@, +,4, 8,4 -
,8/4 ), A+4, /+/, ,+3T ), 8/), /+4, 45/, +3), T+T 454 ,8/4 7, A+4, /+/, ,+3T 7, 8/7, /+4, 45/, +37, T+T 454 ,8/4 +, ,+3T +, 8/+, +3+ ,8/4 >, ,+3T >, 8/>, +3> ,8/4 T, ,+3T T, ,+T, 8/T, +3T ,8/4 , ,+3T , 8/ , +3
8/4
8/4
>
)3@
81, 818, 81 -
43T
Port details
1ort details o! the most $ommon ports are shown in an e(tra table ;see anne(<.
Avr-Asm-Tutorial
1A
http://www.avr-asm-tutorial.net
What is SRAM?
+4A2 are memories that are not dire$tly a$$essable to the $entral pro$essing unit ;Arithmeti$ and /ogi$al 6nit A/6, sometimes $alled a$$umulator< li%e the registers are. ! you a$$ess these memory lo$ations you usually use a register as interim storage. n the !ollowing e(ample a value in +4A2 will be $opied to the register 42 ;1st $ommand<, a $al$ulation with the value in 4F is made and the result is written to 4F ;$ommand 2<. A!ter that this value is written ba$% to the +4A2 lo$ation ;$ommand F, not shown here<. +o it is $lear that operations with values stored in the +4A2 are slower to per!orm than those using registers alone. 5n the other hand: the smallest A74 type has 12H bytes o! +4A2 available, mu$h more than the F2 registers $an hold. The types !rom AT-0+HA1A upwards o!!er the additional opportunity to $onne$t additional e(ternal 4A2, e(panding the internal A12 bytes. #rom the assembler point-o!-view, e(ternal +4A2 is a$$essed li%e internal +4A2. )o e(tra $ommands must be used !or that e(ternal +4A2.
the +4A2 $ontent at address 0(00B0 is $opied to the register. This is the dire$t a$$ess with an address that has to be de!ined by the programmer. +ymboli$ names $an be used to avoid handling !i(ed addresses, that require a lot o! wor%, i! you later want to $hange the stru$ture o! your data in the +4A2. These names are easier to handle than he( numbers, so give that address a name li%e:
.E#$ MyPreferred*tor)ge"e88 = 0<0060
1B
http://www.avr-asm-tutorial.net
&es, it isn't shorter, but easier to remember. 6se whatever name that you !ind to be $onvenient. Another %ind o! a$$ess to +4A2 is the use o! pointers. &ou need two registers !or that purpose, that hold the 1B-bit address o! the lo$ation. As we learned in the 1ointer-4egister-=ivision pointer registers are the pairs G ;G>:G/, 42D:42B<, & ;&>:&/, 42-:42H< and M ;M>:M/, 4F1:4F0<. They allow a$$ess to the lo$ation they point to dire$tly ;e.g. with +T G, 41<, a!ter prior de$rementing the address by one ;e.g. +T -G, 41< or with subsequent in$rementation o! the address ;e.g. +T GL, 41<. A $omplete a$$ess to three $ells in a row loo%s li%e this:
.E#$ MyPreferred*tor)ge"e88 = 0<0060 .DEF MyPreferredRegister = R1 .DEF AnotherRegister = R! .DEF AndAnotherRegister = R4 LDI H,, ,I-,.MyPreferred*tor)ge"e88/ LDI HL, LO1.MyPreferred*tor)ge"e88/ LD MyPreferredRegister, HG LD AnotherRegister, HG LD AndAnotherRegister, H
3asy to operate, those pointers. And as easy as in other languages than assembler, that $laim to be easier to learn. The third $onstru$tion is a little bit more e(oti$ and only e(perien$ed programmers use this. /et's assume we very o!ten in our program need to a$$ess three +4A2 lo$ations. /et's !uther assume that we have a spare pointer register pair, so we $an a!!ord to use it e($lusively !or our purpose. ! we would use the +T//= instru$tions we always have to $hange the pointer i! we a$$ess another lo$ation. )ot very $onvenient. To avoid this, and to $on!use the beginner, the a$$ess with o!!set was invented. =uring that a$$ess the register value isn't $hanged. The address is $al$ulated by temporarly adding the !i(ed o!!set. n the above e(ample the a$$ess to lo$ation 0(00B2 would loo% li%e this. #irst, the pointer register is set to our $entral lo$ation 0(00B0:
.E#$ MyPreferred*tor)ge"e88 = 0<0060 .DEF MyPreferredRegister = R1 LDI +,, ,I-,.MyPreferred*tor)ge"e88/ LDI +L, LO1.MyPreferred*tor)ge"e88/
)ote that 2 is not really added to &, 9ust temporarly. To $on!use you !urther, this $an only be done with the &- and M-register-pair, not with the G-pointer: The $orresponding instru$tion !or reading !rom +4A2 with an o!!set
LDD MyPreferredRegister, +G!
is also possible. That's it with the +4A2, but wait: the most relevant use as sta$% is still to be learned.
Avr-Asm-Tutorial
1D
http://www.avr-asm-tutorial.net
The value 4A23)= is, o! $ourse, spe$i!i$ !or the pro$essor type. t is de!ined in the )8/6=3 !ile !or the pro$essor type. The !ile HA1Ade!.in$ has the line:
.eJ9 RAME%D =K!5F & L)st On'"hiD *RAM Lo=)tion
at the beginning o! our assembler sour$e $ode. +o we de!ined the sta$% now, and we don't have to $are about the sta$% pointer any more, be$ause manipulations o! that pointer are automati$.
Where that value goes to is totally uninteresting. That the sta$% pointer was de$remented a!ter that push, we don't have to $are. ! we need the $ontent again, we 9ust add the !ollowing instru$tion:
POP MyPreferredRegister & Re)d ()=I the C)89e
With 151 we 9ust get the value that was last pushed on top o! the sta$%. 1ushing and popping registers ma%es sense, i!
the $ontent is again needed some lines o! $ode later, all registers are in use, and i! no other opportunity e(ists to store that value somewhere else.
! these $onditions are not given, the use o! the sta$% !or saving registers is useless and 9ust wastes pro$essor time. 2ore sense ma%es the use o! the sta$% in subroutines, where you have to return to the program lo$ation that $alled the routine. n that $ase the $alling program $ode pushes the return address ;the $urrent program $ounter value< onto the sta$% and 9umps to the subroutine. A!ter its e(e$ution the subroutine pops the return address !rom the sta$% and loads it ba$% into the program $ounter. 1rogram e(e$ution is $ontinued e(a$tly one instru$tion behind the $all instru$tion:
R"ALL *oAe>h)t & L9AD to the 8)(e8 soAe>h)t @...B here >e =ontin9e >ith the Drogr)A.
>ere the 9ump to the label somewhat somewhere in the program $ode, +omewhat: J this is the 9ump address
@...B ,ere >e do soAething @...B )nd >e )re finished )nd >)nt to M9AD ()=I to the =)88ing 8o=)tion? RE;
=uring e(e$ution o! the 48A// instru$tion the already in$remented program $ounter, a 1B-bit-address, is pushed onto the sta$%, using two pushes. ,y rea$hing the 43T instru$tion the $ontent o! the previous program $ounter is reloaded with two pops and e(e$ution $ontinues there. &ou don't need to $are about the address o! the sta$%, where the $ounter is loaded to. This address is automati$ally generated. 3ven i! you $all a subroutine within that subroutine the sta$% !un$tion is !ine. This 9ust pa$%s two return addresses on top o! the sta$%, the nested subroutine removes the !irst one, the $alling subroutine the remaining one. As long as there is enough +4A2, everything is !ine. +ervi$ing hardware interrupts isn't possible without the sta$%. nterrupts stop the normal e(e$tion o! the program, wherever the program $urrently is. A!ter e(e$ution o! a spe$i!i$ servi$e routine as a rea$tion to that interrupt program e(e$ution must return to the previous lo$ation, be!ore the interrupt o$$urred. This would not be possible i! the sta$% is not able to store the return address. The enormous advan$es o! having a sta$% !or interrupts are the reason, why even the smallest A74s without having +4A2 have at least a very small hardware sta$%.
Avr-Asm-Tutorial
1H
http://www.avr-asm-tutorial.net
Another opportunity to $onstru$t bugs is to !orget to pop a previously pushed value, or popping a value without pushing one !irst. n a very !ew $ases the sta$% over!lows to below the !irst +4A2 lo$ation. This happens in $ase o! a neverending re$ursive $all. A!ter rea$hing the lowest +4A2 lo$ation the ne(t pushes write to the ports ;0(00A# down to 0(0020<, then to the registers ;0(001# to 0(0000<. #unny and unpredi$table things happen with the $hip hardware, i! this goes on. Avoid this bug, it $an even destroy your hardware:
Avr-Asm-Tutorial
1-
http://www.avr-asm-tutorial.net
internal $lo$% that must be resetted !rom time to time by the program, otherwise it restarts the pro$essor.
&ou $an $all reset by a dire$t 9ump to that address ;see the 9ump se$tion below<.
The third $ase is not a real reset, be$ause the automati$ resetting o! register- and port-values to a wellde!ined de!ault value is not e(e$uted. +o, !orget that !or now. The se$ond option, the wat$hdog reset, must !irst be enabled by the program. t is disabled by de!ault. 3nabling requires write $ommands to the wat$hdog's port. +etting the wat$hdog $ounter ba$% to *ero requires the e(e$ution o! the $ommand
1DR
to avoid a reset. A!ter e(e$ution o! a reset, with setting registers and ports to de!ault values, the $ode at address 0000 is wordwise read to the e(e$ution part o! the pro$essor and is e(e$uted. =uring that e(e$ution the program $ounter is already in$remented by one and the ne(t word o! $ode is already read to the $ode !et$h bu!!er ;#et$h during 3(e$ution<. ! the e(e$uted $ommand does not require a 9ump to another lo$ation in the program the ne(t $ommand is e(e$uted immediately. That is why the A74s e(e$ute e(tremely !ast, ea$h $lo$% $y$le e(e$utes one $ommand ;i! no 9umps o$$ur<. The !irst $ommand o! an e(e$utable is always lo$ated at address 0000. To tell the $ompiler ;assembler program< that our sour$e $ode starts now and here, a spe$ial dire$tive $an be pla$ed at the beginning, be!ore the !irst $ode in the sour$e is written:
."*E.OR- 0000
The !irst dire$tive lets the $ompiler swit$h to the $ode se$tion. All !ollowing is translated as $ode and is written to the program memory se$tion o! the pro$essor. Another target segment would be the 331452 se$tion o! the $hip, where you also $an write bytes or words to.
.E*E-
5ther than with 331452 $ontent, that really goes to the 331452 during programming o! the $hip, the =+3@ segment $ontent is not programmed to the $hip. t is only used !or $orre$t label $al$ulation during the assembly pro$ess. The 54@ dire$tive above stands !or origin and manipulates the address within the $ode segment, where assembled words go to. As our program always starts at 0(0000 the 8+3@/54@ dire$tives are trivial, you $an s%ip these without getting into an error. We $ould start at 0(0100, but that ma%es no real sense as the pro$essor starts e(e$ution at 0000. ! you want to pla$e a table e(a$tly to a $ertain lo$ation o! the $ode segment, you $an use 54@. ! you want to set a $lear sign within your $ode, a!ter !irst de!ining a lot o! other things with .=3#- and .3P6-dire$tives, use the 8+3@/54@ sequen$e, even though it might not be ne$essary to do that. As the !irst $ode word is always at address *ero, this lo$ation is also $alled the reset ve$tor. #ollowing the reset ve$tor the ne(t positions in the program spa$e, addresses 0(0001, 0(0002 et$., are interrupt ve$tors. These are the positions where the e(e$ution 9umps to i! an e(ternal or internal interrupt has been enabled and o$$urs. These positions $alled ve$tors are spe$i!i$ !or ea$h pro$essor type and depend on the internal hardware available ;see below<. The $ommands to rea$t to su$h an interrupt have to be pla$ed to the proper ve$tor lo$ation. ! you use interrupts, the !irst $ode, at the reset ve$tor, must be a 9ump $ommand, to 9ump over the other ve$tors. 3a$h interrupt ve$tor must hold a 9ump $ommand to the respe$tive interrupt servi$e routine. The typi$al program sequen$e at the beginning is li%e !ollows:
Avr-Asm-Tutorial ."*E.OR- 0000 RLMP *t)rt RLMP Int*erCRo9t1 @...B here >e D8)=e the other interr9Dt Ce=tor =oAA)nds
20
http://www.avr-asm-tutorial.net
@...B )nd here is ) good D8)=e for the interr9Dt serCi=e ro9tines theAse8Ces *t)rt? & ;his here is the Drogr)A st)rt @...B ,ere >e D8)=e o9r A)in Drogr)A
The $ommand 4C21 results in a 9ump to the label +tart:, lo$ated some lines below. 4emeber, labels always start in $olumn 1 o! the sour$e $ode and end with a :. /abels, that don't !ul!il these $onditions are not ta%en !or serious by many $ompiler. 2issing labels result in an error message ;Q6nde!ined labelQ<, and $ompilation is interrupted.
+o that's about it. An easy thing. The opposite $ondition to ,4)3 is ,43P or ,4an$h 3Pual. Whi$h o! the status bits, also $alled pro$essor !lags, are $hanged during e(e$ution o! a $ommand is listed in instru$tion $ode tables, see the /ist o! nstru$tions. +imiliarly to the Mero-bit you $an use the other status bits li%e that:
0R"" 8)(e8N0R"* 8)(e8& ")rry'f8)g 0 oder 1 0R*, 8)(e8& EJ9)8 or gre)ter 0RLO 8)(e8& *A)88er 0RMI 8)(e8& Min9s 0RPL 8)(e8& P89s 0R-E 8)(e8& -re)ter or eJ9)8 .>ith sign (it/ 0RL; 8)(e8& *A)88er .>ith sign (it/ 0R," 8)(e8N0R,* 8)(e8& ,)8f oCerf8o> f8)g 0 or 1 0R;" 8)(e8N0R;* 8)(e8& ;'0it 0 or 1 0R " 8)(e8N0R * 8)(e8& ;>oOs =oAD8eAent f8)g 0 or 1 0RIE 8)(e8N0RID 8)(e8& Interr9Dt en)(8ed or dis)(8ed
to rea$t to the di!!erent $onditions. ,ran$hing always o$$urs i! the $ondition is met. =on't be a!raid, most o! these $ommands are rarely used. #or the beginner only Mero and 8arry are relevant.
Avr-Asm-Tutorial
21
http://www.avr-asm-tutorial.net
&ou might use other instru$tions that do nothing, but more $lever is the use o! the )5 5peration $ommand )51. This is the most useless instru$tion:
%OP
This instru$tion does nothing but wasting pro$essor time. At E 2>* $lo$% we need 9ust !our o! these instru$tions to waste 1 Rs. )o other hidden meanings here on the )51 instru$tion. #or a signal generator with 1 %>* we don't need to add E000 su$h instru$tions to our sour$e $ode, but we use a so!tware $ounter and some bran$hing instru$tions. With these we $onstru$t a loop that e(e$utes !or a $ertain number o! times and are e(a$tly delayed. A $ounter $ould be a H-bit-register that is de$remented with the =38 instru$tion, e.g. li%e this:
"LR R1 "o9nt? DE" R1 0R%E "o9nt
! you use more registers to $onstru$t nested $ounters you $an rea$h any delay. And the delay is absolutely e(a$t, even without a hardware timer.
This de!inition o! the ma$ro does not yet produ$e any $ode, it is silent. 8ode is produ$ed i! you $all that ma$ro by its name:
@...B soAe>here in the so9r=e =ode De8)y1 @...B =ode goes on here
This results in !our )51 in$stru$tions inserted to the $ode at that lo$ation. An additional =elay1 inserts additional !our )51 instru$tions. ,y $alling a ma$ro by its name you $an add some parameters to manipulate the produ$ed $ode. ,ut this is more than a beginner has to %now about ma$ros. ! your ma$ro has longer $ode sequen$es, or i! you are short in $ode storage spa$e, you should avoid the use o! ma$ros and use subroutines instead.
Subroutines
n $ontrary to ma$ros a subroutine does save program storage spa$e. The respe$tive sequen$e is only on$e stored in the $ode and is $alled !rom whatever part o! the $ode. To ensure $ontinued e(e$ution o! the sequen$e !ollowing the subroutine $all you need to return to the $aller. #or a delay o! 10 $y$les you need to write this subroutine:
De8)y10? %OP %OP %OP RE;
+ubroutines always start with a label, otherwise you would not be able to 9ump to it, here =elay10:. Three )51s !ollow and a 43T instru$tion. ! you $ount the ne$essary $y$les you 9ust !ind D $y$les ;F !or the )51s, E !or the 43T<. The missing F are !or $alling that routine:
@...B soAe>here in the so9r=e =ode? R"ALL De8)y10 @...B f9rther on >ith the so9r=e =ode
Avr-Asm-Tutorial
22
http://www.avr-asm-tutorial.net
48A// is a relative $all. The $all is $oded as relative 9ump, the relative distan$e !rom the $alling routine to the subroutine is $al$ulated by the $ompiler. The 43T instru$tion 9umps ba$% to the $alling routine. )ote that be!ore you use subroutine $alls you must set the sta$%pointer ;see +ta$%<, be$ause the return address must be pa$%ed on the sta$% by the 48A// instru$tion. ! you want to 9ump dire$tly to somewhere else in the $ode you have to use the 9ump instru$tion:
@...B soAe>here in the so9r=e =ode RLMP De8)y10 Ret9rn? @...B f9rther on >ith so9r=e =ode
The routine that you 9umped to $an not use the 43T $ommand in that $ase. To return ba$% to the $alling lo$ation in the sour$e requires to add another label and the $alled routine to 9ump ba$% to this label. Cumping li%e this is not li%e $alling a subroutine be$ause you $an't $all this routine !rom di!!erent lo$ations in the $ode. 48A// and 4C21 are un$onditioned bran$hes. To 9ump to another lo$ation, depending on some $ondition, you have to $ombine these with bran$hing instru$tions. 8onditioned $alling o! a subroutine $an best be done with the !ollowing $ommands. ! you want to $all a subroutine depending on a $ertain bit in a register use the !ollowing sequen$e:
*0R" R1,6 & *IiD the ne<t instr9=tion if (it 6 is 0 R"ALL $DL)(e8 & ")88 th)t s9(ro9tine
+,48 reads N+%ip ne(t instru$tion i! ,it D in 4egister 41 is 8lear;Mero<O. The 48A// instru$tion to 6p/abel: is only e(e$uted i! bit D in register 41 is 1, be$ause the ne(t instru$tion is s%ipped i! it would be 0. ! you li%e to $all the subroutine in $ase this bit is 0 then you use the $orresponding instru$tion +,4+. The instru$tion !ollowing +,4+/+,48 $an be a single word or double word instru$tion, the pro$essor %nows how !ar he has to 9ump over it. )ote that e(e$ution times are di!!erent then. To 9ump over more than one !ollowing instru$tion these $ommands $annot be used. ! you have to s%ip an instru$tion i! two registers have the same value you $an use the !ollowing e(oti$ instru$tion
"P*E R1,R! & "oAD)re R1 )nd R!, sIiD if eJ9)8 R"ALL *oAe*9(ro9tine & ")88 *oAe*9(ro9tine
A rarely used $ommand, !orget it !or the beginning. ! you li%e to s%ip the !ollowing instru$tion depending on a $ertain bit in a port use the !ollowing instru$tions +, 8 und +, +. That reads +%ip i! the ,it in /o spa$e is 8lear ;or +et<, li%e this:
*0I" PI%0,0 & *IiD if 0it 0 on Dort 0 is 0 RLMP A;)rget & L9AD to the 8)(e8 A;)rget
The 4C21-instru$tion is only e(e$uted i! bit 0 in port , is high. This is something $on!using !or the beginner. The a$$ess to the port bits is limited to the lower hal! o! ports, the upper F2 ports are not usable here. )ow, another e(oti$ appli$ation !or the e(pert. +%ip this i! you are a beginner. Assume we have a bit swit$h with E swit$hes $onne$ted to port ,. =epending on the state o! these E bits we would li%e to 9ump to 1B di!!erent lo$ations in the $ode. )ow we $an read the port and use several bran$hing instru$tions to !ind out, where we have to 9ump to today. As alternative you $an write a table holding the 1B addresses, li%e this:
My;)(? RLMP Ro9tine1 RLMP Ro9tine! @...B RLMP Ro9tine16
n our $ode we $opy that adress o! the table to the M pointer register:
LDI 2,,,I-,.My;)(/ LDI 2L,LO1.My;)(/
and add the $urrent state o! the port , ;in 41B< to this address.
ADD 2L,R16 0R"" %oOCerf8o> I%" 2, %oOCerf8o>?
)ow we $an 9ump to this lo$ation in the table, either !or $alling a subroutine:
I"ALL
The pro$essor loads the $ontent o! the M register pair into its program $ounter and $ontinues operation there. 2ore $lever than bran$hing over and over"
Avr-Asm-Tutorial
2F
http://www.avr-asm-tutorial.net
! the interrupting $ondition o$$urs, e.g. a $hange on the port bit, the pro$essor pushes the a$tual program $ounter to the sta$% ;whi$h must be enabled !irst: +ee initiation o! the sta$%pointer in the +ta$% se$tion o! the +4A2 des$ription<. Without that the pro$essor wouldn't be able to return ba$% to the lo$ation, where the interrupt o$$urred ;whi$h $ould be any time and anywhere within program e(e$ution<. A!ter that, pro$essing 9umps to the prede!ined lo$ation, the interrupt ve$tor, and e(e$utes the instru$tions there. 6sually the instru$tion there is a C621 instru$tion to the interrupt servi$e routine, lo$ated somewhere in the $ode. The interrupt ve$tor is a pro$essor-spe$i!i$ lo$ation and depending !rom the hardware $omponent and the $ondition that leads to the interrupt. The more hardware $omponents and the more $onditions, the more ve$tors. The di!!erent ve$tors !or some o! the A74 types are listed in the !ollowing table. ;The !irst ve$tor isn't an interrupt but the reset ve$tor, per!orming no sta$% operation:< Name 43+3T )T0 )T1 T 23418A1T T 23418521A T 2341 8521, T 2341 85211 T 2341 57# T 2340 57# +1 +T8 6A4T TG 6A4T 6=43 6A4T TG A)AS8521 Interrupt Vector !ress "#$# 0000 0001 0002 000F 000E 000A 000B 000D 000H 000"#"# 0000 0001 0002 %&$& 0000 0001 0002 000F 000E 000A 000B 000D 000H 000000A 000, 0008 >ardware 4eset, 1ower-5n-4eset, Wat$hdog 4eset /evel $hange on the e(ternal )T0 pin /evel $hange on the e(ternal )T1 pin 8apture event on Timer/8ounter 1 Timer/8ounter 1 K 8ompare value A Timer/8ounter 1 K 8ompare value , Timer/8ounter 1 K 8ompare value 1 Timer/8ounter 1 5ver!low Timer/8ounter 0 5ver!low +erial Transmit 8omplete 6A4T $har in re$eive bu!!er available 6A4T transmitter ran empty 6A4T All +ent Analog 8omparator 'riggere! ()
)ote that the $apability to rea$t to events is very di!!erent !or the di!!erent types. The addresses are sequential, but not identi$al !or di!!erent types. 8onsult the data sheet !or ea$h A74 type. The higher a ve$tor in the list the higher is its priority. ! two or more $omponents have an interrupt $ondition pending at the same time, the upmost ve$tor with the lower ve$tor address wins. The lower int has to wait until the upper int was served. To disable lower ints !rom interrupting during the e(e$ution o! its servi$e routine the !irst e(e$uted int disables the pro$essor's -!lag. The servi$e routine must re-enable this !lag a!ter it is done with its 9ob. #or re-setting the status bit there are two ways. The servi$e routine $an end with the $ommand:
RE;I
This return !rom the int routine restores the -bit a!ter the return address has been loaded to the program $ounter. The se$ond way is to enable the -bit by the instru$tion
*EI & *et Interr9Dt En)(8ed RE; & Ret9rn
This is not the same as the 43T , be$ause subsequent interrupts are already enabled be!ore the program
Avr-Asm-Tutorial
2E
http://www.avr-asm-tutorial.net
$ounter is re-loaded with the return address. ! another int is pending, its e(e$ution is already starting be!ore the return address is popped !rom the sta$%. Two or more nested addresses remain on the sta$%. )o bug is to be e(pe$ted, but it is an unne$essary ris% doing that. +o 9ust use the 43T instru$tion to avoid this unne$essary !low to the sta$%. An nt-ve$tor $an only hold a relative 9ump instru$tion to the servi$e routine. ! a $ertain interrupt is not used or unde!ined we $an 9ust put a 43T instru$tion there, in $ase a !alse int happens. n a !ew $ases it is absolutely ne$essary to rea$t to these !alse ints. That is the $ase i! the e(e$ution o! the respe$tive servi$e routine does not automati$ally reset the interrupt $ondition !lag o! the peripheral. n that $ase a simple 43T would reset in never-ending interrupts. This is the $ase with some o! the 6A4T interrupts. As, a!ter an interrupt is under servi$e, !urther e(e$ution o! lower-priority ints is blo$%ed, all int servi$e routines should be as short as possible. ! you need to have a longer routine to serve the int, use one o! the two !ollowing methods. The !irst is to allow ints by +3 within the servi$e routine, whenever you're done with the most urgent tas%s. )ot very $lever. 2ore $onvenient is to per!orm the urgent tas%s, setting a !lag somewhere in a register !or the slower rea$tions and return !rom the int immediately. A very serious rule !or int servi$e routines is: #irst instru$tion is always to save the status register on the sta$%, be!ore you use instru$tions that might $hange !lags in the status register. The interrupted main program might 9ust be in a state using the !lag !or a bran$h de$ision, and the int would 9ust $hange that !lag to another state. #unny things would happen !rom time to time. The last instru$tion be!ore the 43T there!ore is to pop the status register $ontent !rom the sta$% and restore its original $ontent. #or the same reason all used registers in a servi$e routine should either be e($lusively reserved !or that purpose or saved on sta$% and restored at the end o! the servi$e routine. )ever $hange the $ontent o! a register within an int servi$e routine that is used somewhere else in the normal program without restoring it. ,e$ause o! these basi$ requirements a more sophisti$ated e(ample !or an interrupt servi$e routine here.
."*E- & "ode'*egAent st)rts here .OR- 0000 & Address is Fero RLMP *t)rt & ;he reset'Ce=tor on Address 0000 RLMP I*erCi=e & 0001? first Int' eItor, I%;0 serCi=e ro9tine @...B here other Ce=tors *t)rt? & ,ere the A)in Drogr)A st)rts @...B here is eno9gh sD)=e for defining the st)=I )nd other things I*erCi=e? & ,ere >e st)rt >ith the Interr9Dt'*erCi=e'Ro9tine P$*, R16 & s)Ce ) register to st)=I I% R16,*RE- & re)d st)t9s register P$*, R16 & )nd D9t on st)=I @...B ,ere the Int'*erCi=e'Ro9tine does soAething )nd 9ses R16 POP R16 & get DreCio9s f8)g register froA st)=I O$; *RE-,R16 & restore o8d st)t9s POP R16 & get DreCio9s =ontent of R16 froA the st)=I RE;I & )nd ret9rn froA int
/oo%s a little bit $ompli$ated, but is a prerequisite !or using ints without produ$ing serious bugs. +%ip 16+> 41B and 151 41B i! you $an a!!ord reserving the register !or e($lusive use in the servi$e routine. As an interrupt servi$e routine $annot be interrupted ;unless you allow interrupts within the routine<, all di!!erent int servi$e routines $an use the same register. That's it !or the beginner. There are some other things with ints, but this is enough to start with, and not to $on!use you.
Avr-Asm-Tutorial
2A
http://www.avr-asm-tutorial.net
Calculations
>ere we dis$uss all ne$essary $ommands !or $al$ulating in A74 assembler language. This in$ludes number systems, setting and $learing bits, shi!t and rotate, and adding/subtra$ting/$omparing and the !ormat $onversion o! numbers.
dw0 to dwF are in a row in the registers. ! we need to initiate this double word at the beginning o! an appli$ation ;e.g. to E,000,000<, this should loo% li%e this:
.E#$ d>i = 5000000 & define the =onst)nt LDI d>0,LO1.d>i/ & ;he 8o>est 7 (its to R16 LDI d>1,0+;E!.d>i/ & (its 7 .. 15 to R16 LDI d>!,0+;E4.d>i/ & (its 16 .. !4 to R17 LDI d>4,0+;E5.d>i/ & (its !5 .. 41 to R19
+o we have splitted this de$imal number, $alled dwi, to its binary portions and pa$%ed them into the !our byte pa$%ages. )ow you $an $al$ulate with this double word.
Avr-Asm-Tutorial
2B
http://www.avr-asm-tutorial.net
$"% 0 0 0
+, 0 0 0
#" 0 0 0
$+ 0 0 0
% 0 0 0
, 0 1 0
" 1 0 0
$ 0 1 0
&ou $an $al$ulate with these numbers, but this is a bit more $ompli$ated in assember than $al$ulating with binary values. The advantage o! this !ormat is that you $an handle as long numbers as you li%e, as long as you have enough storage spa$e. The $al$ulations are as pre$ise as you li%e ;i! you program A74s !or ban%ing appli$ations<, and you $an $onvert them very easily to $hara$ter strings.
Packed BCDs
! you pa$% two de$imal digits into one byte you don't loose that mu$h storage spa$e. This method is $alled pa$%ed binary $oded digits. The two parts o! a byte are $alled upper and lower nibble. The upper nibble usually holds the more signi!i$ant digit, whi$h has advantages in $al$ulations ;spe$ial instru$tions in A74 assembler language<. The de$imal number 2A0 would loo% li%e this when !ormatted as a pa$%ed ,8=: B)te 2 1 -igits ETF 2T1 Value 02 A0 % 0 0 , 0 1 " 0 0 $ 0 1 % 0 0 , 0 0 " 1 0 $ 0 0
& Instr9=tions for setting? LDI R16,0<0! & $DDer (yte LDI R16,0<50 & Lo>er (yte
To set this $orre$t you $an use the binary notation ;0b...< or the he(ade$imal notation ;0(...< to set the proper bits to their $orre$t nibble position. 8al$ulating with pa$%ed ,8=s is a little more $ompli$ated $ompared to the binary !orm. #ormat $hanges to $hara$ter strings are as easy as with ,8=s. /ength o! numbers and pre$ision o! $al$ulations is only limited by the storage spa$e.
Numbers in ASCII-format
7ery similiar to the unpa$%ed ,8= !ormat is to store numbers in A+8 !ormat. The digits 0 to - are stored using their A+8 ;A+8 K Ameri$an +tandard 8ode !or n!ormation nter$hange< representation. A+8 is a very old !ormat, develloped and optimi*ed !or teletype writers, unne$essarily very $ompli$ated !or $omputer use ;do you %now what a $har named 3nd 5! Transmission 35T meant when it was invented"<, very limited in range !or other than 6+ languages ;only D bits per $hara$ter<, still used in $ommuni$ations today due to the limited e!!orts o! some operating system programmers to swit$h to more e!!e$tive $hara$ter systems. This an$ient system is only topped by the european A-bit long teletype $hara$ter set $alled ,audot set or the still used 2orse $ode. Within the A+8 $ode system the de$imal digit 0 is represented by the number EH ;he( 0(F0, binary 0b0011.0000<, digit - is AD de$imal ;he( 0(F-, binary 0b0011.1001<. A+8 wasn't designed to have these numbers on the beginning o! the $ode set as there are already $ommand $hars li%e the above mentioned 35T !or the teletype. +o we still have to add EH to a ,8= ;or set bit E and A to 1< to $onvert a ,8= to A+8 . A+8 !ormatted numbers need the same storage spa$e li%e ,8=s. /oading 2A0 to a register set representing that number would loo% li%e this:
LDI R17,O!O LDI R16,O5O LDI R16,O0O
Bit manipulations
To $onvert a ,8= $oded digit to its A+8 representation we need to set bit E and A to a one. n other words we need to 54 the ,8= with a $onstant value o! he( 0(F0. n assembler this is done li%e this:
ORI R16,0<40
! we have a register that is already set to he( 0(F0 we $an use the 54 with this register to $onvert the ,8=:
Avr-Asm-Tutorial OR R1,R!
2D
http://www.avr-asm-tutorial.net
isolates the lower !our bits ;K the lower nibble<. )ote that 54 and A)= are only possible with registers above 41A. ! you need to do this, use one o! the registers 41B to 4F1: ! the he( value 0(0# is already in register 42, you $an A)= the A+8 $hara$ter with this register:
A%D R1,R!
The other instru$tions !or manipulating bits in a register are also limited !or registers above 41A. They would be !ormulated li%e this:
*0R R16,0(00110000 & *et (its 5 9nd 5 to one "0R R16,0(00110000 & "8e)r (its 5 )nd 5 to Fero
! one or more bits o! a byte have to be inverted you $an use the !ollowing instru$tion ;whi$h is not possible !or use with a $onstant<:
LDI R16,0(10101010 & InCert )88 eCen (its EOR R1,R16 & in register R1 )nd store res98t in R1
inverts the $ontent in register 41 and repla$es *eros by one and vi$e versa. =i!!erent !rom that is the Two's $omplement, whi$h $onverts a positive signed number to its negative $omplement ;subtra$ting !rom *ero<. This is done with the instru$tion
%E- R1
+o L1 ;de$imal: 1< yields -1 ;binary 1.1111111<, L2 yields -2 ;binary 1.1111110<, and so on. ,esides the manipulation o! the bits in a register, $opying a single bit is possible using the so-$alled T-bit o! the status register. With
0LD R1,0
the T-bit is loaded with a $opy o! bit 0 in register 41. The T-bit $an be set or $leared, and its $ontent $an be $opied to any bit in any register:
"L; & =8e)r ;'(it, or *E; & set ;'(it, or 0*; R!,! & =oDy ;'(it to register R!, (it !
The !ormer bit D, now shi!ted to bit B, is !illed with a 0, while the !ormer bit 0 is shi!ted into the $arry bit o! the status register. This $arry bit $ould be used to round up and down ;i! set, add one to the result<. 3(ample, division by !our with rounding:
L*R R1 & diCision (y ! 0R"" DiC! & L9AD if no ro9nd 9D I%" R1 & ro9nd 9D DiC!? L*R R1 & On=e )g)in diCision (y ! 0R"" DiCE & L9AD if no ro9nd 9D I%" R1 & Ro9nd $D DiCE?
+o, dividing is easy with binaries as long as you divide by multiples o! 2. ! signed integers are used the logi$al shi!t right would overwrite the sign-bit in bit D. The instru$tion Narithmeti$ shi!t rightO A+4 leaves bit D untou$hed and shi!ts the D lower bits, inserting a *ero into bit lo$ation B.
Avr-Asm-Tutorial A*R R1
2H
http://www.avr-asm-tutorial.net
/i%e with logi$al shi!ting the !ormer bit 0 goes to the $arry bit in the status register. What about multiplying a 1B-bit word by 2" The most signi!i$ant bit o! the lower byte has to be shi!ted to yield the lowest bit o! the upper byte. n that step a shi!t would set the lowest bit to *ero, but we need to shi!t the $arry bit !rom the previous shi!t o! the lower byte into bit 0. This is $alled a rotate. =uring rotation the $arry bit in the status register is shi!ted to bit 0, the !ormer bit D is shi!ted to the $arry during rotation.
L*L R1 & Logi=)8 *hift Left of the 8o>er (yte ROL R! & ROt)te Left of the 9DDer (yte
The logi$al shi!t le!t in the !irst instru$tion shi!ts bit D to $arry, the 45/ instru$tion rolls it to bit 0 o! the upper byte. #ollowing the se$ond instru$tion the $arry bit has the !ormer bit D. The $arry bit $an be used to either indi$ate an over!low ;i! 1B-bit-$al$ulation is per!ormed< or to roll it into upper bytes ;i! more than 1B bit $al$ulation is done<. 4olling to the right is also possible, dividing by 2 and shi!ting $arry to bit D o! the result:
L*R R! & Logi=)8 *hift Right, (it 0 to =)rry ROR R1 & ROt)te Right )nd shift =)rry in (it 6
t's easy dividing with big numbers. &ou see that learning assembler is not T>AT $ompli$ated. The last instru$tion that shi!ts !our bits in one step is very o!ten used with pa$%ed ,8=s. This instru$tion shi!ts a whole nibble !rom the upper to the lower position and vi$e versa. n our e(ample we need to shi!t the upper nibble to the lower nibble position. nstead o! using
ROR R1 ROR R1 ROR R1 ROR R1
This instru$tion e($hanges the upper and lower nibble. )ote that the upper nibble's $ontent will be di!!erent a!ter applying these two methods.
nstead o! a se$ond A== we use A=8 in the se$ond instru$tion. That means add with $arry, whi$h is set or $leared during the !irst instru$tion, depending !rom the result. Already s$ared enough by that $ompli$ated math" ! not: ta%e this: We subtra$t 4F:4E !rom 41:42.
*$0 R!,R5 & first the 8o>'(yte *0" R1,R4 & then the high'(yte
Again the same tri$%: during the se$ond instru$tion we subra$t another 1 !rom the result i! the result o! the !irst instru$tion had an over!low. +till breathing" ! yes, handle the !ollowing: )ow we $ompare a 1B-bit-word in 41:42 with the one in 4F:4E to evaluate whether it is bigger than the se$ond one. nstead o! +6, we use the $ompare instru$tion 81, instead o! +,8 we use 818:
"P R!,R5 & =oAD)re 8o>er (ytes "P" R1,R4 & =oAD)re 9DDer (ytes
! the $arry !lag is set now, 41:42 is bigger than 4F:4E. )ow we add some more $ompli$ated stu!!. We $ompare the $ontent o! 41B with a $onstant: 0b10101010.
"PI R16,0<AA
! the Mero-bit in the status register is set a!ter that, we %now that 41B is 0(AA. ! the $arry-bit is set, we %now, it is smaller. ! 8arry is not set and the Mero-bit is not set either, we %now it is bigger. And now the most $ompli$ated test. We evaluate whether 41 is *ero or negative:
;*; R1
! the M-bit is set, the register 41 is *ero and we $an !ollow with the instru$tions ,43P, ,4)3, ,42 ,
Avr-Asm-Tutorial
2-
http://www.avr-asm-tutorial.net
,41/, ,4/5, ,4+>, ,4@3, ,4/T, ,478 or ,47+ to bran$h around a bit. +till with us" ! yes, here is some pa$%ed ,8= $al$ulations. Adding two pa$%ed ,8=s $an result in two di!!erent over!lows. The usual $arry shows an over!low, i! the higher o! the two nibbles over!lows to more than 1A de$imal. Another over!low, !rom the lower to the upper nibble o$$urs, i! the two lower nibbles add to more than 1A de$imal. To ta%e an e(ample we add the pa$%ed ,8=s E- ;Khe( E-< and -- ;Khe( --< to yield 1EH ;Khe( 0(01EH<. Adding these in binary math, results in a byte holding he( 0(32, no byte over!low o$$urs. The lower o! the two nibbles should have an over!low, be$ause -L-K1H ;more than -< and the lower nibble $an only handle numbers up to 1A. The over!low was added to bit E, the lowest signi!i$ant bit o! the upper nibble. Whi$h is $orre$t: ,ut the lower nibble should be H and is only 2 ;1H K 0b0001.0010<. We should add B to that nibble to yield a $orre$t result. Whi$h is quite logi$, be$ause whenever the lower nibble rea$hes more than - we have to add B to $orre$t that nibble. The upper nibble is totally in$orre$t, be$ause it is 0(3 and should be F ;with a 1 over!lowing to the ne(t upper digit o! the pa$%ed ,8=<. ! we add B to this 0(3 we get to 0(E and the $arry is set ;K0(1E<. +o the tri$% is to !irst add these two numbers and then add 0(BB to $orre$t the 2 digits o! the pa$%ed ,8=. ,ut halt: what i! adding the !irst and the se$ond number would not result in an over!low to the ne(t nibble" And not result in a digit above - in the lower nibble" Adding 0(BB would then result in a totally in$orre$t result. The lower B should only be added i! the lower nibble either over!lows to the upper nibble or results in a digit greater than -. The same with the upper nibble. >ow do we %now, i! an over!low !rom the lower to the upper nibble has o$$urred" The 286 sets the >-bit in the status register, the hal!-$arry bit. The !ollowing shows the algorithm !or the di!!erent $ases that are possible a!ter adding two nibbles and adding he( 0(B a!ter that. 1.Add the nibbles. ! over!low o$$urs ;8 !or the upper nibbles, or > !or the lower nibbles<, add B to $orre$t, i! not, do step 2. 2.Add B to the nibble. ! over!low o$$urs ;8 resp. ><, you're done. ! not, subtra$t B. To program an e(ample we assume that the two pa$%ed ,8=s are in 42 and 4F, 41 will hold the over!low, and 41B and 41D are available !or $al$ulations. 41B is the adding register !or adding 0(BB ;the register 42 $annot add a $onstant value<, 41D is used to $orre$t the result depending !rom the di!!erent !lags. Adding 42 and 4F goes li%e that:
LDI R16,0<66 & for )dding 0<66 to the res98t LDI R16,0<66 & for 8)ter s9(tr)=ting froA the res98t ADD R!,R4 & )dd the t>o t>o'digit'0"Ds 0R"" %o"y1 & M9AD if no (yte oCerf8o> o==9rs I%" R1 & in=reAent the ne<t higher (yte A%DI R16,0<0F & donOt s9(tr)=t 6 froA the higher ni((8e %o"y1? 0R," %o,=1 & M9AD if no h)8f'=)rry o==9red A%DI R16,0<F0 & donOt s9(tr)=t 6 froA 8o>er ni((8e %o,=1? ADD R!,R16 & )dd 0<66 to res98t 0R"" %o"y! & M9AD if no =)rry o==9red I%" R1 & in=reAent the ne<t higher (yte A%DI R16,0<0F & donOt s9(tr)=t 6 froA higher ni((8e %o"y!? 0R," %o,=! & M9AD if no h)8f'=)rry o==9red A%DI R16,0<F0 & donOt s9(tr)=t 6 froA 8o>er ni((8e %o,=!? *$0 R!,R16 & s9(tr)=t =orre=tion
Puestion to thin% about: Why is that equally $orre$t, hal! as long and $ompli$ated and where is the tri$%"
Avr-Asm-Tutorial
F0
http://www.avr-asm-tutorial.net
the lower one. The upper part is $leared, e.g. by A)=ing with 0(0#. )ow we have the ,8= o! the upper nibble and we $an either use as is ;,8=< or set bit E and A to $onvert it to an A+8 $hara$ter. A!ter that we $opy the byte again and treat the lower nibble without !irst +WA1ping and get the lower ,8=. A little bit more $ompli$ated is the $onversion o! ,8= digits to a binary. =epending on the numbers to be handled we !irst $lear the ne$essary bytes that will hold the result o! the $onversion. We then start with the highest ,8= digit. ,e!ore adding this to the result we multiply the result with 10. ;)ote that in the !irst step this is not ne$essary, be$ause the result is *ero either<. n order to do the multipli$ation by 10, we $opy the result to somewhere else. Then we multiply the result by !our ;two le!t shi!ts resp. rolls<. Adding the previously $opied number to this yields a multipli$ation with A. )ow a mulitipli$ation with 2 ;le!t shi!t/roll< yields the 10-!old o! the result. #inally we add the ,8= and repeat that algorithm until all de$imal digits are $onverted. !, during one o! these operations, there o$$urs a $arry o! the result, the ,8= is too big to be $onverted. This algorithm handles numbers o! any length, as long as the result registers are prepared. The $onversion o! a binary to ,8=s is more $ompli$ated than that. ! we $onvert a 1B-bit-binary we $an subtra$t 10,000 ;0(2D10<, until an over!low o$$urs, yielding the !irst digit. Then we repeat that with 1,000 ;0(0F3H< to yield the se$ond digit. And so on with 100 ;0(00BE< and 10 ;0(000A<, then the remainder is the last digit. The $onstants 10,000, 1,000, 100 and 10 $an be pla$ed to the program memory storage in a wordwise organised table, li%e this:
DeF;)(? .D1 10000, 1000, 100, 10
and $an be read wordwise with the /12 instru$tion !rom the table. An alternative is a table that holds the de$imal value o! ea$h bit in the 1B-bit-binary, e.g.
.D0 .D0 .D0 .D0 .D0 .D0 0,4,!,6,6,7 0,1,6,4,7,5 0,0,7,1,9,! 0,0,5,0,9,6 0,0,!,0,5,7 & )nd so on 9nti8 0,0,0,0,0,1
Then you shi!t the single bits o! the binary le!t out o! the registers to the $arry. ! it is a one, you add the number in the table to the result by reading the numbers !rom the table using /12. This is more $ompli$ated to program and a little bit slower than the above method. A third method is to $al$ulate the table value, starting with 000001, by adding this ,8= with itsel!, ea$h time a!ter you have shi!ted a bit !rom the binary to the right and added the ,8=. 2any methods, mu$h to optimi*e here.
Multiplication
2ultipli$ation o! binary numbers is e(plained here.
Decimal multiplication
n order to multiply two H-bit-binaries we remind ourselves, how this is done with de$imal numbers: 1234 * 567 = ? -----------------------1234 * + + 1234 * 7 = 60 = 8638 74040 617000
1234 * 500 =
699678
========================
result.
We multiply the !irst number by 10 and then by the ne(t higher digit o! the se$ond number and add to
the result.
We multiply the !irst number by 100, then with the third-highest digit, and add this to the result.
Binary multiplication
)ow in binary. 2ultipli$ation with the single digits is not ne$essary, be$ause there are only the digits 1
Avr-Asm-Tutorial
F1
http://www.avr-asm-tutorial.net
;add the number< and 0 ;don't add the number<. 2ultipli$ation by 10 in de$imal goes to multipli$ation by 2 in binary mode. 2ultipli$ation by 2 is done easily, either by adding the number with itsel!, or by shi!ting all bits one position le!t and writing a 0 to the void position on the right. &ou see that binary math is very mu$h easier than de$imal. Why didn't man%ind use this !rom the beginning"
AVR-Assembler program
The !ollowing sour$e $ode demonstrates realisation o! multipli$ation in assembler.
& M98t7.)sA A98tiD8ies t>o 7'(it'n9A(ers to yie8d ) 16'(it'res98t & .%OLI*; .I%"L$DE :"?E)Crtoo8sE)DDnotesE7515def.in=: .LI*; & & F8o> of A98tiD8i=)tion & & 1.;he (in)ry to (e A98tiD8i=)ted >ith, is shifted (it>ise into the =)rry (it. If it is ) one, the (in)ry n9A(er is )dded to the & res98t, if it is not ) one th)t >)s shifted o9t, the n9A(er is not )dded & !.;he (in)ry n9A(er is A98tiD8ied (y ! (y rot)ting it one Dosition 8eft, shifting ) 0 into the Coid Dosition. & 4.If the (in)ry to (e A98tiD8ied >ith, is not Fero, the A98tiD8i=)tion 8ooD is reDe)ted. If it is Fero, the A98tiD8i=)tion is done. & & $sed registers & .DEF rA1 = R0 & 0in)ry n9A(er to (e A98tiD8i=)ted .7 0it/ .DEF rAh = R1 & InteriA stor)ge .DEF rA! = R! & 0in)ry n9A(er to (e A98tiD8i=)ted >ith .7 0it/ .DEF re8 = R4 & Res98t, L*0 .16 0it/ .DEF reh = R5 & Res98t, M*0 .DEF rAD = R16 & M98ti D9rDose register for 8o)ding & ."*E.OR- 0000 & rMAD *;AR; & *;AR;? 8di rAD,0<AA & e<)AD8e (in)ry 1010.1010 AoC rA1,rAD & to the first (in)ry register 8di rAD,0<55 & e<)AD8e (in)ry 0101.0101 AoC rA!,rAD & to the se=ond (in)ry register & & ,ere >e st)rt >ith the A98tiD8i=)tion of the t>o (in)ries in rA1 9nd rA!, the res98t >i88 go to reh?re8 .16 0it/ & M$L;7? & & "8e)r st)rt C)89es =8r rAh & =8e)r interiA stor)ge =8r re8 & =8e)r res98t registers =8r reh & & ,ere >e st)rt >ith the A98tiD8i=)tion 8ooD & M$L;7)? & & *teD 1? Rot)te 8o>est (it of (in)ry n9A(er ! to the =)rry f8)g .diCide (y !, rot)te ) Fero into (it 6/ & =8= & =8e)r =)rry (it ror rA! & (it 0 to =)rry, (it 1 to 6 one Dosition to the right, =)rry (it to (it 6 & & *teD !? 0r)n=h deDending if ) 0 or 1 h)s (een rot)ted to the =)rry (it & (r== M$L;7( & M9AD oCer )dding, if =)rry h)s ) 0 & & *teD 4? Add 16 (its in rAh?rA8 to the res98t, >ith oCerf8o> froA L*0 to M*0 & )dd re8,rA1 & )dd L*0 of rA1 to the res98t )d= reh,rAh & )dd =)rry )nd M*0 of rA1 & M$L;7(? & & *teD 5? M98tiD8y rAh?rA1 (y ! .16 (its, shift 8eft/ & =8= & =8e)r =)rry (it ro8 rA1 & rot)te L*0 8eft .A98tiD8y (y !/ ro8 rAh & rot)te =)rry into M*0 )nd M*0 one 8eft & & *teD 5? "he=I if there )re sti88 oneOs in (in)ry !, if yes, go on A98tiD8i=)ting & tst rA! & )88 (its FeroP (rne M$L;7) & if not, go on in the 8ooD &
Avr-Asm-Tutorial & End of the A98tiD8i=)tion, res98t in reh?re8 & & End8ess 8ooD & LOOP? rMAD 8ooD
F2
http://www.avr-asm-tutorial.net
Binary rotation
#or understanding the multipli$ation operation, it is ne$essary to understand the binary rotation $ommands 45/ and 454. These instru$tions shi!t all bits o! a register one position le!t ;45/< resp. right ;454<. The void position in the register is !illed with the $ontent o! the $arry bit o! the status register, the bit that rolls out o! the register is shi!ted to the $arry bit. This operation is demonstrated using 0(AA as an e(ample !or 45/ and 0(AA as an e(ample !or 454.
The ob9e$t-$ode has been opened, the $ursor is pla$ed on the !irst e(e$utable instru$tion. #11 does single steps.
The registers 40 and 42 are set to 0(AA and 0(AA, our test binaries, to be multiplied.
Avr-Asm-Tutorial
FF
http://www.avr-asm-tutorial.net
42 is rotated to the right, to roll the least signi!i$ant bit into the $arry bit. 0(AA ;0101.0101< yielded 0(2A ;0010.1010<.
,e$ause the $arry bit had a one the $ontent o! the registers 41:40 is added to the ;empty< register pair 4E:4F, resulting in 0(00AA there.
)ow the register pair 41:40 is rotated one position le!t to multiply this binary by 2. #rom 0(00AA, multipli$ation by 2 yields 0(01AE. The whole multipli$ation loop is repeated as long there is at least one binary 1 in register 42. These !ollowing loops are not shown here.
Avr-Asm-Tutorial
FE
http://www.avr-asm-tutorial.net
6sing %ey #A o! the studio we multistepped over these loops to a brea%point at the end o! the multipli$ation routine. The result register pair 4E:4F has the result o! the multipli$ation o! 0(AA by 0(AA: 0(FHD2.
This wasn't that $ompli$ated, 9ust remind yoursel! on the similiar de$imal operations. ,inary multipli$ation is mu$h easier than de$imal.
Division
Decimal division
Again we start with the de$imal division, to better understand the binary division. We assume a division o! ABDH by 12. This is done li%e this: 5678 : 12 = ? -------------------------- 4 * 1200 = 4800 ---878 - 7 * 120 = 840 --38 - 3 * 12 = 36 -2 Result: 5678 : 12 = 473 Remainder 2 ===================================
Binary division
n binary the multipli$ation o! the se$ond number ;E U 1200, et$.< is not ne$essary, due to the !a$t that we have only 0 and 1 as digits. 6n!ortunately binary numbers have mu$h more single digits than their de$imal equivalent, so trans!erring the de$imal division to its binary equivalent is a little bit in$onvenient. +o the program wor%s a bit di!!erent than that. The division o! a 1B-bit binary number by a H-bit binary in A74 assembler is listed in the !ollowing se$tion.
& DiC7 diCides ) 16'(it'n9A(er (y ) 7'(it'n9A(er .;est? 16'(it'n9A(er? 0<AAAA, 7'(it'n9A(er? 0<55/ .%OLI*; .I%"L$DE :"?E)Crtoo8sE)DDnotesE7515def.in=: .LI*; & Registers .DEF rd18 = R0 & L*0 16'(it'n9A(er to (e diCided .DEF rd1h = R1 & M*0 16'(it'n9A(er to (e diCided .DEF rd19 = R! & interiA register .DEF rd! = R4 & 7'(it'n9A(er to diCide >ith .DEF re8 = R5 & L*0 res98t .DEF reh = R5 & M*0 res98t .DEF rAD = R16& A98tiD9rDose register for 8o)ding & ."*E.OR- 0 rMAD st)rt
Avr-Asm-Tutorial
FA
http://www.avr-asm-tutorial.net
st)rt? & Lo)d the test n9A(ers to the )DDroDri)te registers 8di rAD,0<AA & 0<AAAA to (e diCided AoC rd1h,rAD AoC rd18,rAD 8di rAD,0<55 & 0<55 to (e diCided >ith AoC rd!,rAD & DiCide rd1h?rd18 (y rd! diC7? =8r rd19 & =8e)r interiA register =8r reh & =8e)r res98t .the res98t registers =8r re8 & )re )8so 9sed to =o9nt to 16 for the in= re8 & diCision steDs, is set to 1 )t st)rt/ & ,ere the diCision 8ooD st)rts diC7)? =8= & =8e)r =)rry'(it ro8 rd18 & rot)te the ne<t'9DDer (it of the n9A(er ro8 rd1h & to the interiA register .A98tiD8y (y !/ ro8 rd19 (r=s diC7( & ) one h)s ro88ed 8eft, so s9(tr)=t =D rd19,rd! & DiCision res98t 1 or 0P (r=s diC7= & M9AD oCer s9(tr)=tion, if sA)88er diC7(? s9( rd19,rd!& s9(tr)=t n9A(er to diCide >ith se= & set =)rry'(it, res98t is ) 1 rMAD diC7d & M9AD to shift of the res98t (it diC7=? =8= & =8e)r =)rry'(it, res98ting (it is ) 0 diC7d? ro8 re8 & rot)te =)rry'(it into res98t registers ro8 reh (r== diC7) & )s 8ong )s Fero rot)te o9t of the res98t registers? go on >ith the diCision 8ooD & End of the diCision re)=hed stoD? rMAD stoD & end8ess 8ooD
0(0001: A!ter 1B rotations the rolling out o! the one stops !urther division steps.<,
the 1B-bit-binary in rd1h:rd1l is rotated bitwise to the interim register rd1u ;multipli$ation by 2<, i! a 1
is rotated out o! rd1u, the program bran$hes to the subtra$tion step in step E immediately,
the $ontent o! the interim register is $ompared with the H-bit binarly in rd2, i! rd2 is smaller it is
subtra$ted !rom the interim register and the $arry-bit is set to one, i! rd2 is greater the subtra$tion is s%ipped and a *ero is set to the $arry !lag,
the $ontent o! the $arry !lag is rotated into the result register reh:rel !rom the right, i! a *ero rotated out o! the result register, we have to repeat the division loop, i! it was a one the
division is $ompleted.
! you don't understand rotation yet you'll !ind this operation dis$ussed in the multipli$ation se$tion.
The ob9e$t $ode has been started, the $ursor is on the !irst e(e$utable instru$tion. The %ey #11 per!orms single steps.
Avr-Asm-Tutorial
FB
http://www.avr-asm-tutorial.net
The test binaries 0(AAAA and 0(AA, to be divided, are written to the registers 41:40 and 4F.
The interim register 42 and the result register pair are set to their pred!ined values.
41:40 was rotated le!t to 42, !rom 0(AAAA the doubled value o! 0(01AAAE was yielded.
)o over!low !rom rotation into $arry has o$$urred and 0(01 in 42 was smaller than 0(AA in 4F, so subtra$tion was s%ipped. A *ero in the $arry is rotated into the result register 4A:4E. The !ormer $ontent o! the result register, a single 1-bit in position 0 has rotated to position 1 ;$ontent now: 0(0002<. As a *ero was rotated out o! the result register pair, the ne(t step to be e(e$uted is a bran$h to the beginning o! the division loop start and the loop is repeated.
Avr-Asm-Tutorial
FD
http://www.avr-asm-tutorial.net
A!ter e(e$uting the loop 1B times we have rea$hed the brea%point set at the end o! the division routine. The result register in 4A:4E holds 0(0202, the result o! the division. The registers 42:41:40 are empty, so we do not have a remainder le!t. ! a remainder would have been resulted we $an use it to de$ide whether an in$rementation o! the result should ta%e pla$e, rounding o! the result up. This step is not $oded here.
The whole division needs B0 mi$ro-se$onds pro$essor time ;open a pro$essor view in the studio menue<. A rather long time !or a division.
Number conversion
)umber $onversion routines are not in$luded here. 1lease re!er to the website, i! you need the sour$e $ode or a better understanding.
Decimal Fractions
#irst: =o not use any !loating points, unless you really need them. #loating points are resour$e %illers in an A74, lame du$%s und need e(treme e(e$ution times. 4un into this dilemma, i! you thin% assembler is too $ompli$ated, and you pre!er ,asi$ or other languages li%e 8 and 1as$al. )ot so, i! you use assembler. &ou'll be shown here, how you $an per!orm the multipli$ation o! a !i(ed point real number in less than B0 mi$ro-se$onds, in spe$ial $ases even within 1H mi$ro-se$onds, at E 2$s/s $lo$% !requen$y. Without any !loating point pro$essor e(tensions and other e(pensive tri$%s !or people too la*y to use their brain. >ow to do that" ,a$% to the roots o! math: 2ost tas%s with !loating point reals $an be done using integer numbers. ntegers are easy to program in assembler and per!orm !ast. The de$imal point is only in the brain o! the programmer, and is added somewhere in the de$imal digit stream. )o one reali*es, that this is a tri$%.
Linear conversions
As an e(ample the !ollowing tas%: an H-,it-A=-8onverter measures an input signal in the range !rom 0.00 to 2.AA 7olt, and returns as the result a binary in the range !rom V00 and V##. The result, a voltage, is to be displayed on a /8= display. +illy e(ample, as it is so easy: The binary is $onverted to a de$imal A+8 string between 000 and 2AA, and 9ust behind the !irst digit the de$imal point has to be inserted. =one: The ele$troni$s world sometimes is more $ompli$ated. 3.g., the A=-8onverter returns an H-,it->e( !or input voltages between 0.00 and A.00 7olt. )ow we're tri$%ed and do not %now how to pro$eed. To display the $orre$t result on the /8= we would have to multiply the binary by A00/2AA, whi$h is 1.-B0H. This is a silly number, as it is almost 2, but only almost. And we don't want that %ind o! ina$$ura$y o! 2., while we have an A=-$onverter with around 0.2A. a$$ura$y. To $ope with this, we multiply the input by A00/2AAU2AB or A01.-B and divide the result by 2AB. Why !irst
Avr-Asm-Tutorial
FH
http://www.avr-asm-tutorial.net
multiply by 2AB and then divide by 2AB" t's 9ust !or enhan$ed a$$ura$y. ! we multiply the input by A02 instead o! A01.-B, the error is 9ust in the order o! 0.00H.. That is good enough !or our A=-$onverter, we $an live with that. And dividing by 2AB is an easy tas%, be$ause it is a well-%nown power o! 2. ,y dividing with numbers that are a power o! 2, the A74 !eels very $om!ortable and per!orms very !ast. ,y dividing with 2AB, the A74 is even !aster, be$ause we 9ust have to s%ip the last byte o! the binary number. )ot even shi!t and rotate: The multipli$ation o! an H-bit-binary with the --bit-binary A02 ;he( 1#B< $an have a result greater than 1B bits. +o we have to reserve 2E bits or F registers !or the result. =uring multipli$ation, the $onstant A02 has to be shi!ted le!t ;multipli$ation by 2< to add these numbers to the result ea$h time a one rolls out o! the input number. As this might need eight shi!ts le!t, we need !uther three bytes !or this $onstant. +o we $hose the !ollowing $ombination o! registers !or the multipli$ation:
Register 41 4E : 4F : 42 4D : 4B : 4A
A!ter !illing the value A02 ;00.01.#B< to 4E : 4F : 42 and $learing the result registers 4D : 4B : 4A the multipli$ation goes li%e this: 1.Test, i! the input number is already *ero. ! yes, we're done. 2. ! no, one bit o! the input number is shi!ted out o! the register to the right, into the $arry, while a *ero is stu!!ed into bit D. This instru$tion is named /ogi$al-+hight-4ight or /+4. F. ! the bit in $arry is a one, we add the multipli$ator ;during step 1 the value A02, in step 2 it's 100E, a.s.o.< to the result. =uring adding, we $are !or any $arry ;adding 42 to 4A by A==, adding 4F to 4B and 4E to 4D with the A=8 instru$tion:<. ! the bit in the $arry was a *ero, we 9ust don't add the multipli$ator to the result and 9ump to the ne(t step. E.)ow the multipli$ator is multiplied by 2, be$ause the ne(t bit shi!ted out o! the input number is worth double as mu$h. +o we shi!t 42 to the le!t ;by inserting a *ero in bit 0< using /+/. ,it D is shi!ted to the $arry. Then we rotate this $arry into 4F, rotating its $ontent le!t one bit, and bit D to the $arry. The same with 4E. A.)ow we're done with one digit o! the input number, and we pro$eed with step 1 again. The result o! the multipli$ation by A02 now is in the result registers 4D : 4B : 4A. ! we 9ust ignore register 4A ;division by 2AB<, we have our desired result. To enhan$e o$$ura$y, we $an use bit D in 4A to round the result. )ow we 9ust have to $onvert the result !rom its binary !orm to de$imal A+8 ;see 8onversion bin to de$imal-A+8 on the website<. ! we 9ust add a de$imal point in the right pla$e in the A+8 string, our voltage string is ready !or the display. The whole program, !rom the input number to the resulting A+8 string, requires between D- and 22H $lo$% $y$les, depending !rom the input number. Those who want to beat this with the !loating point routine o! a more sophisti$ated language than assembler, !eel !ree to mail me your $onversion time ;and program !lash and memory usage<.
Avr-Asm-Tutorial
F-
http://www.avr-asm-tutorial.net
& "onCersion tiAes? & ;he >ho8e ro9tine reJ9ires !!7 =8o=I =y=8es A)<iA9A .=onCerting KFF/, )nd 69 =8o=I =y=8es AiniA9A .=onCerting K00/. & At 5 M,F the tiAes )re 56.65 Ai=rose=onds resD. 16.65 Ai=rose=onds. & Definitions? & Registers .DEF rAD = R16 & 9sed )s A98ti'D9rDose register & A R tyDe? ;ested for tyDe A;90*7515, on8y reJ9ired for st)=I setting, ro9tines >orI fine >ith other A;90*'tyDes )8so .%OLI*; .I%"L$DE :7515def.in=: .LI*; & *t)rt of test Drogr)A & L9st >rites ) n9A(er to R1 )nd st)rts the =onCersion ro9tine, for test D9rDoses on8y ."*E.OR- K0000 rMAD A)in A)in? 8di rAD,,I-,.RAME%D/ & *et the st)=I o9t *P,,rAD 8di rAD,LO1.RAME%D/ o9t *PL,rAD 8di rAD,KFF & "onCert KFF AoC R1,rAD r=)88 fD=onC7 & =)88 the =onCersion ro9tine noRend? & 9n8iAited 8ooD, >hen done rMAD noRend & "onCersion ro9tine >r)DDer, =)88s the different =onCersion steDs fD=onC7? r=)88 fD=onC7A & A98tiD8i=)te (y 50! r=)88 fD=onC7r & ro9nd )nd diCide (y !56 r=)88 fD=onC7) & =onCert to A*"II string 8di rAD,O.O & set de=iA)8 =h)r AoC R6,rAD ret & )88 done & *9(ro9tine A98tiD8i=)tion (y 50! fD=onC7A? =8r R5 & set the A98tiD8i=)nt to 50! 8di rAD,K01 AoC R4,rAD 8di rAD,KF6 AoC R!,rAD =8r R6 & =8e)r the res98t =8r R6 =8r R5 fD=onC7A1? or R1,R1 & =he=I if the n9A(er is )88 Feros (rne fD=onC7A! & sti88 oneOs, go on =onCert ret & re)dy, ret9rn ()=I fD=onC7A!? 8sr R1 & shift n9A(er to the right .diC (y !/ (r== fD=onC7A4 & if the 8o>est (it >)s 0, then sIiD )dding )dd R5,R! & )dd the n9A(er in R6?R5?R5?R4 to the res98t )d= R6,R4 )d= R6,R5 fD=onC7A4? 8s8 R! & A98tiD8y R5?R4?R! (y ! ro8 R4 ro8 R5 rMAD fD=onC7A1 & reDe)t for ne<t (it & Ro9nd the C)89e in R6?R6 >ith the C)89e in (it 6 of R5 fD=onC7r? =8r rAD & D9t Fero to rAD 8s8 R5 & rot)te (it 6 to =)rry )d= R6,rAD & )dd L*0 >ith =)rry )d= R6,rAD & )dd M*0 >ith =)rry AoC R!,R6 & =oDy the C)89e to R!?R1 .diCide (y !56/ AoC R1,R6 ret & "onCert the >ord in R!?R1 to )n A*"II string in R5?R6?R6?R7 fD=onC7)? =8r R5 & *et the de=iA)8 diCider C)89e to 100 8di rAD,100 AoC R4,rAD r=)88 fD=onC7d & get A*"II digit (y reDe)ted s9(tr)=tion AoC R5,rAD & set h9ndreds string =h)r 8di rAD,10 & *et the de=iA)8 diCider C)89e to 10 AoC R4,rAD r=)88 fD=onC7d & get the ne<t A*"II digit AoC R6,rAD & set tens string =h)r 8di rAD,O0O & =onCert the rest to )n A*"II =h)r )dd rAD,R1 AoC R7,rAD & set ones string =h)r ret
Avr-Asm-Tutorial
E0
http://www.avr-asm-tutorial.net
& "onCert (in)ry >ord in R!?R1 to ) de=iA)8 digit (y s9(str)=ting the de=iA)8 diCider C)89e in R5?R4 .100, 10/ fD=onC7d? 8di rAD,O0O & st)rt >ith de=iA)8 C)89e 0 fD=onC7d1? =D R1,R4 & "oAD)re >ord >ith de=iA)8 diCider C)89e =D= R!,R5 (r== fD=onC7d! & ")rry =8e)r, s9(tr)=t diCider C)89e ret & done s9(tr)=tion fD=onC7d!? s9( R1,R4 & s9(tr)=t diCider C)89e s(= R!,R5 in= rAD & 9D one digit rMAD fD=onC7d1 & on=e )g)in & End of =onCersion test ro9tine
Avr-Asm-Tutorial
E1
http://www.avr-asm-tutorial.net
Annex
Commands sorted by function
#or the abbreviations used see the list o! abbreviations. 0unction 4egister set 0 2AA 8onstant 4egister KW 4egister +4A2 KW 4egister, dire$t +4A2 KW 4egister +4A2 KW 4egister and )8 =38, +4A2 KW 4egister +4A2, displa$ed KW 4egister 1ort KW 4egister 8opy +ta$% KW 4egister 1rogram storage M KW 40 4egister KW +4A2, dire$t 4egister KW +4A2 4egister KW +4A2 and )8 =38, 4egister KW +4A2 4egister KW +4A2, displa$ed 4egister KW 1ort 4egister KW +ta$% H ,it, L1 Add H ,it H ,it L 8arry 1B ,it, $onstant H ,it, -1 H ,it +ubtra$t H ,it, $onstant H ,it - 8arry H ,it - 8arry, $onstant 1B ,it logi$, le!t logi$, right +hi!t 4otate, le!t over 8arry 4otate, right over 8arry Arithmeti$, right )ibble e($hange And And, $onstant 5r ,inary 5r, $onstant 3($lusive-5r 5nes-$omplement Twos-$omplement Su(function Comman! 8/4 r1 +34 rh /= rh,$2AA 257 r1,r2 /=+ r1,$BAAFA /= r1,rp /= r1,rpL /= r1,-rp /== r1,ryL%BF ) r1,p1 151 r1 /12 +T+ $BAAFA,r1 +T rp,r1 +T rpL,r1 +T -rp,r1 +T= ryL%BF,r1 56T p1,r1 16+> r1 )8 r1 A== r1,r2 A=8 r1,r2 A= W rd,%BF =38 r1 +6, r1,r2 +6, rh,$2AA +,8 r1,r2 +,8 rh,$2AA +, W rd,%BF /+/ r1 /+4 r1 45/ r1 454 r1 A+4 r1 +WA1 r1 A)= r1,r2 A)= rh,$2AA 54 r1,r2 54 rh,$2AA 354 r1,r2 852 r1 )3@ r1 M)7 M)7 M)7 M)7 M)7 M8)7 M)7 0lags M)7 Cl1 1 1 1 1 2 2 2 2 2 1 2 F 2 2 2 2 2 1 2 1 M8)7> 1 M8)7> 1 M8)7+ 2 M)7 1 M8)7> 1 M8)7> 1 M8)7> 1 M8)7> 1 M8)7+ 2 M8)7 M8)7 M8)7 M8)7 M8)7 1 1 1 1 1 1 1 1 1 1 1 1
M8)7> 1
Avr-Asm-Tutorial
E2
http://www.avr-asm-tutorial.net
Comman! +,4 rh,$2AA 8,4 rh,2AA ,+T r1,bD ,/= r1,bD +, pl,bD 8, pl,bD +3M +38 +3) +37 +3> +3+ +3T +3 8/M 8/8 8/) 8/7 8/> 8/+ 8/T 8/ 81 r1,r2 818 r1,r2 81 rh,$2AA T+T r1 4C21 $E0-B C21 48A// $E0-B 8A// 43T 43T M 8 ) 7 > + T M 8 ) 7 > + T
Cl1 1 1 1 1 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
,its $hange
4egister, $opy to T-#lag 4egister, $opy !rom T-#lag 1ort, set 1ort, $lear Mero-#lag 8arry #lag )egative #lag
+tatusbit set
Twos $omplement $arry #lag >al! $arry #lag +igned #lag Trans!er #lag nterrupt 3nable #lag Mero-#lag 8arry #lag )egative #lag
+tatusbit $lear
Twos $omplement $arry #lag >al! $arry #lag +igned #lag Trans!er #lag nterrupt 3nable #lag 4egister, 4egister 4egister, 4egister L 8arry 4egister, $onstant 4egister, 0 4elative ndire$t, Address in M
8ompare
mmediate Cump
+ubroutine, relative +ubroutine, Address in M 4eturn !rom +ubroutine 4eturn !rom nterrupt
Avr-Asm-Tutorial
EF
http://www.avr-asm-tutorial.net
Su(function +tatusbit $lear Cump i! equal Cump i! equal Cump i! $arry Cump i! $arry $lear Cump i! equal or greater Cump i! lower Cump i! negative
Comman! ,4,+ bD,$12D ,4,8 bD,$12D ,43P $12D ,4)3 $12D ,48+ $12D ,488 $12D ,4+> $12D ,4/5 $12D ,42 $12D ,41/ $12D ,4@3 $12D ,4/T $12D ,4>+ $12D ,4>8 $12D ,4T+ $12D ,4T8 $12D ,47+ $12D ,478 $12D ,4 3 $12D ,4 = $12D +,48 r1,bD +,4+ r1,bD +, 8 pl,bD +, + pl,bD 81+3 r1,r2 )51 +/331 W=4
0lags
Cl1 1/2 1/2 1/2 1/2 1/2 1/2 1/2 1/2 1/2 1/2 1/2 1/2 1/2 1/2 1/2 1/2 1/2 1/2 1/2 1/2 1/2/F 1/2/F 1/2/F 1/2/F 1/2/F 1 1 1
8onditioned Cump i! positive Cump Cump i! greater or equal ;+igned< Cump i! lower than *ero ;+igned< Cump on hal! $arry set Cump i! hal! $arry $lear Cump i! T-#lag set Cump i! T-#lag $lear Cump i! Twos $omplement $arry set Cump i! Twos $omplement $arry $lear Cump i! nterrupts enabled Cump i! nterrupts disabled 4egisterbitK0 4egisterbitK1 8onditioned 1ortbitK0 Cumps 1ortbitK1 8ompare, 9ump i! equal )o 5peration 5thers +leep Wat$hdog 4eset
Commands
AD" r1,r! ADD r1,r! ADI1 rd,I64 A%D r1,r! A%DI rh,=!55, Register A*R r1 0LD r1,(6 0R"" =1!6 0R"* =1!6 0RE# =1!6 0R-E =1!6 0R," =1!6 0R,* =1!6
Avr-Asm-Tutorial 0RID =1!6 0RIE =1!6 0RLO =1!6 0RL; =1!6 0RMI =1!6 0R%E =1!6 0RPL =1!6 0R*, =1!6 0R;" =1!6 0R;* =1!6 0R " =1!6 0R * =1!6 0*; r1,(6 "0I D8,(6 "0R rh,!55, Register "L" "L, "LI "L% "LR r1 "L* "L;, .=oAA)nd e<)AD8e/ "L "L2 "OM r1 "P r1,r! "P" r1,r! "PI rh,=!55, Register "P*E r1,r! DE" r1 EOR r1,r! I"ALL ILMP I% r1,D1 I%" r1 LD rD,.rD,rDG,'rD/ .Register/, .*RAM )==ess/, Ports LDD r1,ryGI64 LDI rh,=!55 .Register/, Pointer LD* r1,=65545 LPM L*L r1 L*R r1 MO r1,r! %E- r1 %OP OR r1,r! ORI rh,=!55 O$; D1,r1 POP r1, .in Int'ro9tine/ P$*, r1, .in Int'ro9tine/ R"ALL =5096 RE;, .in Int'ro9tine/ RE;I RLMP =5096 ROL r1 ROR r1 *0" r1,r! *0"I rh,=!55 *0I D8,(6 *0I" D8,(6 *0I* D8,(6 *0I1 rd,I64 *0R rh,!55, Register *0R" r1,(6 *0R* r1,(6 *E" *E, *EI, .in Int'ro9tine/ *E% *ER rh *E* *E;, .e<)AD8e/ *E *E2 *LEEP *; .rDNrDGN'rD/,r1 .Register/, *RAM )==ess, Ports *;D ryGI64,r1 *;* =65545,r1 *$0 r1,r! *$0I rh,=!55 *1AP r1 ;*; r1 1DR
EE
http://www.avr-asm-tutorial.net
Avr-Asm-Tutorial
EA
http://www.avr-asm-tutorial.net
Port details
The table o! the relevant ports in the AT23/ A74 types AT-0+2F1F, 2F2F and HA1A. ,ytewise a$$essable ports or register pairs are not displayed in detail. )o warranty !or $orre$tness, see the original data sheets:
Opportunities 0: nterrupts disabled 1: nterrupts enabled 0: +tored bit is 0 1: +tored bit is 1 0: )o hal!$arry o$$ured 1: >al!$arry o$$ured 0: +ign positive 1: +ign negative 0: )o $arry o$$ured 1: 8arry o$$ured 0: 4esult was not negative/smaller 1: 4esult was negative/smaller 0: 4esult was not *ero/unequal 1: 4esult was *ero/equal 0: )o $arry o$$ured 1: 8arry o$$ured
Stackpointer
Port 0unction Port- !!ress R 2- !!ress 0(A=/0(A3 *aila(ilit) #rom AT-0+2F1F upwards, not in 1200 #rom AT-0+HA1A upwards, only in devi$es with W2AB bytes internal +4A2 +1//+1> +ta$%pointer 00F=/0(F3 Name +1/ +1> 2eaning /ow-,yte o! +ta$%pointer >igh-,yte o! +ta$%pointer
Avr-Asm-Tutorial
EB
http://www.avr-asm-tutorial.net
Opportunities 0K)o e(tra wait state on e(ternal +4A2 1KAdditional wait state on e(ternal +4A2 0K gnore +/331 $ommands 1K+/331 on $ommand 0K dle 2ode ;>al! sleep< 1K1ower =own 2ode ;#ull sleep< 00: /ow-level initiates nterrupt
nterrupt $ontrol 1in )T1 01: 6nde!ined +810 ;$onne$ted to @ 2+?< 10: #alling edge triggers interrupt 11: 4ising edge triggers interrupt +801 00: /ow-level initiates interrupt nterrupt $ontrol 1in )T0 01: 6nde!ined +800 ;$onne$ted to @ 2+?< 10: #alling edge triggers interrupt 11: 4ising edge triggers interrupt
Port
0unction
@ #4 @eneral nterrupt #lag 4egister 3 )T#1 Bit D B 0...A Name )T#1 )T#0 + )T#0 & 2eaning , -
Opportunities
nterrupt by e(ternal pin )T1 o$$ured Automati$ $lear by e(e$ution o! the nt-4outine or nterrupt by e(ternal pin )T0 o$$ured 8lear by $ommand ;)ot used<
Avr-Asm-Tutorial
ED
http://www.avr-asm-tutorial.net
Bit D B A E F 2 1 0
Name T5 31
Opportunities 0: )o nt at over!low 1: nt at over!low 0: )o nt at equal A 1: nt at equal A 0: )o nt at , 1: nt at equal , 0: )o nt at 8apture 1: nt at 8apture 0: )o nt at over!low 1: nt at over!low
58 31A Timer/8ounter 1 8ompare A nterrupt 58 31, Timer/8ounter 1 8ompare , nterrupt ;)ot used< T 8 31 Timer/8ounter 1 8apture nterrupt ;)ot used< T5 30 Timer/8ounter 0 5ver!low- nterrupt ;)ot used<
Port
0unction
T #4 Timer nterrupt #lag 4egister 3 T571 Bit D B A E F 2 1 0 T570 8#1 Name T571 + 58#1A & 58#1,
Opportunities nterrupt-2ode: Automati$ 8lear by e(e$ution o! the nt-4outine 54 1olling-2ode: 8lear by $ommand
58#1A Timer/8ounter 1 8ompare A rea$hed 58#1, Timer/8ounter 1 8ompare , rea$hed ;)ot used< Timer/8ounter 1 8apture-3vent o$$ured ;not used< Timer/8ounter 0 5ver!low o$$ured ;not used<
Timer/Counter 0
Port 0unction Port- !!ress 0(FF # " 8+02 R 2- !!ress 0(AF $ 8+01 4 8+00 T8840 Timer/8ounter 0 8ontrol 4egister 3 Bit Name + & 2eaning , -
Opportunities 000: +top Timer 001: 8lo$% K 8hip $lo$% 010: 8lo$% K 8hip $lo$% / H 011: 8lo$% K 8hip $lo$% / BE 100: 8lo$% K 8hip $lo$% / 2AB 101: 8lo$% K 8hip $lo$% / 102E 110: 8lo$% K !alling edge o! e(ternal 1in T0 111: 8lo$% K rising edge o! e(ternal 1in T0
F..D
;not used<
Avr-Asm-Tutorial
EH
http://www.avr-asm-tutorial.net
Port
0unction
R 2- !!ress 0(A2
Timer/Counter 1
Port 0unction Port- !!ress 0(2# R 2- !!ress 0(E# T8841A Timer/8ounter 1 8ontrol 4egister A
&
# -
" -
$ 1W211
4 1W210
8521A1 8521A0 8521,1 8521,0 Bit D B A E F 2 Name 8521A1 8521A0 8521,1 8521,0 ;not used< 2eaning 8ompare 5utput A 8ompare 5utput ,
Opportunities 00: 581A/, not $onne$ted 01: 581A/, $hanges polarity 10: 581A/, to *ero 11: 581A/, to one
00: 1W2 o!! 01: H-,it 1W2 1ulse width modulator 10: --,it 1W2 11: 10-,it 1W2
Port
0unction
T8841, Timer/8ounter 1 8ontrol 4egister , 3 8)81 Bit D B + 83+1 Name 8)81 83+1 & 2eaning )oise 8an$eler on 81-1in 3dge sele$tion on 8apture , -
Opportunities 0: disabled, !irst edge starts sampling 1: enabled, min !our $lo$% $y$les 0: !alling edge triggers 8apture 1: rising edge triggers 8apture
A..E ;not used< F 8T81 8lear at 1: 8ounter set to *ero i! equal 8ompare 2at$h A 000: 8ounter stopped 001: 8lo$% 010: 8lo$% / H 011: 8lo$% / BE 100: 8lo$% / 2AB 101: 8lo$% / 102E 110: !alling edge e(ternal 1in T1 111: rising edge e(ternal 1in T1
Port
0unction
R 2- !!ress 0(E8/0(E=
Avr-Asm-Tutorial
E-
http://www.avr-asm-tutorial.net
Port
0unction
Port
0unction
R 2- !!ress 0(EH/0(E-
Port
0unction
R 2- !!ress 0(EE/0(EA
Watchdog-Timer
Port 0unction Port- !!ress 0(21 # W=3 " W=12 R 2- !!ress 0(E1 $ W=11 4 W=10 W=T84 Wat$hdog Timer 8ontrol 4egister 3 Bit D..A E F W=T53 W=3 Name + & , W=T53 2eaning ;not used< Wat$hdog Turno!! 3nable Wat$hdog 3nable 1revious set to disabling o! W=3 required 1: Wat$hdog a%tive
000: 1A ms 001: F0 ms 010: B0 ms 011: 120 ms 2..0 W=12..W=10 Wat$hdog Timer 1res$aler 100: 2E0 ms 101: E-0 ms 110: -D0 ms 111: 1,- s
EEPROM
Port 0unction Port- !!ress 0(13/0(1# R 2- !!ress 0(F3/0(F# 33A4//> 331452 Address 4egister
33A4> only in types with more than 2AB ,ytes 331452 ;!rom AT-0+HA1A upwards<
Port
0unction
R 2- !!ress 0(F=
Port
0unction
Avr-Asm-Tutorial
A0
http://www.avr-asm-tutorial.net
Bit D.. F 2 1 0
Name
0unction
332W3 331452 2aster Write 3nable 33W3 3343 331452 Write 3nable 331452 4ead 3nable
1revious set enables write $y$le +et to initiate write +et initiates read
0unction 0: nterrupts disabled 1: nterrupts enabled 0: +1 disabled 1: +1 enabled 0: 2+, !irst 1: /+, !irst 0: +lave 1: 2aster 0: 1ositive 8lo$% 1hase 1: )egative 8lo$% 1hase 0: +ampling at beginning o! 8lo$% 1hase 1: +ampling at end o! 8lo$% 1hase 00: 8lo$% / E 01: 8lo$% / 1B 10: 8lo$% / BE 11: 8lo$% / 12H
Port
0unction
Port- !!ress
R 2- !!ress 0(23
# 0unction
" -
$ -
4 -
nterrupt request
Port
0unction
Port- !!ress
R 2- !!ress 0(2#
Avr-Asm-Tutorial
A1
http://www.avr-asm-tutorial.net
UART
Port 0unction Port- !!ress 0(08 R 2- !!ress 0(28 6=4 6A4T /5 =ata 4egister
Port
0unction
Port- !!ress
R 2- !!ress 0(2,
6+4 6A4T +tatus 4egister 0(0, 3 4G8 Bit Name D B A E F 2..0 4G8 TG8 #3 54 + TG8 & 6=43 2eaning 6A4T 4e$eive 8omplete 6A4T Transmit 8omplete #raming 3rror 5verrun , #3
# 54
" 0unction
$ -
4 -
1: 8har re$eived 1: +hi!t register empty 1: Transmit register available 1: llegal +top-,it 1: /ost $har
;not used<
Port
0unction
R 2- !!ress 0(2A # TG3) " 8>4$ 4G,H 0unction 1: nterrupt on re$eived $har 1: nterrupt at transmit $omplete 1: nterrupt on transmit bu!!er empty 1: 4e$eiver enabled 1: Transmitter enabled 1: 8har length - ,it -th =ata bit on re$eive -.=ata bit on transmit 4 TG,H
684 6A4T 8ontrol 4egister 3 4G8 3 Bit Name D B A E F 2 1 0 + TG8 3 & 6=4 3
2eaning
4G8 3 4G 8omplete nterrupt 3nable TG8 3 TG 8omplete nterrupt 3nable 6=4 3 =ata 4egister 3mpty nterrupt 3nable 4G3) TG3) 8>44G,H TG,H 4e$eiver 3nabled Transmitter 3nable --bit 8hara$ters 4e$eive =ata ,it H Transmit =ata ,it H
Port
0unction
R 2- !!ress 0(2-
Analog Comparator
Port 0unction Port- !!ress 0(0H " A8 8 $ A8 +1 R 2- !!ress 0(2H 4 A8 +0 A8+4 Analog 8omparator 8ontrol and +tatus 4egister 3 A8= Bit Name D B A E A85 A8 8omparator 5utput nterrupt #lag A8= + & A85 2eaning =isable ;not used< 4ead: 5utput o! the 8omparators 1: nterrupt request , A8 # A8 3 0unction =isable 8omparators
Avr-Asm-Tutorial
A2
http://www.avr-asm-tutorial.net
Bit Name F 2 1 0 A8 3 A8 8 A8 +1 A8 +0
nput 8apture 3nable 1: 8onne$t to Timer 1 8apture 01: not used< 10: nterrupt on !alling edge 11: nterrupt on rising edge
I/O Ports
Port Register 154TA A ==4A 1 )A 154T, , ==4, 1 ), 154T8 8 ==48 1 )8 154T= = ==4= 1 )= 0unction =ata 4egister =ata =ire$tion 4egister nput 1ins Address =ata 4egister =ata =ire$tion 4egister nput 1ins Address =ata 4egister =ata =ire$tion 4egister nput 1ins Address =ata 4egister =ata =ire$tion 4egister nput 1ins Address Port- !!ress 0(1, 0(1A 0(10(1H 0(1D 0(1B 0(1A 0(1E 0(1F 0(12 0(11 0(10 R 2- !!ress 0(F, 0(FA 0(F0(FH 0(FD 0(FB 0(FA 0(FE 0(FF 0(F2 0(F1 0(F0
Avr-Asm-Tutorial
AF
http://www.avr-asm-tutorial.net
List of abbreviations
The abbreviations used are $hosen to in$lude the value range. 4egister pairs are named by the lower o! the two registers. 8onstants in 9ump $ommands are automati$ally $al$ulated !rom the respe$tive labels during assembly. Categor) r1 r2 4egister rh rd rp ry %BF $12D 8onstant $2AA $E0-B $BAAFA ,it 1ort bD p1 pl ((re*6 2eans 666 5rdinary +our$e and Target register 5rdinary +our$e register 6pper page register Twin register 1ointer register 1ointer register with displa$ement 1ointer-$onstant 8onditioned 9ump distan$e H-,it-8onstant 4elative 9ump distan$e 1B-,it-Address ,it position 5rdinary 1ort /ower page port 40..4F1 41B..4F1 42E;42A<, 42B;42D<, 42H;42-<, 4F0;4F1< GK42B;42D<, &K42H;42-<, MK4F0;4F1< &K42H;42-<, MK4F0;4F1< 0..BF -BE..LBF 0..2AA -20EH..L20ED 0..BAAFA 0..D 0..BF 0..F1 Value range