control flow 1
play

Control flow (1) Condition codes Conditional and unconditional - PowerPoint PPT Presentation

Control flow (1) Condition codes Conditional and unconditional jumps Loops Conditional moves Switch statements 1 Conditionals and Control Flow Two key pieces 1. Comparisons and tests: check conditions 2. Transfer control: choose next


  1. Control flow (1) Condition codes Conditional and unconditional jumps Loops Conditional moves Switch statements 1

  2. Conditionals and Control Flow Two key pieces 1. Comparisons and tests: check conditions 2. Transfer control: choose next instruction Processor Control-Flow State Familiar C constructs Condition codes (a.k.a. flags ) if else l 1-bit registers hold flags set by last ALU operation while l ZF Zero Flag result == 0 do while l for l SF Sign Flag result < 0 break l Carry Flag carry-out/unsigned overflow CF continue l Overflow Flag two's complement overflow OF Instruction pointer %rip (a.k.a. program counter ) register holds address of next instruction to execute 2

  3. ex 1. compare and test : conditions b,a computes a - b , sets flags, discards result cmpq 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? 3

  4. Aside: save conditions setg: set if greater long gt(int x, int y) { return x > y; stores byte: 0x01 if ~(SF^OF)&~ZF } 0x00 otherwise cmpq %rsi,%rdi # compare: x – y setg %al # al = x > y movzbq %al,%rax # zero rest of %rax Z ero-extend from B yte (8 bits) to Q uadword (64 bits) %ah %al %rax %eax 4

  5. 2. jump : choose next instruction Jump/branch to different part of code by setting %rip . j__ Condition Description Unconditional Always jump jmp 1 Equal / Zero je ZF Not Equal / Not Zero jne ~ZF Negative js SF Nonnegative jns ~SF Greater (Signed) jg ~(SF^OF)&~ZF Jump iff condition Greater or Equal (Signed) jge ~(SF^OF) Less (Signed) jl (SF^OF) Less or Equal (Signed) jle (SF^OF)|ZF Above (unsigned) ja ~CF&~ZF Below (unsigned) jb CF 6

  6. Jump for control flow Jump immediately follows comparison/test. Together, they make a decision: "if %rcx == %rax , jump to label." cmpq %rax,%rcx je label … Executed only if … %rax ≠ %rcx … label: addq %rdx,%rax Label Name for address of following item. 7

  7. Conditional Branch Example long absdiff(long x,long y) { long result; if (x > y) { result = x-y; absdiff: } else { cmpq %rsi, %rdi result = y-x; jle .L7 } subq %rsi, %rdi return result; movq %rdi, %rax } .L8: retq Labels .L7: Name for address of subq %rdi, %rsi movq %rsi, %rax following item. jmp .L8 How did the compiler create this? 8

  8. Introduced by Fran Allen, et al. Control-Flow Graph Won the 2006 Turing Award 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; return result; if (x > y) else } else then Edges = Control Flow : result = y-x; result = x-y; Which basic block executes next (under what condition). return result;

  9. 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;

  10. 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?

  11. 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 Else: result = y-x; subq %rdi, %rsi movq %rsi, %rax jmp End Why might the compiler choose this basic block order instead of another valid order?

  12. ex Execute absdiff Registers cmpq %rsi, %rdi %rax jle Else %rdi subq %rsi, %rdi movq %rdi, %rax %rsi End: retq Else: subq %rdi, %rsi movq %rsi, %rax jmp End 13

  13. 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 ; } 14

  14. Note: CSAPP shows translation with goto long goto_ad(long x, long y){ long result; if (x <= y) goto Else ; result = x-y; End : absdiff: return result; Else: cmpq %rsi, %rdi result = y-x; jle Else goto End ; subq %rsi, %rdi } movq %rdi, %rax End: retq Else: Close to assembly code. subq %rdi, %rsi movq %rsi, %rax jmp End 15

  15. But never use goto in your source code! http://xkcd.com/292/ 16

  16. ex compile if-else long wacky(long x, long y){ int result; if (x + y > 7) { result = x; } else { result = y + 2; } return result; } Assume x available in %rdi , y available in %rsi . Place result in %rax .

  17. Encoding Jumps: PC-relative addressing 0x100 cmpq %rax, %rbx 0x1000 0x102 je 0x70 0x1002 0x104 … 0x1004 … … … 0x174 addq %rax, %rbx 0x1074 l PC-relative offsets support relocatable code. l Absolute branches do not (or it's hard). 18

  18. Compiling Loops C code: Machine code: loopTop: testq %rax, %rax while ( sum != 0 ) { je loopDone <loop body> <loop body code> } jmp loopTop loopDone: 20

  19. do while loop example long result = 1; C Code long fact_do(long x) { long result = 1; result = result*x; do { x = x-1; result = result * x; x = x-1; } while (x > 1); (x > 1) ? return result; Yes } No return result; 21

  20. do while loop translation Register Variable %rdi long result = 1; Assembly %rax fact_do: movq $1,%rax result = result*x; .L11: x = x-1; imulq %rdi,%rax decq %rdi cmpq $1,%rdi (x > 1) ? jg .L11 Yes No retq return result; Why? Why put the loop condition at the end? 22

  21. Why? while loop translation C Code long fact_while(long x){ long result = 1; long result = 1; while (x > 1) { result = result * x; x = x-1; } result = result*x; return result; x = x-1; } long result = 1; (x > 1) ? Yes No (x > 1) ? Yes No return result; result = result*x; x = x-1; This order is used by GCC for x86-64 return result; 23

  22. while loop example int fact_while(int x) { movq $1, %rax int result = 1; jmp .L34 while (x > 1) { .L35: result = result * x; imulq %rdi, %rax x = x - 1; decq %rdi } .L34: return result; cmpq $1, %rdi } jg .L35 retq int result = 1; result = result*x; x = x-1; (x > 1) ? Yes No return result; 25

  23. for loop translation for ( Initialize ; Test ; Update ) { 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 x = x*x; Update p = p>>1; Test ? Yes No (p != 0) ? Yes No 31

  24. Control flow (2) Condition codes Conditional and unconditional jumps Loops Conditional moves Switch statements 35

  25. (Aside) Conditional Move cmov_ src, dest if ( Test ) Dest ß Src Why? Branch prediction in pipelined/OoO processors. long absdiff(long x, long y) { long result; long absdiff(long x, long y) { if (x>y) { return x>y ? x-y : y-x; result = x-y; } } else { result = y-x; } return result; } absdiff: movq %rdi, %rax # x subq %rsi, %rax # result = x-y movq %rsi, %rdx subq %rdi, %rdx # else_val = y-x cmpq %rsi, %rdi # x:y cmovle %rdx, %rax # if <=, result = else_val ret 36

  26. (Aside) Bad Cases for Conditional Move Expensive Computations val = Test(x) ? Hard1(x) : Hard2(x); Risky Computations val = p ? *p : 0; Computations with side effects val = x > 0 ? x*=7 : x+=3; 37

  27. switch statements long switch_eg (long x, long y, long z) { long w = 1; switch(x) { case 1: w = y*z; break; Fall through cases case 2: w = y/z; /* Fall Through */ Missing cases case 3: w += z; break; Multiple case labels case 5: case 6: w -= z; break; Lots to manage, default: let's use a jump table w = 2; } return w; } 38

  28. Jump Table Structure Memory C code: switch(x) { case 1: <some code> break; case 2: <some code> case 3: <some code> Code break; Blocks case 5: case 6: <some code> break; default: <some code> } Translation sketch: 6 5 if (0 <= x && x <= 6) 4 target = JTab[x]; 3 goto target; 2 else 1 Jump 0 goto default; Table 39

  29. Jump Table declaring data, not instructions 8-byte memory alignment Jump table .section .rodata switch(x) { .align 8 case 1: // .L3 .L4: w = y*z; .quad .L8 # x = 0 break; .quad .L3 # x = 1 case 2: // .L5 .quad .L5 # x = 2 w = y/z; .quad .L9 # x = 3 /* Fall Through */ .quad .L8 # x = 4 case 3: // .L9 .quad .L7 # x = 5 w += z; .quad .L7 # x = 6 break; case 5: case 6: // .L7 w -= z; “quad” as in four 1978-era 16-bit words break; default: // .L8 w = 2; } 40

  30. ex switch statement example long switch_eg(long x, long y, long z) { long w = 1; switch(x) { . . . } return w; Jump table } .section .rodata but this is signed... .align 8 .L4: Jump if above .quad .L8 # x = 0 (like jg, but switch_eg: .quad .L3 # x = 1 unsigned) movq %rdx, %rcx .quad .L5 # x = 2 .quad .L9 # x = 3 cmpq $6, %rdi .quad .L8 # x = 4 Indirect ja .L8 .quad .L7 # x = 5 jump jmp *.L4(,%rdi,8) .quad .L7 # x = 6 41

Recommend


More recommend