
CS 251 Fall 2019 CS 240 Principles of Programming Languages λ BenFoundations Wood of Computer Systems x86 Control Flow (Part A, Part B) Condition codes, comparisons, and tests [Un]Conditional jumps and conditional moves Translating if-else, loops, and switch statements https://cs.wellesley.edu/~cs240/ x86 Control Flow 1 Conditionals and Control Flow Two key pieces 1. Comparisons and tests: check conditions 2. Transfer control: choose next instruction Familiar C constructs Processor Control-Flow State l if else Condition codes (a.k.a. flags) 1-bit registers hold flags set by last ALU operation l while ZF l do while Zero Flag result == 0 l for SF Sign Flag result < 0 l break l continue CF Carry Flag carry-out/unsigned overflow OF Overflow Flag two's complement overflow %rip Instruction pointer (a.k.a. program counter) register holds address of next instruction to execute x86 Control Flow 2 1. Compare and test: conditions cmpq b,a computes a - b, sets flags, discards result Which flags indicate that a < b ? (signed? unsigned?) testq b,a computes a & b, sets flags, discards result Common pattern: testq %rax, %rax What do ZF and SF indicate? x86 Control Flow 3 (Aside) Saving conditions as Boolean values setg: set if greater long gt(int x, int y) { stores byte: return x > y; 0x01 if ~(SF^OF)&~ZF } 0x00 otherwise gt: cmpq %rsi,%rdi # compare: x – y setg %al # al = x > y movzbq %al,%rax # zero rest of %rax retq Zero-extend from Byte (8 bits) to Quadword (64 bits) %rax %eax %ah %al set__ comes in same flavors as j__ (next slide) x86 Control Flow 4 2. Jump: choose next instruction Jump/branch to different part of code by setting %rip. j__ Condition Description Unconditional jmp 1 Unconditional jump je ZF Equal / Zero jne ~ZF Not Equal / Not Zero js SF Negative jns ~SF Nonnegative Conditional jg ~(SF^OF)&~ZF Greater (Signed) jumps jge ~(SF^OF) Greater or Equal (Signed) jl (SF^OF) Less (Signed) jle (SF^OF)|ZF Less or Equal (Signed) ja ~CF&~ZF Above (unsigned) jb CF Below (unsigned) x86 Control Flow 5 Jump for control flow Jump immediately follows comparison/test. Together, they make a decision: "if %rcx == %rax then jump to label." cmpq %rax,%rcx je label … … Executed only if … %rax ≠ %rcx label: addq %rdx,%rax Label Name for address of following item. x86 Control Flow 6 Conditional branch example long absdiff(long x,long y) { long result; if (x > y) { result = x-y; } else { result = y-x; absdiff: cmpq %rsi, %rdi } jle .L7 return result; subq %rsi, %rdi } movq %rdi, %rax .L8: retq Labels .L7: Name for address of subq %rdi, %rsi following item. movq %rsi, %rax jmp .L8 How did the compiler create this? x86 Control Flow 7 Introduced by Fran Allen, et al. Won the 2006 Turing Award Control-Flow Graph for her work on compilers. Code flowchart/directed graph. long absdiff(long x, long y){ Nodes = Basic Blocks: long result; Straight-line code always if (x > y) { executed together in order. result = x-y; } else { result = y-x; long result; } if (x > y) else return result; } then else result = x-y; result = y-x; Edges = Control Flow: Which basic block executes next (under what condition). return result; x86 Control Flow 8 Choose a linear order of basic blocks. long result; long result; if (x > y) else if (!(x > y)) then else else then result = x-y; result = y-x; result = y-x; result = x-y; return result; return result; x86 Control Flow 9 Choose a linear order of basic blocks. long result; if (!(x > y)) result = x-y; return result; result = y-x; Why might the compiler choose this basic block order instead of another valid order? x86 Control Flow 10 Translate basic blocks with jumps + labels long result; if (!(x > y)) cmpq %rsi, %rdi jle Else result = x-y; subq %rsi, %rdi movq %rdi, %rax return result; End: retq result = y-x; Else: subq %rdi, %rsi movq %rsi, %rax jmp End Why might the compiler choose this basic block order instead of another valid order? x86 Control Flow 11 Execute absdiff ex Registers cmpq %rsi, %rdi %rax jle Else %rdi 5 subq %rsi, %rdi movq %rdi, %rax %rsi 3 End: retq Else: subq %rdi, %rsi movq %rsi, %rax jmp End x86 Control Flow 12 Execute absdiff ex Registers cmpq %rsi, %rdi %rax jle Else %rdi 4 subq %rsi, %rdi movq %rdi, %rax %rsi 7 End: retq Else: subq %rdi, %rsi movq %rsi, %rax jmp End x86 Control Flow 15 Note: CSAPP shows translation with goto long absdiff(long x,long y){ long goto_ad(long x,long y){ int result; int result; if (x > y) { if (x <= y) goto Else; result = x-y; result = x-y; } else { End: result = y-x; return result; } Else: return result; result = y-x; } goto End; } x86 Control Flow 18 Note: CSAPP shows translation with goto long goto_ad(long x, long y){ absdiff: long result; cmpq %rsi, %rdi if (x <= y) goto Else; jle Else result = x-y; End: subq %rsi, %rdi return result; movq %rdi, %rax Else: End: result = y-x; goto End; retq } Else: subq %rdi, %rsi movq %rsi, %rax jmp End Close to assembly code. x86 Control Flow 19 But never use goto in your source code! http://xkcd.com/292/ x86 Control Flow 20 Compile if-else ex long wacky(long x, long y){ wacky: long result; if (x + y > 7) { result = x; } else { result = y + 2; } return result; } Assume x is available in %rdi, y is available in %rsi. Place result in %rax for return. x86 Control Flow 21 Compile if-else (solution #1) ex long wacky(long x, long y){ wacky: long result; movq %rdi, %rdx if (x + y > 7) { addq %rsi, %rdx result = x; cmpq $7, %rdx } else { jle Else result = y + 2; } movq %rdi, %rax return result; } End: retq Assume x is available in %rdi, y is available in %rsi. Else: addq $2, %rsi Place result in %rax for return. movq %rsi, %rax jmp End x86 Control Flow 22 Compile if-else (solution #2) ex long wacky(long x, long y){ wacky: long result; leaq (%rdi, %rsi), %rdx if (x + y > 7) { cmpq $7, %rdx result = x; jle Else } else { result = y + 2; movq %rdi, %rax } return result; End: } retq Assume x is available in %rdi, Else: y is available in %rsi. leaq 2(%rsi), %rax jmp End Place result in %rax for return. x86 Control Flow 23 Encoding jumps: PC-relative addressing 0x100 cmpq %rax, %rbx 0x1000 0x102 je 0x70 0x1002 0x104 … 0x1004 … … … 0x174 addq %rax, %rbx 0x1074 PC-relative offsets support relocatable code. Absolute branches do not (or it's hard). x86 Control Flow 24 CS 251 Fall 2019 CS 240 Principles of Programming Languages λ BenFoundations Wood of Computer Systems x86 Control Flow (Part A, Part B) Condition codes, comparisons, and tests [Un]Conditional jumps and conditional moves Translating if-else, loops, and switch statements https://cs.wellesley.edu/~cs240/ x86 Control Flow 25 do while loop long result = 1; long fact_do(long x) { long result = 1; result = result*x; do { result = result * x; x = x - 1; x = x - 1; } while (x > 1); return result; (x > 1) ? Yes } No return result; x86 Control Flow 26 do while loop Register Variable fact_do: %rdi long result = 1; movq $1,%rax %rax .L11: result = result*x; imulq %rdi,%rax x = x - 1; decq %rdi (x > 1) ? cmpq $1,%rdi Yes No jg .L11 return result; retq Why put the loop condition at the end? x86 Control Flow 27 while loop long fact_while(long x){ long result = 1; while (x > 1) { long result = 1; result = result * x; x = x - 1; } return result; result = result*x; } x = x - 1; long result = 1; (x > 1) ? Yes (x > 1) ? No Yes No return result; result = result*x; x = x - 1; This order is used by GCC for x86-64. Why? return result; x86 Control Flow 28 while loop long fact_while(long x){ long result = 1; while (x > 1) { result = result * x; x = x - 1; } return result; } fact_while: movq $1, %rax int result = 1; jmp .L34 .L35: result = result * x; imulq %rdi, %rax x = x - 1; decq %rdi .L34: (x > 1) ? cmpq $1, %rdi Yes jg .L35 No return result; retq x86 Control Flow 29 for (Initialize; Test; Update ) { for loop translation Body } for (result = 1; p != 0; p = p>>1) { if (p & 0x1) { result = result * x; Initialize; } while (Test) { x = x * x; Body ; } Update; } result = 1; Initialize if (p & 0x1) { result = result*x; Body } Update x = x * x; p = p >> 1; Test ? Yes No (p != 0) ? Yes No x86 Control Flow 30 for loop: square-and-multiply optional /* Compute x raised to nonnegative power p */ int power(int x, unsigned int p) { int result; for (result = 1; p != 0; p = p>>1) { if (p & 0x1) { result = result * x; } x = x*x; xm * xn = m+n } x return result; 0 ... 0 1 0 1 1 = 11 } 12^31 * ... * 116 * x8 * 14 * x2 * x1 = x11 0 1 Algorithm 1 = x x = x 2 n–1 Exploit bit representation: p = p0 + 2p1 + 2 p2 + … 2 pn–1 Gives: xp = z · z 2 · (z 2) 2 · … · (…((z 2) 2 )…) 2 0 1 2 n –1 Example zi = 1 when pi = 0 n–1 times 311 = 31 * 32 * 38 zi = x when pi = 1 Complexity O(log p) = O(sizeof(p)) = 31 * 32 * ((32)2)2 x86 Control Flow 31 for loop: power iterations optional /* Compute x raised to nonnegative power p */ int power(int x, unsigned int p) { int result; for (result = 1; p != 0; p = p>>1) { if (p & 0x1) { result = result * x; } x = x*x; } return result; } iterations result x p 0 1 3 11 = 10112 1 3 9 5 = 1012 2 27 81 2 = 102 3 27 6561 1 = 12 4 177147 43046721 0 2 x86 Control Flow 32 (Aside) Conditional Move Why? Branch prediction in pipelined/OoO processors.
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages38 Page
-
File Size-