4.4 KiB
4.4 KiB
ARM Hochsprache Strukturen
Unterprogrammtechnik
- wird durch
bl Unterprogramm
aufgerufen- Unterprogramm muss zu dem Zeitpunkt bereits ein bekanntes Label sein
Blatt-Routinen | Nicht-Blatt-Routinen |
---|---|
rufen keine Unterprogramme auf | rufen Unterprogramme auf |
Unterprogrammaufruf
Indirekte Unterprogrammaufrufe
-
Falls Adresse zur Compilezeit nicht bekannt ist
-
Annahme: aufzurufende Programmadresse steht in r0
mov lr, pc
mov pc, r0
- Durch Pipelining entsteht im PC die aktuelle Bitadresse +8
- Da jeder Befehl Länge von 4 Byte hat
- Linkregister zeigt auf Rücksprungadresse
ARM Procedure Calling Standard (APCS)
- Schnittstelle zwischen Programmteilen
- Wie werden Parameter an Unterprogramme übergeben
- Welche Register dürfen zerstört werden
- Wie werden Ereignisse zurückgegeben
- Wie sieht das Stackframe eines Unterprogramms aus
Konvention zur Parameterübergabe von 32Bit-Daten
- Parameter 1-4 werden in den Registern r0-r3 übergeben
- Rückgabewert von Funktionen steht im Register r0 oder r0/r1
- Register r0-r3 und Register ip sind Scratch Register
- Inhalt darf im Unterprogramm zerstört werden
- Informationen in r4-r10, fp, sp müssen erhalten werden
- Inhalt von lr wird zur Rückkehr ins aufrufende Programm benötigt
Parameterübergabe bei anderen Prozessoren (CISC)
- Übergabe in Registern typisch für Load/Store-Architekturen
- vermeidet Zugriffe auf Speicher
- Andere Prozessoren verwenden Stack
- Parameter
- Rücksprungadresse (PC)
- Ergebnis im ACC zurückgeben
Blatt-Funktionen
Nicht-Blatt-Funktionen
- Linkregister wird durch neue Rücksprungadresse überschrieben
- vorher auf Stack retten
- Scratchregister dürfen durch neues Unterprogramm frei verwendet werden
- keine lokalen Variablen speichern
- Variablenregister verwenden
- von Anfang an auf Stack
Unterprogramm
- Unterprogrammaufruf mit Parameterübergabe
- Dokumentation
- Übergabewerte & lokale Variablen
- Eingangsprüfung Parameter
- ggf. Abbruch
- ggf. Register retten
- Initialisation Rückgabeparameter, lokale Variablen
- Programmkörper beachten
- Anweisungen, Schleifen, Verzweigungen: Grenzfälle der Indizes
- Speicherzugriffe passend zur Datengröße
- ggf. Register restaurieren
- Rückgabewert setzen
- Rücksprung
Operanden in Ausdrücken
- Argument im Register
- Argument auf dem Stack
- Stackpointer
- Relative Adressierung
- Stackpointer + Offset
- Als Konstante im Literal-Bereich der Prozedur
- PC-relative Adressierung mit Offset
- Als lokale Variable
- liegt im Stack
- Zugriff relativ zum Stack-Pointer / Frame-Pointer mit LDR
- Als globale Variable
- liegt im statischen Datenbereich im Speicher
- Adresse liegt relativ zur statischen Basisadresse
- Zeiger
- Array
- Kurzschreibweise für Zeiger + Offset
Kontrollfluss
IF-ELSE
Switch
int testswitch( int a, int* b, int c ) {
switch (a) {
case 0:
*b = 0;
break;
case 1:
if ( c > 100 ) *b = 0;
else *b = 3;
break;
case 2:
*b = 1;
break;
case 3:
break;
case 4:
*b = 2;
break;
}
}
While
Do-While
For
void testfor( int a[]) {
for (int i = 0; i < 10; i++){
a[i] = 0;
}
}
Objekte, (virtuelle) Methoden
Methodenaufrufe bei Objekten
- Methode bekommt als ersten Parameter immer einen Zeiger auf das betreffende Objekt (this)
- Zugriff auf Daten des Objektes gewährleistet
Statischer Objektaufruf
- Falls Methoden einer Klasse nicht virtuell
- Compiler kann zur Compile-Zeit schon Klasse bestimmen und Adresse der Methode einsetzen
Dynamischer Methodenaufruf
Beispiele Assemblerprogramme
my_max
#include <stdlib.h>
void my_max(int a, int b, int* c) {}
if (a > b)
*c = a;
else
*c = b;
}