Zum Inhalt springen
Logo TechLab Blog

TechLab Blog

As­sem­bler

Andreas Möckli gab uns an diesem Abend eine Einführung im Assembler-Programmieren.

Wir nutzten dazu Arduino Unos, dessen LED/Sensoren wir dann per Arduino IDE mit Assembler Code ansprachen.

Um sich besser vorstellen zu können, wie man Assembler Code schreibt, hier ein Beispiel:

void setup()
{
asm volatile
(
"ldi r16,0x00\n"
"out 0x03,r16\n"
"out 0x05,r16\n"
"ldi r16,0xFF\n"
"out 0x04,r16\n"
);
}


void loop()
{
asm volatile("anfang: \n");
// Es wird 1 Bit an 6. Stelle gesetzt (D13)
asm volatile
(
"ldi r17,0x20\n"
"out 0x05,r17\n"
);
// Verzögerung, realisiert durch 4 Schlaufen
asm volatile("call verz \n");
// Bit wird an der 6. Stelle gelöscht (D13)
asm volatile
(

"ldi r17,0x00\n"
"out 0x05,r17\n"
);
// Verzögerung
asm volatile("call verz \n");
// Sprung an den Anfang
asm volatile("jmp anfang \n");
// Unterprogramm Verzögerung
asm volatile
(
"verz: \n"
// Schlaufe 4
"ldi r27,0x2F \n"
"label_4: \n"
//Schlaufe 3
"ldi r26,0xFF \n"
"label_3: \n"
// Schlaufe 2
"ldi r25,0xFF\n"
"label_2: \n"
// Befehl: keine Operation
"nop \n"
"dec r25 \n"
"brne label_2 \n"
// Rücksprung Schlaufe 2
"dec r26 \n"
"brne label_3 \n"
// Rücksprung Schlaufe 3
"dec r27 \n"
"brne label_4 \n"
// Rücksprung Schlaufe 4
"ret \n"
// Verlassen des Unterprogramms Verzögerung
);
}

Dieser Code steuert eine LED, typischerweise die eingebaute LED, die an Pin D13 des Arduino UNO angeschlossen ist, indem er sie blinken lässt.

Der setup Teil

  1. Initialisierung: Der Mikrocontroller wird mit bestimmten Einstellungen initialisiert, bevor er mit der eigentlichen Aufgabe beginnt. Dies geschieht im setup-Teil des Programms.
    • ldi r16,0x00 lädt den Wert 0x00 (also 0 in dezimal) in das Register r16. Dieser Schritt bereitet das Register vor, um es für die Konfiguration zu verwenden.
    • out 0x03,r16 und out 0x05,r16 schreiben den Wert aus r16 (0) in die Register an den Adressen 0x03 und 0x05. Diese Aktion setzt bestimmte Konfigurationen für die Pins des Mikrocontrollers, typischerweise beziehen sich diese auf die Datenrichtung und den Zustand der Pins.
    • Dann wird r16 mit 0xFF geladen (ldi r16,0xFF), was bedeutet, dass alle Bits auf 1 gesetzt werden. Mit out 0x04,r16 wird dieser Wert in ein anderes Register geschrieben, um die Datenrichtung der Pins zu bestimmen. In diesem Fall wird damit angegeben, dass alle Pins des betreffenden Ports als Ausgänge konfiguriert werden sollen.

Der loop Teil

  1. Anfang der Schleife: Der anfang: markiert den Startpunkt der Schleife, die kontinuierlich durchlaufen wird.
  2. LED einschalten: Mit ldi r17,0x20 wird das Register r17 mit dem Wert 0x20 geladen, was bedeutet, dass das sechste Bit gesetzt wird (entspricht Pin D13 bei einem Arduino UNO). Der Befehl out 0x05,r17 schreibt dann diesen Wert in das Register, das den Zustand der Pins kontrolliert, und schaltet die LED ein.
  3. Verzögerung: Der Befehl call verz ruft ein Unterprogramm auf, das eine Verzögerung erzeugt. Dies gibt der LED Zeit, eingeschaltet zu bleiben, sodass das Blinken sichtbar wird.
  4. LED ausschalten: Ähnlich wie beim Einschalten wird die LED ausgeschaltet, indem ldi r17,0x00 und out 0x05,r17 verwendet werden, um das entsprechende Bit zu löschen.
  5. Verzögerung: Erneut wird eine Verzögerung durch das Aufrufen des verz Unterprogramms eingefügt, um der LED Zeit zu geben, ausgeschaltet zu bleiben.
  6. Zurück zum Anfang: Mit jmp anfang springt das Programm zurück zum Anfang der Schleife, um das Ein- und Ausschalten der LED zu wiederholen.

Das verz Unterprogramm

Das Unterprogramm verz erzeugt eine Verzögerung durch das Ausführen mehrerer ineinander verschachtelter Schleifen. Jede Schleife zählt einen Registerwert herunter, beginnend mit einem anfänglichen Wert, bis dieser Wert 0 erreicht. Durch das ineinander Verschachteln dieser Schleifen wird die Verzögerung verlängert, ohne dass ein spezieller Timer oder eine spezielle Verzögerungsfunktion verwendet wird. Dies ist eine sehr grundlegende Methode, um eine Zeitverzögerung in Assemblersprache zu implementieren.

Zusammenfassung

Zusammengefasst erzeugt dieser Code ein Blinkmuster für eine LED am Pin D13 eines Arduino UNO. Er tut dies, indem er direkt Hardware-Register des Mikrocontrollers mittels Assemblerbefehlen manipuliert, um die LED ein- und auszuschalten und dazwischen Verzögerungen einzufügen.

Man sieht schon, dass Assembler Code doch einiges an Einarbeitung benötigt, bis man die Funktionsweise versteht. Andreas hat uns an diesem Abend aber sehr praxisnah die Grundlagen von Assember beigebracht und jetzt ist es an uns, bei Interesse selbstständig weitere Programme zu schreiben.

Hier noch ein Youtube Video von "Der Hobbyelektroniker", welches die Registeransprechung gut aufzeigt und erklärt.

Alle Materialien (Beispiele, Aufgaben, Internetressourcen), die uns Andreas an diesem Abend zur Verfügung gestellt hat, sind hier zu finden.

Anzahl Kommentare 0
Kommentare