Today Control flow ifwhiledo whileforswitch Maybe start on
Today Control flow if/while/do while/for/switch Maybe start on procedures Stack discipline Stack-based languages and call chains Stack frames – 1–
Condition Codes Single Bit Registers CF ZF SF OF Carry Flag Zero Flag Sign Flag Overflow Flag Implicit Setting By Arithmetic Operations addl Src, Dest C analog: t = a+b • CF set if carry out from most significant bit – Used to detect unsigned overflow • ZF set if t == 0 • SF set if t < 0 • OF set if two’s complement overflow (a>0 && b>0 && t<0) || (a<0 && b<0 && t>0) Not Set by leal instruction – 2–
Setting Condition Codes (cont. ) Explicit Setting by Compare Instruction cmpl Src 2, Src 1 Note Inverted Order • cmpl b, a like computing a-b without setting destination • CF set if carry out from most significant bit – Used for unsigned comparisons • ZF set if a == b • SF set if (a-b) < 0 • OF set if two’s complement overflow (a>0 && b<0 && (a-b)<0) || (a<0 && b>0 && (a-b)>0) Explicit Setting by Test instruction testl Src 2, Src 1 • Sets condition codes based on value of Src 1 & Src 2 – Useful to have one of the operands be a mask • testl b, a like computing a&b without setting destination • ZF set when a&b == 0 • SF set when a&b < 0 – 3–
Reading Condition Codes Set. X Dest Instructions • Set single byte based on combinations of condition codes – 4–
Reading Condition Codes (Cont. ) %ax, %bx, %cx, %dx Set. X Instructions • Set single byte based on combinations of condition codes • One of 8 addressable byte registers – Embedded within first 4 integer registers – Does not alter remaining 3 bytes – Typically use andl 0 x. FF, %eax to finish job int gt (int x, int y) { return x > y; } movl cmpl setg andl 12(%ebp), %eax, 8(%ebp) %al $255, %eax # # %eax %ah %al %edx %dh %dl %ecx %ch %cl %ebx %bh %bl %esi %edi %esp Body eax = y Compare x : eax al = x > y Zero rest of %eax – 5– %ebp Note inverted ordering! Cmpl y, x => (x-y)
Jumping – Goto instructions j. X Instructions • Jump to different part of code depending on condition codes – 6–
Conditional Branch Example _max: pushl %ebp movl %esp, %ebp int max(int x, int y) { if (x > y) return x; else return y; } movl 8(%ebp), %edx movl 12(%ebp), %eax cmpl %eax, %edx jle L 9 movl %edx, %eax Set Up Body L 9: movl %ebp, %esp popl %ebp ret – 7– Finish
Conditional Branch Example (Cont. ) int goto_max(int x, int y) { int rval = y; int ok = (x <= y); if (ok) goto done; rval = x; done: return rval; } movl 8(%ebp), %edx movl 12(%ebp), %eax cmpl %eax, %edx jle L 9 movl %edx, %eax L 9: # • C allows “goto” as means of transferring control – Closer to machine-level programming style • Generally considered bad coding style • Machine only does gotos • Compiler tries to have one return # edx = # eax = # x : y # if <= # eax = Done: – 8– x y goto L 9 x Skipped when x y
“Do-While” Loop Example Goto Version C Code int fact_do (int x) { int result = 1; do { result *= x; x = x-1; } while (x > 1); return result; } int fact_goto(int x) { int result = 1; loop: result *= x; x = x-1; if (x > 1) goto loop; return result; } • Use backward branch to continue looping • Only take branch when “while” condition holds – 9–
“Do-While” Loop Compilation Goto Version int fact_goto (int x) { int result = 1; loop: result *= x; x = x-1; if (x > 1) goto loop; return result; } Registers %edxx %eaxresult Assembly _fact_goto: pushl %ebp movl %esp, %ebp movl $1, %eax movl 8(%ebp), %edx L 11: imull %edx, %eax decl %edx cmpl $1, %edx jg L 11 movl %ebp, %esp popl %ebp ret – 10 – # Setup # eax = 1 # edx = x # # result *= x x-Compare x : 1 if > goto loop # Finish
General “Do-While” Translation Goto Version C Code do Body while (Test); loop: Body if (Test) goto loop • Body can be any C statement – Typically compound statement: { Statement 1; Statement 2; … Statementn; } • Test is expression returning integer = 0 interpreted as false 0 interpreted as true – 11 –
“While” Loop Example #1 First Goto Version C Code int fact_while (int x) { int result = 1; while (x > 1) { result *= x; x = x-1; }; return result; } int fact_while_goto (int x) { int result = 1; loop: if (!(x > 1)) goto done; result *= x; x = x-1; goto loop; done: return result; } • Is this code equivalent to the do-while version? • Must jump out of loop if test fails – 12 –
Actual “While” Loop Translation C Code int fact_while(int x) { int result = 1; while (x > 1) { result *= x; x = x-1; }; return result; } • Uses same inner loop as do-while version • Guards loop entry with extra test Second Goto Version int fact_while_goto 2 (int x) { int result = 1; if (!(x > 1)) goto done; loop: result *= x; x = x-1; if (x > 1) goto loop; done: return result; } – 13 –
General “While” Translation C Code while (Test) Body Do-While Version Goto Version if (!Test) goto done; do Body while(Test); done: if (!Test) goto done; loop: Body if (Test) goto loop; done: – 14 –
“For” Loop Example General Form int result; for (result = 1; p != 0; p = p>>1) { if (p & 0 x 1) result *= x; x = x*x; } for (Init; Test; Update ) Body Init result = 1 Body Test p != 0 Update p = p >> 1 { if (p & 0 x 1) result *= x; x = x*x; } – 15 –
“For” “While” For Version for (Init; Test; Update ) Body Do-While Version Init; if (!Test) goto done; do { Body Update ; } while (Test) done: While Version Init; while (Test ) { Body Update ; } Goto Version Init; if (!Test) goto done; loop: Body Update ; if (Test) goto loop; done: – 16 –
“For” Loop Compilation Goto Version result = 1; if (p == 0) goto done; loop: if (p & 0 x 1) result *= x; x = x*x; p = p >> 1; if (p != 0) goto loop; done: Init; if (!Test) goto done; loop: Body Update ; if (Test) goto loop; done: Init result = 1 Test p != 0 Body { if (p & 0 x 1) result *= x; x = x*x; Update p = p >> 1 } – 17 –
Switch Statements typedef enum {ADD, MULT, MINUS, DIV, MOD, BAD} op_type; char unparse_symbol(op_type op) { switch (op) { case ADD : return '+'; case MULT: return '*'; case MINUS: return '-'; case DIV: return '/'; case MOD: return '%'; case BAD: return '? '; } } Implementation Options • Series of conditionals – Good if few cases – Slow if many • Jump Table – Lookup branch target – Avoids conditionals – Possible when cases are small integer constants • GCC – Picks one based on case structure • Bug in example code – No default given – 18 –
Jump Table Structure Switch Form switch(op) { case 0: Block 0 case 1: Block 1 • • • case n-1: Block n– 1 } Jump Table jtab: Targ 0 Jump Targets Targ 0: Code Block 0 Targ 1: Code Block 1 Targ 2: Code Block 2 Targ 1 Targ 2 • • • Targn-1 • • • Approx. Translation target = JTab[op]; goto *target; Targn-1: – 19 – Code Block n– 1
Switch Statement Example Branching Possibilities Enumerated Values typedef enum {ADD, MULT, MINUS, DIV, MOD, BAD} op_type; ADD MULT MINUS DIV MOD BAD char unparse_symbol(op_type op) { switch (op) { • • • } } Setup: unparse_symbol: pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax cmpl $5, %eax ja. L 49 jmp *. L 57(, %eax, 4) – 20 – # # # 0 1 2 3 4 5 Setup eax = op Compare op : 5 If > goto done goto Table[op]
Assembly Setup Explanation Symbolic Labels • Labels of form. LXX translated into addresses by assembler Table Structure • Each target requires 4 bytes • Base address at. L 57 Jumping jmp. L 49 • Jump target is denoted by label. L 49 jmp *. L 57(, %eax, 4) • Start of jump table denoted by label. L 57 • Register %eax holds op • Must scale by factor of 4 to get offset into table • Fetch target from effective Address. L 57 + op*4 – 21 –
Jump Table Contents. section. rodata. align 4. L 57: . long. L 51 #Op =. long. L 52 #Op =. long. L 53 #Op =. long. L 54 #Op =. long. L 55 #Op =. long. L 56 #Op = Targets & Completion 0 1 2 3 4 5 Enumerated Values ADD MULT MINUS DIV MOD BAD 0 1 2 3 4 5 . L 51: movl $43, %eax # ’+’ jmp. L 49. L 52: movl $42, %eax # ’*’ jmp. L 49. L 53: movl $45, %eax # ’-’ jmp. L 49. L 54: movl $47, %eax # ’/’ jmp. L 49. L 55: movl $37, %eax # ’%’ jmp. L 49. L 56: movl $63, %eax # ’? ’ # Fall Through to. L 49 – 22 –
Switch Statement Completion. L 49: movl %ebp, %esp popl %ebp ret # # Done: Finish Puzzle • What value returned when op is invalid? Answer • Register %eax set to op at beginning of procedure • This becomes the returned value Advantage of Jump Table • Can do k-way branch in O(1) operations – 23 –
Object Code Setup • Label. L 49 becomes address 0 x 804875 c • Label. L 57 becomes address 0 x 8048 bc 0 08048718 <unparse_symbol>: 8048718: 55 pushl 8048719: 89 e 5 movl 804871 b: 8 b 45 08 movl 804871 e: 83 f 8 05 cmpl 8048721: 77 39 ja 8048723: ff 24 85 c 0 8 b jmp %ebp %esp, %ebp 0 x 8(%ebp), %eax $0 x 5, %eax 804875 c <unparse_symbol+0 x 44> *0 x 8048 bc 0(, %eax, 4) – 24 –
Object Code (cont. ) Jump Table • Doesn’t show up in disassembled code • Can inspect using GDB gdb code-examples (gdb) x/6 xw 0 x 8048 bc 0 – Examine 6 hexadecimal format “words” (4 -bytes each) – Use command “help x” to get format documentation 0 x 8048 bc 0 <_fini+32>: 0 x 08048730 0 x 08048737 0 x 08048740 0 x 08048747 0 x 08048750 0 x 08048757 – 25 –
Extracting Jump Table from Binary Jump Table Stored in Read Only Data Segment (. rodata) • Various fixed values needed by your code Can examine with objdump code-examples –s –-section=. rodata • Show everything in indicated segment. Hard to read • Jump table entries shown with reversed byte ordering Contents 8048 bc 0 8048 bd 0 8048 be 0 … of section. rodata: 30870408 37870408 40870408 47870408 50870408 57870408 46616374 28256429 203 d 2025 6 c 640 a 00 43686172 203 d 2025 • E. g. , 30870408 really means 0 x 08048730 – 26 – 0. . . 7. . . @. . . G. . . P. . . W. . . Fact(%d) = %ld. . Char = %
Disassembled Targets • No-operations (movl %esi, %esi) inserted to align target addresses 8048730: b 8 8048735: eb 8048737: b 8 804873 c: eb 804873 e: 89 8048740: b 8 8048745: eb 8048747: b 8 804874 c: eb 804874 e: 89 8048750: b 8 8048755: eb 8048757: b 8 2 b 25 2 a 1 e f 6 2 d 15 2 f 0 e f 6 25 05 3 f 00 00 00 00 00 movl jmp movl jmp movl $0 x 2 b, %eax 804875 c <unparse_symbol+0 x 44> $0 x 2 a, %eax 804875 c <unparse_symbol+0 x 44> %esi, %esi $0 x 2 d, %eax 804875 c <unparse_symbol+0 x 44> $0 x 2 f, %eax 804875 c <unparse_symbol+0 x 44> %esi, %esi $0 x 25, %eax 804875 c <unparse_symbol+0 x 44> $0 x 3 f, %eax – 27 –
Matching Disassembled Targets Entry 0 x 08048730 0 x 08048737 0 x 08048740 0 x 08048747 0 x 08048750 0 x 08048757 8048730: b 8 8048735: eb 8048737: b 8 804873 c: eb 804873 e: 89 8048740: b 8 8048745: eb 8048747: b 8 804874 c: eb 804874 e: 89 8048750: b 8 8048755: eb 8048757: b 8 – 2 b 25 2 a 1 e f 6 2 d 15 2 f 0 e f 6 25 05 3 f 00 00 00 00 00 movl jmp movl jmp movl
Relationship to C++ Class Animal { public: virtual void Make. Sound(); class Cow : public Animal { private: Moo. Data moodata; public: virtual void Make. Sound(); } • Each class has a jumptable (vtable) associated with it – one entry for each virtual function – Animal table contains table with pointer to Animal Make. Sound function – Cow table contains table with pointer to Cow Make. Sound function – Both Make. Sounds are at the same offset in the table • Each instance contains a special pointer (vtable pointer) to its class’s vtable • Animal *animal=new Cow; animal->Make. Sound(); – Read vtable pointer to get vtable – Cow vtable – Read vtable entry at function’s offset – Cow: : Make. Sound – “jump” to that address (really a procedure call -> next time) – (*(animal->_vptr[MAKESOUND]))(animal); – 29 –
Summarizing C Control • • if-then-else do-while switch Assembler Control • jump • Conditional jump Compiler • Must generate assembly code to implement more complex control Standard Techniques • All loops converted to do-while form • Large switch statements use jump tables Conditions in CISC • CISC machines generally have condition code registers Conditions in RISC • Use general registers to store condition information • Special comparison instructions • E. g. , on Alpha: C++ cmple $16, 1, $1 • Virtual function calls – Sets register $1 to 1 when Register $16 <= 1 – 30 –
IA 32 Stack • Region of memory managed with stack discipline • Register %esp indicates lowest allocated position in stack – i. e. , address of top element Pushing • • • Increasing Addresses pushl Src Fetch operand at Src Decrement %esp by 4 Write operand at address given by %esp Popping • • Stack “Bottom” Stack popl Dest Pointer Read operand at address given %esp by %esp Increment %esp by 4 Write to Dest – 31 – Stack Grows Down Stack “Top”
Stack Operation Examples pushl %eax popl %edx 0 x 110 0 x 10 c 0 x 108 123 0 x 104 213 0 x 108 123 %eax 213 %edx 555 %edx 213 %esp 0 x 108 %esp 0 x 104 %esp 0 x 108 – 32 –
Procedure Control Flow Use stack to support procedure call and return Stack stores the context of a procedure call Derrida: There is no such thing as meaning without context. Derrida: Each context may give a different meaning Procedure call: call label Push return address on stack; Jump to label Return address value • Address of instruction beyond call • Example from disassembly 804854 e: e 8 3 d 06 00 00 8048553: 50 – Return address = 0 x 8048553 call pushl 8048 b 90 <main> %eax Procedure return: • ret Pop address from stack; Jump to address – 33 –
Procedure Call / Return Example 804854 e: 8048553: e 8 3 d 06 00 00 50 call pushl 8048 b 90 <main> %eax 8048 b 90 ret 0 x 110 0 x 10 c 0 x 108 123 0 x 104 0 x 8048553 %esp 0 x 108 %esp %eip 0 x 804854 e 0 x 104 %eip 0 x 8048 b 90 %eip is program counter – 34 – %esp 0 x 108 %eip 0 x 8048553
Stack-Based Languages that Support Recursion • e. g. , C, C++, Pascal, Java, Fortran 9 x, … • Code must be “Reentrant” – Multiple simultaneous instantiations of single procedure • Need some place to store state of each instantiation – Arguments – Local variables – Return pointer Context Stack Discipline • State for given procedure needed for limited time – From when called to when return • Callee returns before caller does Stack Allocated in Frames • state for single procedure instantiation – 35 –
Call Chain Example Code Structure yoo(…) { • • who(); • • } Call Chain yoo who(…) { • • am. I(); • • } • Procedure am. I recursive who am. I(…) { • • am. I(); • • } – 36 – am. I
IA 32 Stack Structure Stack Growth • Toward lower addresses • • • yoo Stack Pointer • Address of next available location in stack • Use register %esp Increasing Addresses who Frame Pointer am. I • Start of current stack frame • Use register %ebp Stack Grows Frame Pointer %ebp Stack Pointer %esp – 37 – am. I Stack “Top”
IA 32/Linux Stack Frame Callee Stack Frame (“Top” to Bottom) • Parameters for called functions • Local variables – If can’t keep in registers • Saved register context • Old frame pointer Caller Frame Arguments Frame Pointer (%ebp) Caller Stack Frame Return Addr Old %ebp Saved Registers • Return address – Pushed by call instruction • Arguments for this call Local Variables Stack Pointer (%esp) – 38 – Argument Build
Spares follow here – 39 –
“While” Loop Example #2 /* Compute x raised to nonnegative power p */ int ipwr_while(int x, unsigned p) { int result = 1; while (p) { if (p & 0 x 1) result *= x; x = x*x; p = p>>1; } return result; } Algorithm • Exploit property that p = p 0 + 2 p 1 + 4 p 2 + … 2 n– 1 pn– 1 • Gives: xp = z 0 · z 1 2 · (z 2 2) 2 · … · (…((zn – 12) 2 )…) 2 zi = 1 when p. I = 0 zi = x when p. I = 1 n times • Complexity O(log p) – 40 – Example 310 = 3 2 * 38 = 32 * ((32) 2) 2
ipwr Computation int ipwr(int x, unsigned p) { int result = 1; while (p) { if (p & 0 x 1) result *= x; x = x*x; p = p>>1; } return result; } – 41 –
“While” “Do-While ” “Goto ” int result = 1; while (p) { if (p & 0 x 1) result *= x; x = x*x; p = p>>1; } int result = 1; if (!p) goto done; do { if (p & 0 x 1) result *= x; x = x*x; p = p>>1; } while (p); done: int result = 1; if (!p) goto done; loop: if (!(p & 0 x 1)) goto skip; result *= x; skip: x = x*x; p = p>>1; if (p) goto loop; done: • Also converted conditional update into test and branch around update code – 42 –
Example #2 Compilation Goto Version int result = 1; if (!p) goto done; loop: if (!(p & 0 x 1)) goto skip; result *= x; skip: x = x*x; p = p>>1; if (p) goto loop; done: Registers %ecx %edx %eax x p result pushl %ebp movl %esp, %ebp movl $1, %eax movl 8(%ebp), %ecx movl 12(%ebp), %edx testl %edx, %edx je L 36 L 37: # testb $1, %dl je L 38 imull %ecx, %eax L 38: # imull %ecx, %ecx shrl $1, %edx jne L 37 L 36: # movl %ebp, %esp popl %ebp ret – 43 – # Setup # eax = 1 # ecx = x # edx = p # Test p # If 0, goto done Loop: # Test p & 0 x 1 # If 0, goto skip # result *= x Skip: # x *= x # p >>= 1 # if p goto Loop Done: # Finish
- Slides: 43