Skip to content

Assembly Generierung

Simon Johannes Engelhardt edited this page Feb 24, 2025 · 5 revisions

Wichtige Informationen zur Assembly Generierung

Caller und Callee Konventionen

Es wurde sich an den C-Konventionen orientiert. Das heißt der Caller ist dafür verantwortlich, alle Register, die später noch gebraucht werden, auf dem Stack zu speichern.

Evaluierungskonvention

Immer wenn eine Expression oder Funktion evaluiert wird, steht das Ergebnis am Ende in dem Register %rax.

Haupteinstiegspunkt

Was in C die main ist, ist hier die haupt. Diese Funktion ist der Einstiegspunkt in das Programm. Was die Funktion zurückgibt, wird als Exit-Code des Programms ausgeben und sollte eine Zahl sein.

Globale und lokale Variablen

Variablen, die außerhalb einer Funktion stehen, werden als globale Variablen behandelt. Sie stehen jeder Funktion zur Verfügung. Werden innerhalb einer Funktion Variablen deklariert, so werden diese als lokale Variablen behandelt und stehen innerhalb der Funktion zur Verfügung. Wird auf eine Variable zugegriffen, so wird zuerst in der lokalen Scope nach der Variable gesucht. Falls keine gefunden wird, betrachtet man die globalen Variablen.

Ganzzahl

In der Ausführung des Compilers werden nur ganze Zahlen und keine Dezimalzahlen implementiert. Eine Ganzzahl ist eine signed 64-Bit Zahl. Bei allen mathematischen Operationen werden die Assemblydirektiven für quad's genutzt (addq, imulq, etc.). Speichert man eine Ganzzahl global, so muss diese in der Data-Sektion gespeichert werden. Für korrekten Zugriff müssen die Bytes mit Speichergrenzen alligned sein. Deshalb braucht es für jede globale Variable folgende Direktive: .p2align 3, 0x0 (siehe. Diese sorgt für das korrekte Schreiben in den Hauptspeicher. Bei Nutzung im String wird "%g"(für Ganzzahl) genutzt.

Booleans

Booleans sind entweder wahr oder falsch. Sie werden repräsentiert als 1 oder 0 und sind wie die Ganzzahl eine signed 64-Bit Zahl. Booleans können also in allen Operationen wie Ganzzahlen benutzt werden. Bei Nutzung im String wird "%w" (für Wahrheitswert) genutzt.

Strings

Strings können nicht verändert werden. Sie können statisch vor dem Kompilieren angegeben werden als lokale oder globale Variable oder Inline in einer Funktion (z. B.: drucke("%g\n", 1); gibt eine Ganzzahl und eine Newline aus). Alle genutzten Strings werden gesammelt und zusammengefasst geschrieben in die Read-Only Sektion in Assembly. Es wird nur ASCII unterstützt.

Bibliotheksfunktionen

Bisher wird nur eine C Bibliotheksfunktion unterstützt: printf. In der Quellsprache heißt diese Funktion drucke und nimmt als erstes Argument eine Zeichenkette an und danach beliebige Argumente. In der Zeichenkette können die nachfolgenden Argumente substituiert werden. Beispiel: drucke("%g%z\n", 42, "Hallo Welt");. Hierbei steht g für Ganzzahl und z für Zeichenkette.

Unterschiede Linux und Mac

Mir war es wichtig beide Plattformen zu unterstützen, da ich auf einem MacBook den meisten Code geschrieben habe, aber auch öfters Linux benutze. Bei der Generierung des Assembly Codes gibt es wichtige Dinge, die zu beachten sind. Deshalb muss auch spezifiziert werden, für welche Plattform kompiliert werden soll.

Feature MacOS Linux
Funktionsnamen _printf, _main printf, main
Datensektionen .section __DATA,__data .section .data
Read-only Datensektion .section __TEXT,__cstring .section .rodata
Codesektionen .section __TEXT,__text .section .text