X86 Control Flow

X86 Control Flow

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.

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    38 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us