-
Notifications
You must be signed in to change notification settings - Fork 0
Assembly Generierung
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.
Immer wenn eine Expression oder Funktion evaluiert wird, steht das Ergebnis am Ende in dem Register %rax
.
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.
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.
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 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 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.
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.
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 |