x86 Assembler Programmierung Flashcards
MMX Instruktionen
Was bedeutet MMX?
Multi Media Extension
MMX Instruktionen
Was ist die Grundidee von MMX?
Ermöglichen von mehreren Rechenoperationen mit einem Befehl
MMX Instruktionen
Neben der Einführung von 8 neuen 64-Bit Registern kann auch als Vektoraddition durchgeführt werden. Beispiel: paddb mm0, mm2. Erkläre was passiert und wie viele Operationen gleichzeitig durchgeführt werden.
Es werden 8 unabhängige Bytes addiert (jeweils 8 Bit) und 8 Operationen gleichzeitig ausgeführt
SSE Instruktionen
Was bedeutet SSE?
Streaming SIMD Extensions
SSE Instruktionen
Wie lauten die Erweiterungen?
SSE2, SSE3,…
SSE Instruktionen
Wie groß ist das Register?
Es handelt sich um ein 128-Bit Register
SSE Instruktionen
MMX arbeitet mit Integer. Womit arbeitet SIMD?
Mit Gleitkommazahlen
SSE Instruktionen
SISD ist die Single Instruction und Single Data. Welche Architektur wäre ein gutes Beispiel?
Die klassische Intel-Architektur
SSE Instruktionen
SIMD ist Single Instruction und Multiple Data. Wofür ist es nützlich?
Für Vektorberechnungen
SSE Instruktionen
MISD ist Multiple Instructions und Single Data. Gibt es die überhaupt?
Nein, die gibt es nicht
SSE Instruktionen
MIMD ist Multiple Instructions und Multiple Data. Was wäre ein gutes Beispiel dafür?
Parallelrechner, z.B. Multicore-Chips
AMD Prozessoren
Nenne alle AMD Prozessoren aus der Vorlesung
- Athlon
- Turion
- Duron
- Sempron
- Opteron
x86 Registersätze
Das General Purpose Register besteht aus 8 Registern zu je 32 Bit. Was ist die Aufgabe des General Purpose Register?
Speichern von Daten, Zähler und Speicheradressen
x86 Registersätze
Wie wird der Speicher unterteilt?
Der Speicher wird in Segmente unterteilt
x86 Registersätze
Was macht das Flags Register?
Es gibt den Zustand der CPU wieder z.B. N und Z Bit oder Carry Bit
x86 Registersätze
Was gibt der Instruction Pointer (IP/EIP) / Program Counter (PC) an?
Die Adresse des nächsten Maschinensprache-Befehls
x86 Registersätze
Woraus besteht das Spezialregister?
MMX/SSE
x86 Registersätze
Wofür steht das Register ECX und wofür ist es zuständig?
Es steht für das Counter Register und ist für Shift/Rotate Instruktionen zuständig
x86 Registersätze
Wofür steht das Register EDX und wofür ist es zuständig?
Es steht für das Data register und ist für arithmetische Operationen und I/O zuständig
x86 Registersätze
Wofür steht das Register ESI?
Es steht für das Source Index register
x86 Registersätze
Wofür steht das Register EBP und was beinhaltet es?
Es steht für den Stack Base Pointer register und beinhaltet die Adresse des Stacks am oberen Ende
x86 Registersätze
Wofür steht das Register ESP und was beinhaltet es?
Es steht für das Stack Pointer register und beinhaltet die Adresse des Stacks am unteren Ende
x86 Registersätze
Wofür steht das Register EAX und wofür ist es zuständig?
Es steht für Accumulator register und ist zuständig für arithmetische Operationen
x86 Registersätze
Wofür steht das Register EDI?
Es steht für das Destination Index register
x86 Registersätze
Wofür steht das Register EBX und was beinhaltet es?
Es steht für das Base register und beinhaltet die Speicheradresse
x86 Registersätze
Womit beginnen 32-Bit Register?
Sie beginnen mit E: EAX, EDX
x86 Registersätze
Welche Bits sind adressierbar?
Die niederwertigen 16 Bits wie AX, DX und BX
x86 Registersätze
Haben die niederwertigen 16 Bits eigene Register?
Nein, die haben keine eigenen Register
x86 Registersätze
Die 2 * 8 Bit von AX, BX, CX und DX sind adressierbar. Es gibt AH, BH, CH und DH und AL, BL, CL und DL. Welche sind die höherwertigen Bits und welche die niederwertigen Bits?
- AH, BH, CH, DH (die höherwertigen 8 Bit)
- AL, BL, CL, DL (die niederwertigen 8 Bit)
x86 Registersätze
Wofür stehen die Segmentregister SS, CS, DS, ES, FS und GS?
- SS: Stack Segment
- CS: Code Segment
- DS: Data Segment
- ES: Extra Segment
- F: F Segment
- GS: G Segment
Segmente bei Intel Pentium CPUs
Woraus besteht ein Pentium Segment-Selektor?
Aus dem Index, GDT/LDT und Privilege Level
Segment bei Intel Pentium CPUs
Wozu dient der Index?
Er dient dazu, den spezifischen Segment-Deskriptor innerhalb der Tabelle zu identifizieren
Segmente bei Intel Pentium CPUs
Wofür ist GDT/LDT zuständig?
Es bestimmt die Segment-Deskriptor-Tabelle
Segmente bei Intel Pentium CPUs
Welche Rechte hat das Privilige Level?
Es hat Zugriffsrechte auf Segment Ebene
x86 Registersätze
Warum wird Segmentierung heute nicht mehr genutzt?
Da Paging besser ist
x86 Registersätze
SS, CS, DS, ES zeigen für einen Prozess alle auf dieselbe Speicheradresse. Wie wird der Speicher dann adressiert?
Der Speicher wird komplett linear adressiert
x86 Registersätze
FS und GS zeigen für einen Prozess nicht auf dieselbe Speicheradresse. Was wird dort gespeichert?
TLD = Thread Local Data, d.h. Daten, die für jeden Thread anders sind
x86 Registersätze / Flagregister
Welche Flagregister gibt es?
- CF: ?
- PF: ?
- AF: ?
- ZF: ?
- SF: ?
- TF: ?
- IF: ?
- DF: ?
- OF: ?
- IOPL: ?
- AC: ?
- CF: Carry Flag
- PF: Parity Flag
- AF: Adjust Flag
- ZF: Zero Flag
- SF: Sign Flag
- TF: Trap Flag
- IF: Interruption Flag
- DF: Direction Flag
- OF: Overflow Flag
- IOPL: I/O Privilige Level field (2 bits)
- AC: Alignment Check
x86 Datenrepräsentation
Bei Little Endian wird das niederwertige Byte zuerst angegeben. Wie wird der Wert 0xA1B2C3D4 im Speicher abgelegt?
D4 C3 B2 A1
Zweierkomplement
Bei dem Zweierkomplement erhält man die negativen Zahlen, indem man alle Bits invertiert und eines addiert. Wie würde 1 = 0001 invertiert aussehen?
- Invertiert = 1110
- Ein Bit addieren
- -1 = 1111
Adressierungsarten
Wo stehen die Operanden und das Ergebnis bei der Register Adressierung?
Die Operanden stehen in den Registern und das Ergebnis ist auch in einem Register
Adressierungsarten
Wo wird der Wert und das Ergebnis bei den Konstanten gespeichert?
Der Wert ist im Maschinensprachbefehl gespeichert und das Ergebnis in einem Register
Adressierungsarten
Wo befindet sich der Operand bei der direkten Speicheradressierung?
Der Operand befindet sich im Hauptspeicher und wird auch aus dem gelesen
Beispiel auf Folie 22
Adressierungsarten
Wo wird die Adresse des Operanden bei der direkten Speicheradressierung hineinkodiert?
Die Adresse des Operanden ist im Maschinensprachebefehl hineinkodiert
Beispiel auf Folie 22
Adressierungsarten
Die direkte Speicheradressierung mit Offset ist eigentlich keine Addressierungsart.
Beispiel:
- byte_tbl db 4, 8, 15, 16, 23, 42
- mov al, byte_tbl+2
Was ist byte_tbl und die 2 in dem Beispiel?
byte_tbl ist eine konstante Adresse im Datensegment und 2 ist eine Konstante
Adressierungsarten
Die direkte Speicheradressierung mit Offset ist eigentlich keine Addressierungsart.
Beispiel:
- byte_tbl db 4, 8, 15, 16, 23, 42
- mov al, byte_tbl+2
Was macht dann der Assembler mit den Konstanten byte_tbl und 2?
Der Assembler addiert beide Konstanten und nutzt dann die normale direkte Speicheradressierung
Adressierungsarten
Bei dem Register Indirekt sind beide Operanden Register. Was speichert der linke Operand und der rechte Operand?
Der linke Operand speichert das Ergebnis und der rechte Operand enthält eine Adresse
Beispiel dazu auf Folie 24
Adressierungsarten
Wird beim Register Indirekt auch die Segmentadresse addiert?
Ja, die Segmentadresse wird hinzuaddiert
Adressierungsarten
Bei der Speicheradressierung mit Basis-Offset hat ein Befehl 3 Operanden. Woraus bestehen die 3 Operanden?
Aus 2 Register und einer Konstante
Beispiel zu Folie 25
Adressierungsarten
Bei der Speicheradressierung mit Basis und Index hat ein Befehl 3 Operanden. Was sind die 3 Operanden?
Sie sind alle Register
Beispiel auf Folie 26
Adressierungsarten
Beispiel zur Speicheradressierung mit Basis-Offset:
- byte_tbl db 4, 8, 15, 16, 23, 42
- mov ax, byte_tbl [bx]
Was passiert mit BX und der resultierenden Adresse?
BX wird aufaddiert und die resultierende Adresse wird ausgelesen
Adressierungsarten
Beispiel zur Speicheradressierung mit Basis-Offset:
- byte_tbl db 4, 8, 15, 16, 23, 42
- mov ax, byte_tbl [bx]
Womit wird die Basisadresse angegeben?
Die Basisadresse ist mit byte_tbl gegeben
Adressierungsarten
Beispiel zur Speicheradressierung mit Basis-Offset:
- byte_tbl db 4, 8, 15, 16, 23, 42
- mov ax, byte_tbl [bx]
Wo landet das Ergebnis?
Das Ergebnis landet im linken Operanden
Adressierungsarten
Beispiel zur Speicheradressierung mit Basis und Index:
- mov ax, [bx + di]
Was passiert mit den Registern BX und DI?
Die Register BX und DI werden addiert
Addressierungsarten
Beispiel zur Speicheradressierung mit Basis und Index:
- mov ax, [bx + di]
Was ist das Ergebnis?
Das Ergebnis ist eine Speicheradresse und wird ausgelesen
Adressierungs
Beispiel zur Speicheradressierung mit Basis und Index:
- mov ax, [bx + di]
Wo landet das Ergebnis?
Das Ergebnis landet im linken Operanden
Adressierungsarten
Beispiel zu Register Indirekt:
- mov ax, [bx]
Wird die Segmentadresse hinzuaddiert?
Ja, sie wird hinzuaddiert
Adressierungsarten
Beispiel zur direkten Speicheradressierung:
- mov ax, [102h]
Was passiert in dem Beispiel?
Liest den Speicher an der Adresse 102h aus und schreibt das Ergebnis in das Register AX
Adressierungsarten
Beispiel zur direkten Speicheradressierung:
- mov ax, [102h]
Wie wird die Adresse berechnet?
- addr = DS + 102h
- Die Adresse des Datensegmentregisters wird automatisch aufaddiert
Adressierungsarten
Beispiel zu Register Indirekt:
- mov ax, [bx]
Was enthält das Register BX?
Das Register BX enthält eine Adresse
Adressierungsarten
Beispiel zu Register Indirekt:
- mov ax, [bx]
Wie wird die Adresse ausgelesen und wo wird es gespeichert?
Die Adresse wird 16-bittig ausgelesen und in AX gespeichert
Adressierungsarten
Beispiel zur Register Adressierung:
- mov ax, bx
Was passiert in dem Beispiel?
Es wird bx nach ax kopiert
Adressierungsarten
Beispiel zu Konstanten (Immediate):
- mov ax, 1
Was passiert in dem Beispiel?
Der Wert 1 wird nach ax kopiert
Adressierungsarten
Bei der Speicheradressierung mit Basis, Index und Offset hat ein Befehl 4 Operanden. Woraus bestehen die 4 Operanden?
Die Operanden bestehen aus 3 Register und 1 Konstante
Adressierungsarten
Beispiel zur Speicheradressierung mit Basis, Index, Offset:
- mov ax, [bx + di + 10]
- mov ax, byte_tbl [bx + di]
Was passiert mit den Registern BX und DI?
Die Register BX und DI werden addiert
Adressierungsarten
Beispiel zur Speicheradressierung mit Basis, Index, Offset:
- mov ax, [bx + di + 10]
- mov ax, byte_tbl [bx + di]
Was ist das Ergebnis und was passiert damit?
Das Ergebnis ist eine Speicheradresse und wird ausgelesen
Adressierungsarten
Beispiel zur Speicheradressierung mit Basis, Index, Offset:
- mov ax, [bx + di + 10]
- mov ax, byte_tbl [bx + di]
Wo landet das Ergebnis?
Das Ergebnis landet im linken Operanden
Stack
Beim Stack hat jeder Prozess mind. 3 Speicherblöcke. Liste die Speicherblöcke auf.
- Text
- Data
- Stack
Stack
Was enthält der Text?
Statische Daten
Stack
Was enthält die Data?
Dynamische Daten
Stack
Wofür ist der Stack da?
Für Funktionsaufrufe
Stackoperationen
In welche Richtung wächst der Stack?
Der Stack wächst von oben nach unten
Stackoperationen
Bei push ax wird der Operand auf dem Stack gespeichert. Um wie viele Bit kann das SP Register verringert werden?
Es kann um 1 Bit, 2 Bit, 4 Bit oder 8 Bit verringert werden
Stackoperationen
Bei pop ax wird ein Wert vom Stack geholt. Was passiert mit der Adresse die im SP Register steht?
Die Adresse, die im SP Register steht, wird ausgelesen
Stackoperationen
Um wie viele Bits kann das SP Register erhöht werden?
Das Register kann um 1 Bit, 2 Bit, 4 Bit oder 8 Bit erhöht werden
Stackoperationen
Beim push ax werden Operanden auf dem Stack gespeichert. Was macht man mit der Adresse die im SP Register steht?
Der Operand wird an die neue Adresse geschrieben, auf die das SP Register zeigt
Stack Frame
Der Stack Pointer (SP) ist das Ende des Stack Frames. Wohin zeigt er?
Er zeigt immer auf das oberste Byte des Stacks
Stack Frame
Wohin zeigt der Stack Base Pointer (BP)?
Zeigt immer auf den Beginn eines Stack Frames
Stack Frame
Jeder Funktionsaufruf hat einen Stack Frame. Was bedingt das Aufrufen einer Funktion?
Das Aufrufen erzeugt einen neuen Stack Frame
Stack Frame
Wo liegen die lokalen Variablen ab dem BP?
Sie liegen in Richtung der niedrigeren Adressen
Stack Frame
Wo liegen die Funktionsparameter beim Stack Frame?
Sie liegen an höheren Adressen bis zum BP
Rekursion vs Iteration
Was macht der Stack eines Assembler bei der Iteration?
Der Stack nimmt die lokalen Variablen und die Rücksprungadresse auf
Rekursionstiefe
Welche Daten werden bei jedem Rekursionsschritt auf den Stack geschrieben?
- Parameter
- Base Stack Pointer
- Rücksprungadresse
Rekursionstiefe
Was bestimmt die Stackgröße und was ist das Resultat?
Die Stackgröße wird durch die Rekursionstiefe, Parameter, Base Stack Pointer und Stack bestimmt. Das Resultat wäre ein Stack Overflow.
Rekursionstiefe
Welche Gründe gibt es für hohe Rekursionstiefe?
Meistens Bugs oder manchmal auch naturwissenschaftliche Berechnungen
Tail-Recursion
Bei der Tail-Recursion ist der Ort des rekursiven Aufrufs entscheidend. Welches Beispiel hat die Tail-Recursion?
int F(int a, int b) { if (a == 0 || b == 0) return 0; return a + b + F(a * 0.9999, b * 0.9999; }
int F(int a, int b, int c) { if (a == 0 || b == 0) return c; return F(a * 0.9999, b * 0.99999, a + b); }
Beispiel 2 hat die Tail Recursion, da der rekursive Aufruf die letzte Instruktion ist.
Tail Recursion
Wie sieht bei der iterativen Lösung ohne Stacknutzung die Rücksprungadresse aus?
Es ist immer dieselbe, mit Ausnahme der Abbruchbedingung
Tail Recursion
Werden lokale Variablen & Parameter noch benötigt?
Die werden nicht benötigt, wenn die Rekursion zurück kommt und gibt es teilweise auch nicht
Tail Recursion
Wieso muss man das Base Pointer Register nicht sichern?
Da nichts auf den Stack kommt
Tail Recursion
Was ist die Idee hinter der Tail Recursion?
Beliebige Rekursionstiefe ermöglichen
Tail Recursion
Was ist der Ansatz?
Erkennen, dass es sich um Tail-Recursion handelt und die Rekursion iterativ umzuwandeln
Beispiel auf Folie 50
Loop Unrolling
Da bei kleinen Schleifen sich das Springen nicht mehr lohnt macht man eher…?
Einfache Wiederholungen da sie schneller sind
Inline Funktionen
Das Aufrufen einer Funktion ist immer teuer und der Sprung braucht Zeit. Zu welchen Misses kann es kommen?
Es kann zu mehr Cache Misses kommen
Sprünge und bedingte Sprünge
Gebe das Beispiel aus der Vorlesung zu bedingten Sprüngen an
BNE Else
Sprünge und bedingte Sprünge
Gebe das Beispiel aus der Vorlesung zu nicht-bedingten Sprüngen an
BR Next
Sprünge und bedingte Sprünge
Übersetze den folgenden Code:
~~~
If (i == 0)
k = 1;
Else
k = 2;
~~~
If: CMP i, 0 BNE Else Then: MOV k, 1 BR Next Else: MOV k, 2 Next: FOO x,y
Nicht-bedingte Sprünge
Unit S2 der Pipeline untersucht gerade den Befehl “BR Next”. Eigentlich geht es dann mit “FOO x,y” weiter.
Während dessen (PARALLEL DAZU) holt Unit S1 den nächsten Befehl. Unit S1 holt den Befehl “MOV k,2” aus dem Speicher.
Jetzt hat die CPU den Falschen Befehl im Speicher.
Was könnte der Grund sein?
Die CPU muss den vermeintlich nächsten Befehl holen bevor sie merkt, dass sie springen muss
Unit S2 der Pipeline untersucht gerade den Befehl “BR Next”. Eigentlich geht es dann mit “FOO x,y” weiter.
Während dessen (PARALLEL DAZU) holt Unit S1 den nächsten Befehl. Unit S1 holt den Befehl “MOV k,2” aus dem Speicher.
Jetzt hat die CPU den Falschen Befehl im Speicher. Die CPU muss den vermeintlich nächsten Befehl holen bevor sie merkt, dass sie springen muss.
Welche Lösungsmöglichkeit gibt es mit UltraSPRAC III?
Der Befehl nach dem Sprung wird immer ausgeführt.
Unit S2 der Pipeline untersucht gerade den Befehl “BR Next”. Eigentlich geht es dann mit “FOO x,y” weiter.
Während dessen (PARALLEL DAZU) holt Unit S1 den nächsten Befehl. Unit S1 holt den Befehl “MOV k,2” aus dem Speicher.
Jetzt hat die CPU den Falschen Befehl im Speicher. Die CPU muss den vermeintlich nächsten Befehl holen bevor sie merkt, dass sie springen muss.
Was schreibt man im Zweifelsfall bei UltraSPRAC III, wenn der nächste Befehl unsicher ist?
Im Zweifelsfall schreibt man an diese Stelle ein NOP
Nicht bedingte Sprünge
Unit S2 der Pipeline untersucht gerade den Befehl “BR Next”. Eigentlich geht es dann mit “FOO x,y” weiter.
Während dessen (PARALLEL DAZU) holt Unit S1 den nächsten Befehl. Unit S1 holt den Befehl “MOV k,2” aus dem Speicher.
Jetzt hat die CPU den Falschen Befehl im Speicher. Die CPU muss den vermeintlich nächsten Befehl holen bevor sie merkt, dass sie springen muss.
Welche Lösungsmöglichkeit gibt es mit Pentium?
Umgehen des Problems durch eine Menge extra Transistoren
Bedingte Sprünge
Bedingte Sprünge sind der kniffligste Fall für die Pipeline. Das Ergebnis von “BNE Next” liegt erst vor, wenn Unit S4 fertig ist. Also herrscht 3 Takte lange Unsicherheit. Was wären Lösungsansätze?
- Einfach: Erstmal die drei Takte abwarten das ist aber leider langsam
- Komplex: Spekulative Ausführung, d.h die CPU führt Befehle spekulativ aus
Bedingte Sprünge
Gibt es irgendwelche Folgen wenn die CPU bei der spekulativen Ausführung richtig geraten hat?
Nein, da die Konsequenzen nicht schlimmer als unbedingte Sprünge sind
Gibt es irgendwelche Folgen wenn man bei der Spekulativen Ausführung falsch geraten hat?
Die Pipeline muss geleert werden und rückgängiggemacht werden
Bedingte Sprünge vorhersagen
Um die Sprünge vorherzusagen rät die CPU statisch. Wieso führen bedingte Rücksprünge wahrscheinlich zu einem Sprung?
Weil bedingte Sprünge in Schleifen vorkommen und die n-mal wiederholt werden und 1-mal abbrechen
Bedingte Sprünge vorhersagen
Bedingte Vorwärtssprünge haben selten eine statisch bevorzugte Wahrscheinlichkeit. Das bedeutet, dass sie leicht…?
tendenziell eher nicht springen
Bedingte Sprünge vorhersagen
Wieso kann statisches Raten des Compilers funktionieren?
Der Compiler weiß es manchmal besser als die CPU allerdings nur selten
Bedingte Sprünge vorhersagen
Was könnte der Compiler beim statischen Raten theoretisch machen?
Er könnte theoretisch ein Flag im Befehl setzen, die die Vorzugsentscheidung angibt
Bedingte Sprünge vorhersagen
Was macht der Compiler zuerst beim Profiling?
Der Compiler beginnt mit einer statischen Vorhersage von Sprungwahrscheinlichkeiten
Bedingte Sprünge vorhersagen
Warum wird das Programm beim Profiling mehrfach ausgeführt nachdem der Compiler statisch rät?
Die Sprungwahrscheinlichkeiten werden ermittelt
Bedingte Sprünge vorhersagen
Was macht der Compiler beim Profiling nachdem das Programm mehrfach ausgeführt wurde?
Es verbessert seine Vorhersagen
Bedingte Sprünge vorhersagen
Beim dynamischen Raten der CPU mit 1 Bit merkt sich die CPU die letzten Sprungbefehle. Welcher Nachteil entsteht?
Es kostet extra Speicher in der CPU
Bedingte Sprünge vorhersagen
Worauf beruht die Vorhersage beim dynamischen Raten der CPU mit 1 Bit?
Beruht auf der letzten Befehlsausführung, da die CPU ein extremes Kurzzeitgedächtnis hat
Bedingte Sprünge vorhersagen
Welcher Algorithmus wird beim Dynamischen Raten der CPU mit 2 Bit benutzt?
Der “second chance” Algorithmus
Bedingte Sprünge vorhersagen
Was merkt sich die CPU beim dynamischen Raten der CPU mit 2 Bit?
Die letzten 2 Befehlsausführungen