GNU Assembler
Eigentlich ist es ein normales GCC-Project, nur dass kein C-Programm da ist. Daher muss die Definition von der "main"-Funktion, die ja obligat ist, im Assembler erfolgen.
#include <avr/io.h> ; das gibt den Controllertyp an .text ; was nun folgt, gehört in den FLASH-Speicher .global main ; main ist auch in anderen Modulen bekannt main: ; zu 'main' wird nach Reset hingesprungen ;.... eigene befehle Hauptschleife: ; ein Sprunglabel ;.... eigene befehle rjmp Hauptschleife ; immer wiederholen
Und das wars auch schon.
Es bietet sich an, GCC aufzurufen und ihn die Arbeit an Assembler und Linker delegieren zu lassen. Standard Datei-Erweiterung dazu ist *.S
:
avr-gcc -o beispiel.elf -mmcu=atmega8 beispiel.S
Falls die Plattform Ärger mit Groß/Kleinschreibung macht wie Windows, dann geht auch
avr-gcc -x assembler-with-cpp -o beispiel.elf -mmcu=atmega8 beispiel.ss
GCC legt die Vektortabelle selbständig an und nimmt die richtigen Einträge vor. Dies gilt auch für den RESET-Vektor. Bevor zu main
gesprungen wird, wird noch eine kleine Initialisierung gemacht: Stackpointer setzen und Y-Reg darauf initialisieren, um es als Framepointer nutzen zu können.
Falls man eine IRQ bedienen möchte, schreibt man
.text .global SIG_OVERFLOW0 ; alternativ: __vector_9 schreiben, wenn 9 die IRQ-Nummer ist ; SIG_XXX ist ein #define aus avr/ioxxxx.h ; das durch #include <avr/io.h> mitincludet wird SIG_OVERFLOW0: ; dito ; ISR-Code reti
Dadurch wird an der richtigen Stelle der Vektortabelle ein Eintrag veranlasst.
Ein Disassemble des Maschinencodes sieht dann so aus (Vectab gekürzt):
Disassembly of section .text: 00000000 <__vectors>: 0: 12 c0 rjmp .+36 ; 0x26 2: 18 c0 rjmp .+48 ; 0x34 4: 17 c0 rjmp .+46 ; 0x34 ... 12: 11 c0 rjmp .+34 ; 0x36 ... 00000026 <__ctors_end>: 26: 11 24 eor r1, r1 28: 1f be out 0x3f, r1 ; 63 2a: cf e5 ldi r28, 0x5F ; 95 2c: d4 e0 ldi r29, 0x04 ; 4 2e: de bf out 0x3e, r29 ; 62 30: cd bf out 0x3d, r28 ; 61 32: 02 c0 rjmp .+4 ; 0x38 00000034 <__bad_interrupt>: 34: e5 cf rjmp .-54 ; 0x0 00000036 <__vector_9>: 36: 18 95 reti 00000038 <main>: 38: ff cf rjmp .-2 ; 0x38