How To Compare The Values In Registers Avr
Introduction to AVR assembler programming for beginners
What is a register?
Registers are special storages with viii bits capacity and they expect like this:| 7 | 6 | five | iv | 3 | two | 1 | 0 |
|---|
Note the numeration of these bits: the to the lowest degree significant chip starts with zero (20 = 1).
A register can either shop numbers from 0 to 255 (positive number, no negative values), or numbers from -128 to +127 (whole number with a sign scrap in bit 7), or a value representing an ASCII-coded character (e.g. 'A'), or simply eight single $.25 that do non have something to do with each other (east.grand. for eight unmarried flags used to point eight different yeah/no decisions).
The special character of registers, compared to other storage sites, is that
- they tin can be used directly in assembler commands,
- operations with their content crave only a single control word,
- they are continued directly to the central processing unit called the accumulator,
- they are source and target for calculations.
.DEF MyPreferredRegister = R16
Note that assembler directives like this are merely meaningful for the assembler but do not produce any lawmaking that is executable in the AVR target fleck. Instead of using the register name R16 we can now utilise our own proper name MyPreferredRegister, if nosotros desire to apply R16 within a control. So we write a little chip more text each time nosotros use this annals, simply we have an association what might be the content of this annals.
Using the command line
LDI MyPreferredRegister, 150
which means: load the number 150 immediately to the register R16, LoaD Firsthand. This loads a fixed value or a constant to that register. Following the assembly or translation of this lawmaking the programme storage written to the AVR chip looks like this:
000000 E906
The load command code also as the target register (R16) every bit well as the value of the abiding (150) is part of the hex value E906, even if you don't run into this directly. Don't be afraid: you don't have to retrieve this coding considering the assembler knows how to interpret all this to yield E906.
Inside ane command two different registers tin play a role. The easiest command of this blazon is the copy command MOV. Information technology copies the content of one register to another register. Similar this:
.DEF MyPreferredRegister = R16
.DEF AnotherRegister = R15
LDI MyPreferredRegister, 150
MOV AnotherRegister, MyPreferredRegister
The first two lines of this monster programme are directives that define the new names of the registers R16 and R15 for the assembler. Again, these lines do non produce any code for the AVR. The command lines with LDI and MOV produce code:
000000 E906
000001 2F01
The commands write 150 into annals R16 and copy its content to the target register R15. Of import Notation:
The first register is always the target annals where the consequence is written to!
(This is unfortunately unlike from what ane expects or from how nosotros speak. It is a elementary convention that was once divers that style to confuse the beginners learning assembler. That is why assembler is that complicated.)
To the acme of that page
Different registers
The beginner might want to write the above commands similar this: .DEF AnotherRegister = R15
LDI AnotherRegister, 150
And: y'all lost. Only the registers from R16 to R31 load a constant immediately with the LDI command, R0 to R15 don't do that. This restriction is not very fine, simply could not exist avoided during construction of the command gear up for the AVRs.
In that location is one exception from that rule: setting a annals to Zero. This command
CLR MyPreferredRegister
is valid for all registers.
Besides the LDI command you will observe this register class restriction with the following boosted commands:
- ANDI Rx,Yard ; Bit-And of annals Rx with a constant value One thousand,
- CBR Rx,G ; Clear all bits in register Rx that are set to one inside the abiding mask value M,
- CPI Rx,K ; Compare the content of the register Rx with a constant value One thousand,
- SBCI Rx,Thousand ; Subtract the constant K and the current value of the carry flag from the content of register Rx and shop the result in register Rx,
- SBR Rx,Thou ; Set all bits in register Rx to 1, that are one in the constant mask Grand,
- SER Rx ; Set all $.25 in annals Rx to 1 (equal to LDI Rx,255),
- SUBI Rx,K ; Subtract the constant G from the content of register Rx and store the result in register Rx.
To the meridian of that page
Pointer-register
A very special extra role is divers for the register pairs R26:R27, R28:R29 and R30:R31. The role is so of import that these pairs take actress names in assembler: X, Y and Z. These pairs are xvi-chip pointer registers, able to point to adresses with max. 16-bit into SRAM locations (10, Y or Z) or into locations in plan retentivity (Z).The lower byte of the 16-chip-adress is located in the lower register, the higher byte in the upper register. Both parts have their own names, eastward.g. the college byte of Z is named ZH (=R31), the lower Byte is ZL (=R30). These names are defined in the standard header file for the fries. Dividing these 16-bit-pointer-names into 2 different bytes is done like follows:
.EQU Adress = RAMEND ; RAMEND is the highest 16-bit adress in SRAM
LDI YH,High(Adress) ; Set the MSB
LDI YL,Depression(Adress) ; Set up the LSB
Accesses via pointers are programmed with specially designed commands. Read access is named LD (LoaD), write access named ST (STore), e.k. with the X-arrow:
| Pointer | Sequence | Instance |
|---|---|---|
| X | Read/Write from adress X, don't alter the arrow | LD R1,X ST 10,R1 |
| Ten+ | Read/Write from/to adress 10 and increase the arrow afterwards by one | LD R1,X+ ST 10+,R1 |
| -X | Decrement the arrow by one and read/write from/to the new adress afterwards | LD R1,-Ten ST -X,R1 |
There is only ane command for the read access to the program storage. It is divers for the pointer pair Z and it is named LPM (Load from Program Memory). The command copies the byte at adress Z in the programme memory to the annals R0. As the program memory is organised word-wise (1 control on ane adress consists of 16 bits or two bytes or one give-and-take) the least significant fleck selects the lower or higher byte (0=lower byte, 1= higher byte). Considering of this the original adress must be multiplied by 2 and access is limited to 15-bit or 32 kB plan retentiveness. Like this:
LDI ZH,HIGH(ii*Adress)
LDI ZL,LOW(two*Adress)
LPM
Following this command the adress must be incremented to betoken to the next byte in program retentivity. As this is used very often a special pointer incrementation command has been divers to exercise this:
ADIW ZL,1
LPM
ADIW means Add together Firsthand Word and a maximum of 63 can be added this manner. Note that the assembler expects the lower of the pointer register pair ZL as first parameter. This is somewhat confusing equally addition is done as sixteen-bit- operation.
The complement command, subtracting a constant value of between 0 and 63 from a xvi-scrap arrow register is named SBIW, Subtract Immediate Word. (SuBtract Immediate Word). ADIW and SBIW are possible for the pointer annals pairs X, Y and Z and for the register pair R25:R24, that does not accept an extra proper name and does non allow admission to SRAM or program memory locations. R25:R24 is ideal for handling 16-flake values.
Equally incrementation after reading is very ofttimes needed, newer AVR types take the instruction
LPM R,Z+
This allows to send the byte read to whatsoever location R, and auto-increments the arrow register.
How to insert that table of values in the program memory? This is done with the assembler directives .DB and .DW. With that y'all can insert bytewise or wordwise lists of values. Bytewise organised lists expect like this:
.DB 123,45,67,89 ; a list of four bytes
.DB "This is a text. " ; a list of byte characters
Y'all should ever identify an even number of bytes on each single line. Otherwise the assembler will add a zero byte at the end, which might be unwanted.
The similiar list of words looks like this:
.DW 12345,6789 ; a list of 2 words
Instead of constants yous can also place labels (leap targets) on that list, similar that:
Label1:
[ ... hither are some commands ... ]
Label2:
[ ... here are some more than commands ... ]
Table:
.DW Label1,Label2 ; a wordwise list of labels
Note that reading the labels with LPM get-go yields the lower byte of the word.
A very special application for the arrow registers is the access to the registers themselves. The registers are located in the kickoff 32 bytes of the chip's adress space (at adress 0x0000 to 0x001F). This access is only meaningful if you have to copy the annals'southward content to SRAM or EEPROM or read these values from there dorsum into the registers.
More common for the apply of pointers is the access to tables with stock-still values in the program retentiveness space. Here is, as an example, a tabular array with 10 unlike sixteen-bit values, where the fifth table value is read to R25:R24:
MyTable:
.DW 0x1234,0x2345,0x3456,0x4568,0x5678 ; The table values, wordwise
.DW 0x6789,0x789A,0x89AB,0x9ABC,0xABCD ; organised
Read5: LDI ZH,HIGH(MyTable*ii) ; Adress of tabular array to pointer Z
LDI ZL,LOW(MyTable*2) ; multiplied by two for bytewise admission
ADIW ZL,10 ; Signal to 5th value in table
LPM ; Read to the lowest degree significant byte from plan memory
MOV R24,R0 ; Re-create LSB to 16-scrap register
ADIW ZL,1 ; Point to MSB in program memory
LPM ; Read MSB of table value
MOV R25,R0 ; Copy MSB to 16-scrap register
This is only an instance. You tin can calculate the table adress in Z from some input value, leading to the respective table values. Tables can exist organised byte- or character-wise, too.
To the peak of that folio
Recommendation for the use of registers
- Define names for registers with the .DEF directive, never use them with their directly name Rx.
- If you demand pointer access reserve R26 to R31 for that purpose.
- 16-scrap-counter are best located R25:R24.
- If you demand to read from the program memory, eastward.g. fixed tables, reserve Z (R31:R30) and R0 for that purpose.
- If you programme to have access to single bits within sure registers (e.g. for testing flags), utilise R16 to R23 for that purpose.
To the top of that page
©2002 by http://www.avr-asm-tutorial.cyberspace
How To Compare The Values In Registers Avr,
Source: http://www.avr-asm-tutorial.net/avr_en/beginner/REGISTER.html
Posted by: manningnowbod00.blogspot.com

0 Response to "How To Compare The Values In Registers Avr"
Post a Comment