171 lines
4.4 KiB
Markdown
171 lines
4.4 KiB
Markdown
# 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
|
|
- können lokale Variablen in Scratch-Registern speichern
|
|
- Rückkehradresse kann im Linkregister bleiben
|
|
- 
|
|
|
|
## 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
|
|

|
|
```c++
|
|
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
|
|

|
|
```c++
|
|
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
|
|
```c++
|
|
#include <stdlib.h>
|
|
void my_max(int a, int b, int* c) {}
|
|
if (a > b)
|
|
*c = a;
|
|
else
|
|
*c = b;
|
|
}
|
|
```
|
|
|
|
#### my_max ohne Optimierung
|
|

|
|
|
|
#### my_max mit Optimierung
|
|

|
|
|