MachineLevel Programming II Control Flow Topics n Condition
- Slides: 35
Machine-Level Programming II: Control Flow Topics n Condition Codes l Setting l Testing n Control Flow l If-then-else l Varieties of Loops l Switch Statements
Condition Codes Single Bit Registers CF ZF Carry Flag Zero Flag SF OF Sign Flag Overflow Flag Implicitly Set By Arithmetic Operations addl Src, Dest C analog: t = a + b n CF set if carry out from most significant bit l Used to detect unsigned overflow ZF set if t == 0 n SF set if t < 0 n n OF set if two’s complement overflow (a>0 && b>0 && t<0) || (a<0 && b<0 && t>=0) Not Set by leal instruction
Setting Condition Codes (cont. ) Explicit Setting by Compare Instruction cmpl Src 2, Src 1 n cmpl b, a like computing a-b without setting destination n CF set if carry out from most significant bit l Used for unsigned comparisons n ZF set if a == b SF set if (a-b) < 0 n OF set if two’s complement overflow n (a>0 && b<0 && (a-b)<0) || (a<0 && b>0 && (a-b)>0)
Setting Condition Codes (cont. ) Explicit Setting by Test instruction testl Src 2, Src 1 n Sets condition codes based on value of Src 1 & Src 2 l Useful to have one of the operands be a mask n n n testl b, a like computing a&b without setting destination ZF set when a&b == 0 SF set when a&b < 0
Reading Condition Codes Set. X Instructions n Set single byte based on combinations of condition codes
Reading Condition Codes (Cont. ) Set. X Instructions n n Set single byte based on combinations of condition codes One of 8 addressable byte registers l Embedded within first 4 integer registers l Does not alter remaining 3 bytes l Typically use movzbl to finish job Body int gt (int x, int y) { return x > y; } movl 12(%ebp), %eax cmpl %eax, 8(%ebp) setg %al movzbl %al, %eax %ah %al %edx %dh %dl %ecx %ch %cl %ebx %bh %bl %esi %edi %esp %ebp # eax = y # Compare x : y # al = x > y # Zero rest of %eax Note inverted ordering!
Jumping j. X Instructions n Jump to different part of code depending on condition codes
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 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; } n C allows “goto” as means of transferring control l Closer to machine-level programming style n Generally considered bad coding style movl 8(%ebp), %edx # edx = x movl 12(%ebp), %eax # eax = y cmpl %eax, %edx # x : y jle L 9 # if <= goto L 9 movl %edx, %eax # eax = x Skipped when x y L 9: # Done:
“Do-While” Loop Example C Code int fact_do (int x) { int result = 1; do { result *= x; x = x-1; } while (x > 1); return result; } n n Goto Version 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
“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 %edx %eax x result Assembly _fact_goto: pushl %ebp movl %esp, %ebp movl $1, %eax movl 8(%ebp), %edx # Setup # eax = 1 # edx = x L 11: imull %edx, %eax decl %edx cmpl $1, %edx jg L 11 # result *= x # x-# Compare x : 1 # if > goto loop movl %ebp, %esp popl %ebp ret # Finish
General “Do-While” Translation Goto Version C Code do Body while (Test); n loop: Body if (Test) goto loop Body can be any C statement l Typically compound statement: { Statement 1; Statement 2; … Statementn; } n Test is expression returning integer = 0 interpreted as false 0 interpreted as true
“While” Loop Example #1 C Code int fact_while (int x) { int result = 1; while (x > 1) { result *= x; x = x-1; }; return result; } n n First Goto Version 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
Actual “While” Loop Translation C Code int fact_while(int x) { int result = 1; while (x > 1) { result *= x; x = x-1; }; return result; } n Uses same inner loop as do-while version n 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; }
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:
“For” Loop Example /* Compute x raised to nonnegative power p */ int ipwr_for(int x, unsigned p) { int result; for (result = 1; p != 0; p = p>>1) { if (p & 0 x 1) result *= x; x = x*x; } return result; } Algorithm n n 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 pi = 0 zi = x when pi = 1 n Complexity O(log p) n– 1 times Example 310 = 32 * 38 = 32 * ((32) 2) 2
ipwr Computation /* Compute x raised to nonnegative power p */ int ipwr_for(int x, unsigned p) { int result; for (result = 1; p != 0; p = p>>1) { if (p & 0 x 1) result *= x; x = x*x; } return result; }
“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; } Init result = 1 Body for (Init; Test; Update ) Body Test p != 0 { if (p & 0 x 1) result *= x; x = x*x; } Update p = p >> 1
“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:
“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 Update p = p >> 1 Test p != 0 Body { if (p & 0 x 1) result *= x; x = x*x; }
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 '? '; } } Switch Statements Implementation Options n Series of conditionals l Good if few cases l Slow if many n Jump Table l Lookup branch target l Avoids conditionals l Possible when cases are small integer constants n GCC l Picks one based on case structure n Bug in example code l No default given
Jump Table Structure Switch Form switch(op) { case val_0: Block 0 case val_1: Block 1 • • • case val_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: Code Block n– 1
Switch Statement Example Branching Possibilities typedef enum {ADD, MULT, MINUS, DIV, MOD, BAD} op_type; Enumerated Values 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) ADD MULT MINUS DIV MOD BAD 0 1 2 3 4 5 # Setup # eax = op # Compare op : 5 # If > goto done # goto Table[op]
Assembly Setup Explanation Symbolic Labels n Labels of form. LXX translated into addresses by assembler Table Structure n n Each target requires 4 bytes Base address at. L 57 Jumping jmp. L 49 n Jump target is denoted by label. L 49 jmp *. L 57(, %eax, 4) n Start of jump table denoted by label. L 57 n Register %eax holds op n n Must scale by factor of 4 to get offset into table Fetch target from effective Address. L 57 + op*4
Jump Table Contents Targets & Completion . section. rodata . align 4. L 57: . long. L 51 #Op = 0. long. L 52 #Op = 1. long. L 53 #Op = 2. long. L 54 #Op = 3. long. L 55 #Op = 4. long. L 56 #Op = 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 Enumerated Values ADD MULT MINUS DIV MOD BAD 0 1 2 3 4 5
Switch Statement Completion. L 49: movl %ebp, %esp popl %ebp ret # Done: # Finish Puzzle n What value returned when op is invalid? Answer n Register %eax set to op at beginning of procedure n This becomes the returned value Advantage of Jump Table n Can do k-way branch in O(1) operations
Object Code Setup n n 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 %ebp 8048719: 89 e 5 movl %esp, %ebp 804871 b: 8 b 45 08 movl 0 x 8(%ebp), %eax 804871 e: 83 f 8 05 cmpl $0 x 5, %eax 8048721: 77 39 ja 804875 c <unparse_symbol+0 x 44> 8048723: ff 24 85 c 0 8 b jmp *0 x 8048 bc 0(, %eax, 4)
Object Code (cont. ) Jump Table n Doesn’t show up in disassembled code Can inspect using GDB gdb code-examples (gdb) x/6 xw 0 x 8048 bc 0 n l Examine 6 hexadecimal format “words” (4 -bytes each) l 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
Extracting Jump Table from Binary Jump Table Stored in Read Only Data Segment (. rodata) n Various fixed values needed by your code Can examine with objdump code-examples –s –-section=. rodata n Show everything in indicated segment. Hard to read n Jump table entries shown with reversed byte ordering Contents of section. rodata: 8048 bc 0 30870408 37870408 40870408 47870408 0. . . 7. . . @. . . G. . . 8048 bd 0 50870408 57870408 46616374 28256429 P. . . W. . . Fact(%d) 8048 be 0 203 d 2025 6 c 640 a 00 43686172 203 d 2025 = %ld. . Char = % … n E. g. , 30870408 really means 0 x 08048730
Disassembled Targets 8048730: b 8 2 b 00 00 00 8048735: eb 25 8048737: b 8 2 a 00 00 00 804873 c: eb 1 e 804873 e: 89 f 6 8048740: b 8 2 d 00 00 00 8048745: eb 15 8048747: b 8 2 f 00 00 00 804874 c: eb 0 e 804874 e: 89 f 6 8048750: b 8 25 00 00 00 8048755: eb 05 8048757: b 8 3 f 00 00 00 n n movl $0 x 2 b, %eax jmp 804875 c <unparse_symbol+0 x 44> movl $0 x 2 a, %eax jmp 804875 c <unparse_symbol+0 x 44> movl %esi, %esi movl $0 x 2 d, %eax jmp 804875 c <unparse_symbol+0 x 44> movl $0 x 2 f, %eax jmp 804875 c <unparse_symbol+0 x 44> movl %esi, %esi movl $0 x 25, %eax jmp 804875 c <unparse_symbol+0 x 44> movl $0 x 3 f, %eax movl %esi, %esi does nothing Inserted to align instructions for better cache performance
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 2 b 00 00 00 8048735: eb 25 8048737: b 8 2 a 00 00 00 804873 c: eb 1 e 804873 e: 89 f 6 8048740: b 8 2 d 00 00 00 8048745: eb 15 8048747: b 8 2 f 00 00 00 804874 c: eb 0 e 804874 e: 89 f 6 8048750: b 8 25 00 00 00 8048755: eb 05 8048757: b 8 3 f 00 00 00 movl jmp movl jmp movl
Sparse Switch Example /* Return x/111 if x is multiple && <= 999. -1 otherwise */ int div 111(int x) { switch(x) { case 0: return 0; case 111: return 1; case 222: return 2; case 333: return 3; case 444: return 4; case 555: return 5; case 666: return 6; case 777: return 7; case 888: return 8; case 999: return 9; default: return -1; } } n Not practical to use jump table l Would require 1000 entries n Obvious translation into if-then-else would have max. of 9 tests
Sparse Switch Code movl 8(%ebp), %eax cmpl $444, %eax je L 8 jg L 16 cmpl $111, %eax je L 5 jg L 17 testl %eax, %eax je L 4 jmp L 14 # get x # x: 444 # x: 111 n Compares x to possible case values n Jumps different places depending on outcomes. . . # x: 0 L 5: movl $1, %eax jmp L 19 L 6: movl $2, %eax jmp L 19 . . . L 7: movl $3, %eax jmp L 19 L 8: movl $4, %eax jmp L 19. . .
Sparse Switch Code Structure < < 111 = 444 = > 4 > 777 < = 1 7 0 -1 = 0 222 2 -1 n 555 = n > 5 333 = 3 Organizes cases as binary tree Logarithmic performance < = -1 888 = > 8 666 = 6 -1 999 = 9
Summarizing C Control Standard Techniques n n if-then-else do-while All loops converted to do-while form n while n n switch Large switch statements use jump tables n Assembler Control n n jump Conditional jump Compiler n Must generate assembly code to implement more complex control Conditions in CISC machines generally have condition code registers Conditions in RISC n n n Use general registers to store condition information Special comparison instructions E. g. , on Alpha: cmple $16, 1, $1 l Sets register $1 to 1 when Register $16 <= 1
- Gd&t symbol
- Data flow vs control flow
- Control flow and data flow computers
- Transaction flow testing
- Stock control e flow control
- Flow control and error control
- Karel the robot learns java
- Perbedaan linear programming dan integer programming
- Greedy programming vs dynamic programming
- System programming vs application programming
- Integer programming vs linear programming
- Definisi linear
- Flow programming
- Flow programming language
- Control structure in c
- Pathophysiology of atelectasis
- 15l to fio2
- Venturi mask 50 percent
- Lumina flow
- Internal and external flow
- Energy naturally flows from warmer matter to cooler matter
- Oikos meaning
- Transform flow and transaction flow
- Data flow structure
- Distinguish between rotational and irrotational flow
- Internal versus external flow
- Flow diagram cheese production flow chart
- Flow control valve symbol
- Udp flow control
- Compare instruction in 8086
- Exceptional control flow
- Repl capture/apply: memory
- Material flow control
- Control flow graph for bubble sort
- Unidirectional motor symbol
- Control flow graph example