Systemprogrammierung (37-023) Assemblerprogrammierung Betriebssystemgrundlagen Maschinenmodelle Dozenten: Thomas Stricker Roman Geus WebSite: www.cs.inf.ethz.ch/37-023 Begleit-/Textbuch: R. Paul: SPARC Architecture, Assembly Language Programming and C --- B. Kernigham, D. Richie: The C Programming Language Heute: Kontrollstrukturen in Assembler Branches Schleifenprogrammierung Case Statements 27/29.11.00-1 37-023 Systemprogrammierung Stricker
Branches auf pipelined RISC (architekturspezifischer Aspekt) Hardware muss nicht in schnelleren Zyklen getaktet werden, statt dessen Parallelisierung Tiefe der Pipeline bei SPARC V8: 5 (2 sichtbar) 27/29.11.00-2 37-023 Systemprogrammierung Stricker
Probleme bei Branching (Verzweigungen): Wird ein Branch ausgeführt, so muss die folgende Instruktion aus der Zieladresse des Branches entnommen werden! Instruktion nach branch-anweisung findet sich allerdings noch in der Pipeline. Korrekterweise müsste die Pipeline geleert werden SPARC überlässt diese Kontrolle dem Benutzer Verwendung von zwei Programmzeigern: %pc -> execute %npc-> fetch Branch Delay Slot: Nächste Instruktion wird ausgeführt, bevor die erste Instruktion des Branches wirksam wird. einfachste Vorgehensweise: nop -> Zyklus geht verloren! 27/29.11.00-3 37-023 Systemprogrammierung Stricker
SPARC Maschinen Zyklus Branch Delay Slots können effizient genutzt werden, verschlechtern allerdings die Lesbarkeit des Codes 27/29.11.00-4 37-023 Systemprogrammierung Stricker
Conditional Branches in Assembler Condition Code Register: Bestehend aus 4 Kontrollbits Teil des Prozessor Status Registers Z: zeigt an, ob Resultat 0 N: zeigt an, ob Resultat negativ V: zeigt an, ob Resultat generell zu gross für Register (Overflow) C: Carry Bit des most significant Bit Satz von Instruktionen, welche condition codes setzen! addcc subcc smulcc sdivcc /* typischerweise mit Suffix cc */ 27/29.11.00-5 37-023 Systemprogrammierung Stricker
Branch Instruktionen der SPARC Nach Branch-Instruktion wird Adresszeiger auf Adresse der ersten Instruktion des Branches gesetzt. Labels zur Adress-Markierung. bxy label /* bxy eine der folgenden Instruktionen */ 27/29.11.00-6 37-023 Systemprogrammierung Stricker
While Loop Fundamentale Kontrollstruktur in Computer Programmen Wichtigste loop Da normalerweise sehr oft durchlaufen, muss der resultierende Assemblercode möglichst effizient sein Anzahl der Instruktionen minimieren!! Beispielprogramm in C 1 main() { 2 int temp; 3 int x = 0; 4 int y = 0x9; 5 int z = 0x42; 6 7 temp = y; 8 while (temp>0) { 9 x = x + z; 10 temp = temp - 1; 11 } 12 printf( %d\n,x); 13 } 27/29.11.00-7 37-023 Systemprogrammierung Stricker
While Loop in Assembler.data x:.word 0!bsp8.s y:.word 0x9 z:.word 0x42.text start: set y, %r1 ld [%r1], %r2 set z, %r1 ld [%r1], %r3 mov %r0, %r4 add %r2, 1, %r2 ba test nop top: add %r4, %r3, %r4 test: subcc %r2, 1, %r2 bg top!temp>0 nop!branch DELAY SLOT set x, %r1 st %r4, [%r1] end: ta 0 27/29.11.00-8 37-023 Systemprogrammierung Stricker
Ablauf des Programmzählers Standardzyklus des Prozessors: pc <- npc; npc += 4; Bei Branches pc <- npc /* delay slot */ ncp <- branch_label Sinnvolle Nutzung des Delay Slots Im Beispiel kann die Addition von y und x in den delay slot übertragen werden: x:.word 0 y:.word 0x9 z:.word 0x42 start: set y, %r1 ld [%r1], %r2 set z, %r1 ld [%r1], %r3 mov %r0, %r4 add %r2, 1, %r2 top: subcc %r2, 1, %r2 bg,a top!annulled branch add %r4, %r3, %r4 set x, %r1 st %r4, [%r1] end: ta 0 27/29.11.00-9 37-023 Systemprogrammierung Stricker
Möglichkeit zur Annulierung Branch delay slot Instruktionen können annulliert werden, wenn der branch nicht genommen wird! bg, a /* wird im Code durch,a angezeigt */ Die sinnvolle Verwaltung von Branch-Delay-Slots bleibt dem Benutzer überlassen! 27/29.11.00-10 37-023 Systemprogrammierung Stricker
Allgemeines while statement Situation schwieriger bei folgender while Anweisung: 1 main() { 2 int a= 0; 3 int b= 3; 4 while (a<=17) { 5 a= a+ b; 6 } 7 } Man benötigt eine zusätzliche Vergleichsinstruktion: cmp cmp register1, register2 register2, const. /* synthetische Instruktion */ subccregister1, register2, g0 subccregister2, const, g0 /* vergleicht Register miteinander und setzt Vorzeichenbit des condition codes */ 27/29.11.00-11 37-023 Systemprogrammierung Stricker
1. Variante in Assembler 1.data 2 a:.word0 3 b:.word3!bsp10.s 4 5.global_main 6.text 7 _main: set a, %r1 8 ld [%r1], %r2 9 set b, %r1 10 ld [%r1], %r3 11 loop: cmp %r2, 17! a>17 12 bg store 13 nop!1. delay slot 14 add %r2, %r3, %r2 15 ba loop 16 nop!2. delay slot 17 store: set a, %r1 18 st %r2, [%r1] 19 end: ta 0 Compare Instruktion vergleicht Register mit Konstante Innerhalb der loop keine optimale Programmausführung -> Optimierung 27/29.11.00-12 37-023 Systemprogrammierung Stricker
2. Variante in Assembler 1.data!Variant 2 of while 2 a:.word8!loop is add, cmp, nop 3 b:.word3!bsp11.s 4 5.global_main 6.text 7 _main: set a, %r1 8 ld [%r1], %r2 9 set b, %r1 10 ld [%r1], %r3 11 test: cmp %r2, 17 12 bg store 13 nop 14 loop: add %r2, %r3, %r2!4 cycles 15 cmp %r2, 17 16 ble loop 17 nop 18 store: set a, %r1 19 st %r2, [%r1] 20 end: ta 0 Loop konnte gegenüber Variante 1 um zwei Instruktionen verkürzt werden. 27/29.11.00-13 37-023 Systemprogrammierung Stricker
3. Variante in Assembler 1.data!Variant 3 of while 2 a:.word 0! 1. test can be avoided 3 b:.word 3! bsp12.s 4 5.global _main 6 7.text 8 _main: set a, %r1 9 ld [%r1], %r2 10 set b, %r1 11 ld [%r1], %r3 12 13 ba test!unconditional branch 14 nop 15 16 loop: add %r2, %r3, %r2 17 18 test: cmp %r2, 17!initializes CC 19 ble loop!4 cycles 20 nop 21 22 store: set a, %r1 23 st %r2, [%r1] 24 end: ta 0 Erster bedingter branch kann durch absoluten branch ersetzt werden! 27/29.11.00-14 37-023 Systemprogrammierung Stricker
4. Variante in Assembler 1.data!Variant 4 of while 2 a:.word0!1. test can be avoided 3 b:.word3!removal of uncond. nop 4!bsp13.s 5.global _main 6.text 7 _main: set a, %r1 8 ld [%r1], %r2 9 set b, %r1 10 ld [%r1], %r3 11 12 ba test!branch always 13 cmp %r2, 17!CC init 14 loop: add %r2, %r3, %r2 15 16 cmp %r2, 17!4 cycles 17 test: ble loop 18 nop 19 20 store: set a, %r1 21 st %r2, [%r1] 22 end: ta 0 nop im unconditional branch delay slot kann einfach umgangen werden! 27/29.11.00-15 37-023 Systemprogrammierung Stricker
5. Variante in Assembler 23.data!Variant 5 of while 24 a:.word0!1.test can be avoided 25 b:.word3!removal of uncond. nop 26!removal of cond. nop 27!branch delay slot bsp14.s 28.global_main 29.text 30 31 _main: set a, %r1 32 ld [%r1], %r2 33 set b, %r1 34 ld [%r1], %r3 35 36 loop: cmp %r2, 17!3 cycles 37 ble,aloop 38 add %r2, %r3, %r2 39 40 store: set a, %r1 41 st %r2, [%r1] 42 end: ta 0 Weitere Code-Optimierung durch Annullierung des Branch Delay Slots möglich 27/29.11.00-16 37-023 Systemprogrammierung Stricker
Flussdiagramm (annuled conditional branch) 27/29.11.00-17 37-023 Systemprogrammierung Stricker
Do Loops Wenn Schleife zumindest einmal ausgeführt wird, sollte Do loop verwendet werden. Initialer Test kann entfallen C-Code fragment 1 main() { /* bsp15.c */ 2 3 int a = 0; 4 int b = 3; 5 do { 6 a = a + b; 7 } while (a<=17); 8 } 27/29.11.00-18 37-023 Systemprogrammierung Stricker
DO-Loop in Assembler Code 1.data! 2 a:.word0 3 b:.word3!bsp16.s 4 5.global _main 6 7.text 8 _main: set a, %r1 9 ld [%r1], %r2 10 set b, %r1 11 ld [%r1], %r3 12 13 add %r2, %r3, %r2 14 loop: cmp %r2, 17 15 ble,aloop 16 add %r2, %r3, %r2 17 18 store: set a, %r1 19 st %r2, [%r1] 20 end: ta 0 21 27/29.11.00-19 37-023 Systemprogrammierung Stricker
For loops C-Syntax 1 main() { 2 int a = 0; 3 int b = 3; 4 int i; 5 6 for(i=1; i<=15; i++) {/* bsp17.c */ 7 a = a + b; 8 } 9 } Können in while-schleifen umgesetzt werden! 1 main(){ 2 int a = 0; 3 int b = 3; 4 int i = 1; 5 6 while(i<=15) { 7 a = a + b; 8 i++; 9 } /* bsp18.c */ 10 } 27/29.11.00-20 37-023 Systemprogrammierung Stricker
For Loops in Assembler 1.data 2 a:.word 0 3 b:.word 3!bsp19.s 4 i:.word 1 5 6 con:.word 15 7 8.global _main 9 10.text 11 _main: set a, %r1 12 ld [%r1], %r2 13 set b, %r1 14 ld [%r1], %r3 15 set i, %r1 16 ld [%r1], %r4 17 set con, %r1 18 ld [%r1], %r5 19 20 ba test!branch always 21 22 loop: cmp %r4, %r5 23 add %r2, %r3, %r2 24 25 test: ble,a loop 26 inc %r4 27 28 store: set a, %r1 29 st %r2, [%r1] 30 end: ta 0 27/29.11.00-21 37-023 Systemprogrammierung Stricker
C-Syntax und Code If Then Statements 1 main() { 2 int a; 3 int b = 1; 4 int c = 2; /* bsp20.c */ 5 int d = 3; 6 7 printf ( a =?\n ); 8 scanf( %d,&a); 9 10 if ((a + b)>c) { 11 a += b; 12 c++; 13 } 14 a += d; 15 printf( a = %d\n,a); 16 printf( b = %d\n,b); 17 printf( c = %d\n,c); 18 printf( d = %d\n,d); 19 } Branch muss bei Nichterfülltsein der Bedingung genommen werden scanf Funktion ermöglicht Eingabe Kompakte Zuweisungen in C: i += 5 27/29.11.00-22 37-023 Systemprogrammierung Stricker
If/Then in Assembler Wir benötigen die logischen Komplemente der bedingten branch Instruktionen Bedingung Komplement bl less bge ble less equal bg bne not equal be be equal bne bge greater equal bl bg greater ble Ausnutzung des Branch delay slot, erste Anweisung nach der if Abfrage wird wiederholt ble Bedingung als Komplement zur if- Abfrage 27/29.11.00-23 37-023 Systemprogrammierung Stricker
If/then in Assembler (con t) 1.global _main 2 3.text 4 _main: set a, %r1! bsp21.s 5 ld [%r1], %r2 6 set b, %r1 7 ld [%r1], %r3 8 set c, %r1 9 ld [%r1], %r4 10 set d, %r1 11 ld [%r1], %r5 12 13 add %r2, %r3, %r6 14 cmp %r6, %r4 15 16 ble,a store 17 add %r2, %r5, %r2!branch DS 18 inc %r4 19 add %r2, %r3, %r2 20 add %r2, %r5, %r2 21 store: set a, %r1 22 st %r2, [%r1] 23 end: ta 0 27/29.11.00-24 37-023 Systemprogrammierung Stricker
C-Syntax und Code If Else Statement 1 if ((a + b)>=c) { /* bsp22.c */ 2 a += b; 3 c++; 4 } else { 5 a -= b; 6 c--; 7 } 8 c += 10; Assembler Code Fragment 1 add %r2, %r3, %r6!bsp23.s 2 cmp %r6, %r4!a->r2, b->r3, c->r4 3 4 bl,a else 5 sub %r2, %r3, %r2!1. instruction of else 6 add %r2, %r3, %r2!1. instruction of then 7 inc %r4 8 ba store 9 add %r4, 10, %r4 10 11 else: dec %r4 12 add %r4, 10, %r4 13 14 store: set a, %r1 15 st %r2, [%r1] 16 end: ta 0 27/29.11.00-25 37-023 Systemprogrammierung Stricker
erste Instruktion des else Teils wurde in den branch delay slot der bl Condition übernommen Vermeidung jeglicher nops Code wird schwer lesbar 27/29.11.00-26 37-023 Systemprogrammierung Stricker
Annullierung von unbedingten branches ba,a Delay slot wird immer annulliert, aber es wird trotzdem gesprungen!!! Ist sinnvoll, wenn statt einer Instruktion ein branch zu einer Subroutine (call.sqrt) erfolgen soll. Branch verliert in diesem Fall Delay slot. 27/29.11.00-27 37-023 Systemprogrammierung Stricker
Delayed Control Transfer Couples Wenn Branch Instruktion im delay slot einer weiteren branch instruktion liegt ba ble label1 label2 1. Instruktion muss unbedingte Branch Instruktion sein, sonst Reihenfolge der Instruktionen nicht definiert 27/29.11.00-28 37-023 Systemprogrammierung Stricker
Switch Statement Switch Statement: Verzweigung mittels Tabelle Unterschiedliche Anzahl Instruktionen pro case. switch-beispiel (C-Syntax): 1 switch (i + 3) { 2 case 1: i += 1; 3 break; 4 case 2: i += 2; 5 break; 6 case 15: i += 15; 7 case 3: i += 3; 8 break; 9 case 4: i += 4; 10 case 6: i += 6; 11 break; 12 case 5: i += 5; 13 break; 14 default: i--; 15 } 27/29.11.00-29 37-023 Systemprogrammierung Stricker
Berechnung Switch-Adressen Finde grösstes und kleinstes Label Berechne Label-Range Berechne Differenz: switch-ausdruck - kleinstes Label) Vergleiche Range mit Differenz Nehme Wert als Index einer Pointer Tabelle, welche auf switch-anweisungen zeigen Fehlende Pointers in Tabelle werden durch Pointer->Next oder -> default ersetzt Wenn out of range ->default Einträge in gleicher Reihenfolge, wie C- Code 27/29.11.00-30 37-023 Systemprogrammierung Stricker
switch in Assembler 1.data 2.align4 3 table:.word L1,L2,L3,L4,L5,L6,L7,L8,L9 4.word L10,L11,L12,L13,L14,L15 5.text 6.align 4 7 start: mov 0, %l0!initialize i=0 8 add %l0,3,%o0!compute switch expression 9 subcc %o0,1,%o0!reduce by min & cmp to zero 10 blu default!expression too small 11 cmp %o0, 1!compare to range 12 bgu default!too large 13 nop 14 set table, %o1!jump table 15 sll %o0, 2, %o0!word offset in table 16 ld [%o1+%o0],%o0!ptr to executable!code 17 jmpl %o0, %g0!transfer control 18 nop 19 L1: ba end!first ptr in jump table points here 20 add %l0,1,%l0!i++ 21 L2: ba end 22 add %l0,2,%l0!i += 2 23 L15: add %l0,15,%l0!i += 15; note no break 24 L3: ba end 25 add %l0,3,%l0!i += 3 26 L4: add %l0, 4, %l0!i += 4; note no break 27 L6: ba end 28 add %l0,6,%l0!i += 6 29 27/29.11.00-31 37-023 Systemprogrammierung Stricker
switch in Assembler (cont.) 30 L4: add %l0, 4, %l0!i += 4; note no break; 31 L6: ba end 32 add %l0,6,%l0!i += 6 33 L5: ba end 34 add %l0,5,%l0!i += 5 35 L7: 36 L8: 37 L9: 38 L10: 39 L11: 40 L12: 41 L13: 42 L14: 43 default:sub %l0, 1, %l0!i-- 44 end: ta 0 45 27/29.11.00-32 37-023 Systemprogrammierung Stricker