Aus RN-Wissen.de
Wechseln zu: Navigation, Suche
Laderegler Test Tueftler Seite

GNU Assembler

Eigentlich ist es ein normales GCC-Project, nur daß kein C-Programm da ist. Daher muß 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; 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

Siehe auch

Gcc Dokumentation

Beispiel C-Projekt mit Assembler-Modul


LiFePO4 Speicher Test