AVR GCC assembler syntax
- A
;anywhere begins a comment. - A
#at the start of a line starts a comment, or a logical line number directive or preprocessor control command. - A
$acts as a newline to separate statements, but doesn’t end a comment. - Register names are
r0throughr31(r16throughr31on the reduced core), case insensitive. Can also use the plain register number directly. - Registers
X(r26:r27),Y(r28:r29), andZ(r30:r31) exist, with the low address as the low byte. Can also useXL/XHand similar. Case insensitive.
More scrap
In avr-binutils:
avr-as
Assemble AVR assembly into object filesavr-ld
Link object filesavr-objdump
Disassembler, show instruction bytesavr-objcopy
Convert ELF files into raw binary or Intel HEXavr-nm
List symbols in object files
avrdude uploads programs to the Arduino Nano.
avr-gcc invokes the assembler for me??, with correct MCU settings.
.global main
.text
main:
ldi r16, 0x42
ldi r17, 0x17
add r16, r17
loop:
rjmp loop
Assemble with avr-gcc -mmcu=atmega328p -c test.S -o test.o, disassemble with avr-objdump -d test.o.
LDI R16, 0x42 becomes 0xE402, stored little endian (02 E4).
Scrap
- 8-bit data width
- 32 general purpose registers
- 32KB program memory
- 2KB SRAM
- 1KB EEPROM
- Stack kept in SRAM??
- Lots of interrupts
- Lots of addressing modes (direct, indirect, relative)
- AVRe+ instruction set variant, missing
ELPM,EIJMP,EICALL(per ISM p. 149)
Register stuff:
- Arithmetic and logical instructions operate directly on any registers, so less movement required.
- LDI only loads values into R16-R31.
- X (R27:R26), Y (R29:R28), Z (R31:R30) are used for indirect memory access (they contain 16-bit addresses).
LD R16, X+loads a byte from the address stored in X and auto-increments X. CP R16, R17performs a comparison and sets bits in the SREG status register, which we can then conditionally branch with.
Memory stuff:
- Program and data memory have separate address spaces.
- The program lives in flash, which has 16-bit words. Instructions are generally 16 bits wide.
LPMis used to read a byte from flash (using byte addresses, not word addresses??). - SRAM contains working data and the hardware stack. The stack pointer (SPL and SPH) must be initialised to a value.
Instruction stuff:
LDI
Load immediate constantMOV
Copy registerLDS
Load from direct data addressLD
Load from SRAMST
Store to SRAMSTS
Store to direct data addressPUSH
Push register to stackPOP
Pop register from stackLPM
Read program flash
ADD:SUB:ADC:SBC:INC:DEC:MUL
Unsigned multiplyADIW
Add immediate to wordSUBI
Subtract immediate
AND:OR
IOREOR
XORCOM
NOTNEG
Two’s complementLSL
Logical shift leftLSR
Logical shift rightASR
Arithmetic shift rightROL
Rotate left through carryROR
Rotate right through carrySWAP
Swap nibbles
RJMP
Relative jumpJMP
Absolute jumpRCALL
Relative callCALL
Absolute callRET
Return from callRETI
Return from interruptBREQ
Branch if equalBRNE
Branch if not equalBRCS
Branch if carry setBRCC
Branch if carry clearBRMI
Branch if
Memory organisation
Instruction set
Status register (SREG):
| Name | |
|---|---|
C |
Carry flag |
Z |
Zero flag |
N |
Negative flag |
V |
Two’s compliment overflow flag |
S |
Sign flag |
H |
Half carry flag |
T |
Transfer bit |
I |
Global interrupt enable bit |
Registers and operands:
| Name | |
|---|---|
Rd |
Destination (and source) register |
Rr |
Source register |
R |
Result |
K |
Constant data |
k |
Constant address |
b |
Bit position in register |
s |
Bit position in status register |
X,Y,Z |
Indirect address register |
A |
IO memory address |
q |
Displacement for direct addressing |
UU |
Unsigned and unsigned operands |
SS |
Signed and signed operands |
SU |
Signed and unsigned operands |
ADC
Add with carry. Adds registers Rd and Rr and the contents of the C flag and stores the result in register Rd. Sets H, S, V, N, Z, C.
0001 11rd dddd rrrr |