Hier entsteht eine Sammlung von verschiedenen nützlichen Makros für den AVR Assembler.
[bearbeiten] 16 Bit Konstante in Z-Pointer laden
.MACRO SetZPtr ;(Adresse)
ldi ZL, LOW(@0)
ldi ZH, HIGH(@0)
.ENDMACRO |
Natürlich auch möglich mit X- und Y-Pointer.
[bearbeiten] 2 Register ohne Zwischenspeicher vertauschen
.MACRO SWAP ;(a, b)
eor @0, @1
eor @1, @0
eor @0, @1
.ENDMACRO |
[bearbeiten] Konstante addieren
.MACRO ADDI ;(a, k)
subi @0, -(@1)
.ENDMACRO |
[bearbeiten] Konstante addieren (16 Bit)
.MACRO ADDIW ;(RdL:RdH, k)
subi @0L, LOW(-@1)
sbci @0H, HIGH(-@1)
.ENDMACRO |
oder (sinnlos)
.MACRO ADDIW ;(Rd, k)
sbiw @0, (-@1)
.ENDMACRO |
DAS geht auch ohne Makro
SBIW und ADIW sind aber beide auf die Register(paare) R24, R26, R28, R30 beschränkt UND nehmen nur Zahlen <64 an.
Bei grösseren und neueren AVRs sind etliche I/O-Register nicht mit IN/OUT-Befehlen ansprechbar. LDS/STS erreicht zwar alle, ist aber bei kleineren oder älteren ineffizient.
.macro input
.if @1 < 0x40
in @0, @1
.else
lds @0, @1
.endif
.endm |
.macro output
.if @0 < 0x40
out @0, @1
.else
sts @0, @1
.endif
.endm |
Abfrage eines Bits eines I/O-Ports und Sprung wenn 1/0.
Überschreibt u.U. ZL.
Branch if Bit in I/O-Register is Set
.macro bbis ;port,bit,target
.if @0 < 0x20
sbic @0, @1
rjmp @2
.elif @0 < 0x40
in zl, @0
sbrc zl, @1
rjmp @2
.else
lds zl, @0
sbrc zl, @1
rjmp @2
.endif
.endm |
Branch if Bit in I/O-Register is Cleared
.macro bbic ;port,bit,target
.if @0 < 0x20
sbis @0, @1
rjmp @2
.elif @0 < 0x40
in zl, @0
sbrs zl, @1
rjmp @2
.else
lds zl, @0
sbrs zl, @1
rjmp @2
.endif
.endm |