11/7/2007 Rechnerarchitektur und Assemblerprogrammierung Vorlesung 4 Was bisher geschah… y Prozeduren y Unterstützung durch MIPS-Architektur y Instruktion jal y Spezialregister $ra, $sp, $fp 1 11/7/2007 Bisher bekannte Instruktionen Arithmetik Datentransfer Logik Sprünge add lw and beq sub sw or bne addi nor j lui andi jr ori slt sll slti srl jal 20 von 52 Instruktionen MIPS-Register Register $zero $v0-$v1 $a0-$a3 $t0-$t7 $s0-$s7 $t8-$t9 $sp $fp $ra 28 von 32 Registern 2 11/7/2007 Erinnerung Prozeduraufruf Aufrufer … Prozedur … Aufrufer … 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. … schreibt evtl. zusätzliche Argumente auf den Stack … sichert Argumentregister $a0, …, $a3 und $ra auf Stack … legt Argumente in $a0, …, $a3 ab … springt zu Prozedur, aktueller PC wird in $ra gesichert … sichert $s0, …, $s7 auf Stack … führt Berechnung durch … schreibt Ergebnisse in $v0, $v1 … liest $s0, …, $s7 von Stack und schreibt zurück … springt an Adresse in $ra ... liest $a0, $a3 und $ra vom Stack und schreibt zurück … löscht evtl. zusätzliche Argumente vom Stack … verarbeitet Ergebnisse $v0, $v1 Aufrufkonventionen y Konvention bzgl. … y Register-Semantik y Reihenfolge y y Argumente gesicherte Register, etc. y Rolle Aufrufer/Prozedur y MIPS y Argumente in Registern (von links nach rechts) y mehr als vier Stack (von links nach rechts) y Reihenfolge y (evtl.) Stack-Argumente y Gerettete Argumentregister y Gerettetes $ra y Gerettete Variablenregister y Lokale Daten 3 11/7/2007 Exkurs: x86 y x86–Architektur kennt verschiedene Aufrufkonventionen y Bereits darüber gestolpert? __cdecl, __fastcall, __stdcall, thiscall y Einfluss y der Programmiersprache? y des Programmiermodells? __cdecl y Standard bei C/C++ y Prozeduren mit variabel langer Argumentliste … int method ( int a, ... ); y Alle Argumente auf Stack (von rechts nach links) y Anzahl Argumente von Aufruf zu Aufruf unterschiedlich Aufrufer räumt Stack auf Instruktionen zum Aufräumen nach jedem Aufruf größere Binaries y Dank C/C++ sehr weit verbreitet 4 11/7/2007 __stdcall y Standard bei WIN32 API, COM y Argumente von rechts nach links auf Stack y Prozedur räumt auf y Instruktionen zum Aufräumen am Ende der Prozedur y nur einmal pro Prozedur kleinere Binaries __fastcall y Standard bei Itanium und AMD64 y Erste zwei Argumente (von links, <32 Bit) in Registern y Weitere Argumente von rechts nach links auf Stack y Geschwindigkeitsvorteil y Prozedur räumt Stack auf 5 11/7/2007 Visual C/C++ y Visual C/C++ y __cdecl ist Standard y Alternative Aufrufkonvention erzwingen durch… int [__cdecl] methodA(int x, int y); int __stdcall methodB(int x, int y); int __fastcall methodC(int x, int y); GCC y Aufrufkonvention erzwingen durch… int methodA(int x, int y) __attribute__((cdecl)); int methodB(int x, int y) __attribute__((stdcall)); int methodC(int x, int y) __attribute__((fastcall)); y Registernutzung durch Switches einstellbar … -fcall-used-reg Treat the register named reg as an allocable register that is clobbered by function calls. It may be allocated for temporaries or variables that do not live across a call. Functions compiled this way will not save and restore the register reg . -fcall-saved-reg Treat the register named reg as an allocable register saved by functions. It may be allocated even for temporaries or variables that live across a call. Functions compiled this way will save and restore the register reg if they use it. 6 11/7/2007 Interoperabilität y Aufrufer und Prozedur bzgl. Konvention einigen! y Innerhalb Compile-Einheit kein Problem Compiler regelt alles… ☺ int methodA(int x, int y) __attribute__((cdecl)); int methodB(int x, int y) __attribute__((stdcall)); int methodA(int x, int y) { methodB(x,y); } y Mischung aus Assembler und C/C++ … y Aufrufkonvention aufzurufender Prozedur beachten y Mismatch Stack Fazit y __stdcall vs. __cdecl y Stack aufräumen geht mit wenigen Instruktionen Größenunterschied der Binaries marginal y __stdcall vs. __fastcall y Geschwindigkeitsvorteil nur vordergründig y Registerinhalte auf Stack retten Speicherzugriff 7 11/7/2007 Speicher… y Lokale Variablen in Prozeduren bereits behandelt y Stack y Adressierung relativ zu $fp y Instruktionen y Wo im Speicher? y Statische / Globale Variablen y Größe steht bei Kompilierung fest y Wo im Speicher? y Dynamische Datenstrukturen? y Allokation zur Laufzeit y Variable Größe y Wo im Speicher? y Speicherorganisation? Kapitel 3 Maschinensprache Speicherorganisation 8 11/7/2007 Heap y Speicherbereich für dynamische Datenstrukturen y Größe kann zur Laufzeit wachsen y Stack ebenfalls dynamisch y Probleme? y Ideen? MIPS Speicherorganisation y Nur eine Konvention y Nirgendwo in MIPS-Architektur festgelegt y Wir brauchen… y Code y Textsegment y statische Daten y Datensegment y Stack y Stacksegment y dynamische Datenstrukturen y Heap OS Stack Heap Stat. Daten Text Reserviert 9 11/7/2007 Genauere Betrachtung 0xffff ffff 0x7fff fffd 0x7fff fffc OS 2 GB Bereich 2-4 GB für OS reserviert!!! Stack ~ 1,8 GB 0x1001 0000 0x1000 0000 Heap Statische Daten 64 KB Text 252 MB Reserviert 256 KB 0x0040 0000 0x0 Statische Variablen y C y Variablen außerhalb von Prozeduren static y + explizit als static markierte Variablen y Alle anderen = automatic y Zugriff? y Zusätzliches Zeiger-Register $gp (Global Pointer) y Mit 0x1000 8000 initialisiert ( spim) Register y Zugriff durch 16 Bit Offset $zero y lw $t0, OFFSET($gp) 0x1000 ffff 0x1000 8000 0x1000 0000 Statische Daten Adresse Semantik 0 Konstante 0 $v0 - $v1 2-3 Rückgabewerte $a0-$a3 4-7 Argumente $t0-$t7 8-15 Temporäre Register $s0-$s7 16-23 Gesicherte Register $t8-$t9 24-25 Temporäre Register $gp 28 Globaler Zeiger $sp 29 Stackzeiger $fp 30 Framezeiger $ra 31 Rücksprungadresse 10 11/7/2007 Dynamische Datenstrukturen y Auf dem Heap y Allokieren/Freigeben von Speicher durch Entwickler y Mit malloc/free in C y Mit new/delete in C++ y Fehlerhafte Verwendung fatal y y y Fehlendes malloc/new? Fehlendes free/delete? Wie verhindern? Stack y Größe dynamisch y Stack wächst von oben nach unten y $sp mit 0x7fff fffc initialisieren y Heap wächst von unten nach oben y Kollision/Überschneidung fatal y Wie verhindern? y Stackverwaltung … y … in Assembler y Programmierer verantwortlich y … in Hochsprachen y durch Compiler y Garantiert korrekt 11 11/7/2007 Exkurs: ? Buffer Overflows $a0 $ra y Beispiel… y 5 Bytes auf Stack reservieren y Problem? &arr 0 0 0 0 0 void PROBLEM() { char arr[5]; strcpy(arr,GETDATA()); ... } Canaries y Früher: Kanarienvögel in Kohleminen y anfälliger Stoffwechsel y “Warnsystem” vor Kohlenmonoxid y Idee? y Zufälligen Wert vor $ra einfügen y Vor Rücksprung Wert testen! y Function Pointer? &arr $a0 CANARY $ra 0 0 0 0 0 void NOT_SECURE() { char arr[42]; strcpy(arr,GETDATA()); ... } 12 11/7/2007 Zusammenfassung Speicher y Verschieden Arten von Variablen y statisch zur Übersetzungszeit y y y Lebensdauer an Programm gebunden Größe zur Laufzeit nicht veränderbar Statischer Datenbereich y automatisch beim Betreten einer Funktion y Lebensdauer an Funktion gebunden y Größe zur Laufzeit nicht veränderbar y Vorsicht vor Buffer Overflows! y Stack y dynamisch beliebig y beliebige Lebensdauer y Größe variabel y Heap Objektorientierung y Was ist ein Objekt? y Zusammenhänge mit … y … Speicherorganisation … y … Aufrufsemantiken? 13 11/7/2007 Beispiel: OO in C++ class Point { public: int x, y; static int m; void move() { this.x+=m; this.y+=m; } } Point::m = 1; Point p1; p1.x = 7; p1.y = 42; Point p2; p2.x = 2; p2.y = 0; Point p3; p3.x = 10; p3.y = 25; Was steht wo im Speicher? class Point { public: int x, y; static int m; void move() { this.x+=m; this.y+=m; } } Point::m = 1; Point p1; p1.x = 7; p1.y = 42; Point p2; p2.x = 2; p2.y = 0; Point p3; p3.x = 10; p3.y = 25; 14 11/7/2007 Objekte auf dem Stack class Point Stack { public: int x, y; static int m; void move() { this.x+=m; this.y+=m; } } Point::m = 1; Point p1; p1.x = 7; p1.y = 42; Point p2; p2.x = 2; p2.y = 0; Point p3; p3.x = 10; p3.y = 25; p1 x=7 y=42 p2 x=2 y=0 p3 x=10 y=25 statische Daten class Point m=1 Textsegment Point::move() { this.x+=m; this.y+=m; } Objekte auf dem Heap class Point { Stack p1 p2 p3 public: int x, y; static int m; void move() { this.x+=m; this.y+=m; } } Point::m = 1; Point p1 = new Point(); p1->x = 7; p1->y = 42; Point p2 = new Point(); P2->x = 2; p2->y = 0; Point p3 = new Point(); P3->x = 10; p3->y = 25; p1 x=7 y=42 p2 x=2 y=0 p3 x=10 y=25 Heap statische Daten class Point m=1 Textsegment Point::move() { this.x+=m; this.y+=m; } 15 11/7/2007 Instanzmethoden y Methodencode nur einmal im Speicher y Zugriff auf Instanzvariablen? Stack p1 p2 p3 y Ideen? p1 x=7 y=42 p2 x=2 y=0 p3 x=10 y=25 Heap statische Daten class Point m=1 Textsegment Point::move() { this.x+=m; this.y+=m; } thiscall y Aufrufkonvention für C++-Instanzmethoden y this in Register übergeben y Prozedur räumt Stack auf y Variabel lange Argumentlisten? __cdecl this auf Stack übergeben y Überladene Funktionen y Ideen? 16 11/7/2007 NameMangling y Codierung der Parameter in Symbolnamen y Beispiel… int methodA(int x, int y) { return methodB(x,y); } float methodA(float x, float y) { return x+y; } 0000000000000130 T _Z7methodAff 0000000000000110 T _Z7methodAii Das war’s für heute… y Folien, Übungsaufgaben wie immer im Laufe des Tages auf http://syssoft.uni-trier.de/~scholtes 17 11/7/2007 Rechnerarchitektur und Assemblerprogrammierung Übung 3 Aufgabe 1 y Implementierung einer Fibonacci-Prozedur + Aufruf 18 11/7/2007 Lösung: Prozedur FIB: N1: REC: bne $a0, $zero, N1 addi $v0, $zero, 0 jr $ra addi $t0, $zero, 1 bne $a0, $t0, REC addi $v0, $t0, 0 jr $ra add $sp, $sp, -4 sw $s0, 0($sp) addi $sp, $sp, -8 sw $a0, 4($sp) sw $ra, 0($sp) addi $a0, $a0, -1 jal FIB addi $s0, $v0, 0 # falls n==0 gib 0 zurück # # # # # # addi $a0, $a0, -1 jal FIB add $v0, $v0, $s0 # neues Argument ist n-2 # Rekursiver Aufruf mit n-1 # Addiere Fib(n-1) zu Fib(n-2) in s0 lw $ra, 0($sp) lw $a0, 4($sp) addi $sp, $sp, 8 # altes $ra wiederherstellen # altes Argument n wiederherstellen # Werte auf Stack löschen lw $s0, 0($sp) addi $sp, $sp, 4 jr $ra # s0 wiederherstellen # falls n==1 gib 1 zurück # $s0 auf Stack sichern 2 Wörter auf Stack reservieren zunächst Argument $a0=n sichern dann $ra sichern neues Argument ist n-1 Rekursiver Aufruf mit n-2 Speichere Fib(n-1) in s0 # Rücksprung Lösung: Aufruf main: addi $v0, $zero, 5 syscall # Wert n in v0 legen addi $sp, $sp, -8 sw $a0, 4($sp) sw $ra, 0($sp) # Altes $ra und $a0 sichern! addi $a0, $v0, 0 jal FIB addi $a0, $v0, 0 addi $v0, $zero, 1 syscall # Argument in Register $a0 legen # Aufrufen # Ausgeben lw $ra, 0($sp) lw $a0, 4($sp) addi $sp, $sp, 8 jr $ra # $ra und $a0 wiederherstellen! # Stack aufräumen 19 11/7/2007 Aufgabe 2 y Übersetzung einer C-Prozedur mit Stack-Variablen y Mit und ohne $fp int proc ( int x , int y ) { int a = x + y ; int b = 16 * a ; if (b<1024) { int c = proc ( a , b ) ; return 2 * c ; } else return 1; } Lösung ohne $fp proc: RET: addi $sp, $sp, -8 # Zwei Stack-Variablen a, b reservieren add $s0, $a0, $a1 sw $s0, 4($sp) sll $s1, $s0, 4 sw $s1, 0($sp) slti $t0, $s1, 1024 beq $t0, $zero, RET addi $sp, $sp, -12 sw $a0, 8($sp) sw $a1, 4($sp) sw $ra, 0($sp) lw $a0, 12($sp) lw $a1, 8($sp) jal proc lw $a0, 8($sp) lw $a1, 4($sp) lw $ra, 0($sp) addi $sp, $sp, 12 addi $sp, $sp, -4 addi $s2, $v0, 0 sw $s2, 0($sp) sll $v0, $s2, 1 addi $sp, $sp, 12 j $ra # # # # # addi $v0, $zero, 1 addi $sp, $sp, 8 j $ra a = x + y Auf Stack schreiben :-) b = 16 * a Auf Stack schreiben ☺ Falls b nicht kleiner 1024 gehe zu RET # $ra, $a0 und $a1 sichern # a und b vom Stack lesen :-) # Rekursiver Aufruf # $a0, $a1, $ra wiederherstellen # # # # # Stack Variable c reservieren c = proc(a,b) Auf Stack schreiben return 2*c Alle drei Stack-Variablen löschen # Zwei Stack-Variablen löschen 20 11/7/2007 Lösung mit $fp proc: RET: addi $sp, $sp, -4 sw $fp, 0($sp) addi $fp, $sp, 0 addi $sp, $sp, -8 add $s0, $a0, $a1 sw $s0, -4($fp) sll $s1, $s0, 4 sw $s1, -8($fp) slti $t0, $s1, 1024 beq $t0, $zero, RET addi $sp, $sp, -12 sw $a0, 8($sp) sw $a1, 4($sp) sw $ra, 0($sp) lw $a0, -4($fp) lw $a1, -8($fp) jal proc lw $a0, 8($sp) lw $a1, 4($sp) lw $ra, 0($sp) addi $sp, $sp, 12 addi $sp, $sp, -4 addi $s2, $v0, 0 sw $s2, -12($t0) sll $v0, $s2, 1 addi $sp, $sp, 12 lw $fp, 0, ($sp) addi $sp, $sp, 4 j $ra addi $v0, $zero, 1 addi $sp, $sp, 8 lw $fp, 0, ($sp) addi $sp, $sp, 4 j $ra # Alten FP sichern # # # # # # # FP setzen Zwei Stack-Variablen a, b reservieren a = x + y a auf Stack schreiben :-) b = 16 * a b auf Stack schreiben Falls b nicht kleiner 1024 gehe zu RET # $ra, $a0 und $a1 sichern # a und b vom Stack lesen :-) # Rekursiver AUfruf # $a0, $a1, $ra wiederherstellen # # # # # # Stack Variable c reservieren c = proc(a,b) c auf Stack schreiben return 2*c Alle drei Stack-Variablen löschen FP wiederherstellen # Zwei Stack-Variablen löschen # FP wiederherstellen Aufgabe 3 y Siehe heutige Vorlesung ☺ 21 11/7/2007 Das war’s für heute… y Übungsaufgaben auf http://syssoft.uni-trier.de/~scholtes 22
© Copyright 2025 ExpyDoc