12/22/2016 Control Flow Computers execute instructions in sequence. Except when we change the flow of control Jump and Call instructions Controlling Program Flow Unconditional jump Direct jump: jmp Label » Jump target is specified by a label (e.g., jmp .L1 ) Indirect jump: jmp *Operand » Jump target is specified by a register or memory location (e.g., jmp *%rax ) – 2 – Conditional statements Condition codes Processor flag register eflags Some jumps are conditional (extended flags) A computer needs to jump if certain a condition is true Registers In C, if, for , and while statements Flags are set or cleared by %rax %r8 if (x) {…} else {…} depending on the result of %rbx %r9 an instruction %rcx %r10 while (x) {…} %rdx %r11 Each bit is a flag, or condition %rsi %r12 code do {…} while (x) %rdi %r13 CF Carry Flag SF Sign Flag %rsp %r14 for (i=0; i<max; i++) {…} ZF Zero Flag OF Overflow Flag %rbp %r15 %rip switch (x) { case 1: … case 2: … Condition codes } CF ZF SF OF – 3 – – 4 – 1
12/22/2016 Implicit setting Explicit setting via compare Automatically Set By Arithmetic and Logical Operations Setting condition codes via compare instruction Example: addq Src , Dest cmpq b , a C analog: t = a + b Computes a-b without setting destination CF (for unsigned integers) CF set if carry out from most significant bit set if carry out from most significant bit (unsigned overflow) Used for unsigned comparisons (unsigned long t) < (unsigned long a) ZF set if a == b ZF (zero flag) SF set if (a-b) < 0 set if t == 0 SF (for signed integers) OF set if two’s complement (signed) overflow set if t < 0 (a>0 && b<0 && (a-b)<0) || (a<0 && b>0 && (a-b)>0) OF (for signed integers) Byte, word, and double word versions cmpb, cmpw, cmpl set if signed (two’s complement) overflow (a>0 && b>0 && t<0) || (a<0 && b<0 && t>=0) Not set by lea , push, pop, mov instructions – 5 – – 6 – Explicit setting via test Conditional jump instrcutions Setting condition codes via test instruction Jump to different part of code based on condition codes testq b , a jX Condition Description Computes a&b without setting destination jmp 1 Unconditional Sets condition codes based on result je, jz ZF Equal / Zero Useful to have one of the operands be a mask jne,jnz ~ZF Not Equal / Not Zero Often used to test zero, positive js SF Negative testq %rax, %rax jns ~SF Nonnegative ZF set when a&b == 0 SF set when a&b < 0 jg ~(SF^OF)&~ZF Greater (Signed) Byte, word and double word versions testb, testw, jge ~(SF^OF) Greater or Equal (Signed) testl jl (SF^OF) Less (Signed) jle (SF^OF)|ZF Less or Equal (Signed) ja ~CF&~ZF Above (unsigned) jb CF Below (unsigned) – 7 – – 8 – Overflow flips result 2
12/22/2016 Jump instructions Conditional jump example Non-optimized What’s the difference between jg and ja ? gcc –Og -S –fno-if-conversion control.c absdiff: cmpq %rsi, %rdi # x:y Which one would you use to compare two pointers? long absdiff(long x, long y) jle .L4 { movq %rdi, %rax long result; subq %rsi, %rax if (x > y) ret result = x-y; .L4: # x <= y else movq %rsi, %rax result = y-x; subq %rdi, %rax return result; ret } Register Use(s) %rdi Argument x %rsi Argument y %rax Return value – 9 – – 10 – General Conditional Expression Practice problem 3.18 Translation (Using Branches) /* x in %rdi, y in %rsi, z in %rdx */ long test(long x, long y, long z) test: { C Code leaq (%rdi,%rsi), %rax addq %rdx, %rax x+y+z long val = ____________ ; val = Test ? Then_Expr : Else_Expr ; cmpq $-3, %rdi if ( ____________ ) { x < -3 jge .L2 cmp %rdx,%rsi y < z if ( ____________ ) jge .L3 val = x>y ? x-y : y-x; x*y movq %rdi, %rax val = ____________ ; imulq %rsi, %rax else ret y*z .L3: val = ____________ ; movq %rsi, %rax Goto Version } else if ( ____________ ) x > 2 imulq %rdx,%rax ret ntest = ! Test ; val = ____________ ; x*z Create separate code regions for .L2 if (ntest) goto Else; then & else expressions cmpq $2, %rdi return val; val = Then_Expr ; jle .L4 } movq %rdi, %rax goto Done; imulq %rdx, %rax Else: Execute appropriate one .L4 ret val = Else_Expr ; Done: . . . – 11 – – 12 – 3
12/22/2016 Avoiding conditional branches Conditional moves Conditional instruction exectuion Modern CPUs with deep pipelines cmovXX Src, Dest Instructions fetched far in advance of execution Move value from src to dest if condition XX holds Mask the latency going to memory No branching Problem: What if you hit a conditional branch? Handled as operation within Execution Unit Must predict which branch to take! Added with P6 microarchitecture (PentiumPro onward, 1995) Branch prediction in CPUs well-studied, fairly effective Example But, best to avoid conditional branching altogether # %rdi = x, %rsi = y # return value in %rax returns max(x,y) movq %rdi,%rdx # Get x movq %rsi,%rax # rval=y cmpq %rdx, %rax # rval:x cmovl %rdx,%rax # If <, rval=x Performance 14 cycles on all data More efficient than conditional branching (single control flow path) But overhead: both branches are evaluated – 13 – – 14 – General Conditional Expression Conditional Move example Translation (Using conditional move) Branch version long absdiff(long x, long y) absdiff: Conditional Move template { C Code cmpq %rsi, %rdi # x:y long result; Instruction supports jle .L4 val = Test ? Then_Expr : Else_Expr ; if (x > y) if (Test) Dest Src movq %rdi, %rax result = x-y; subq %rsi, %rax GCC attempts to restructure else result = Then_Expr ; ret execution to avoid disruptive result = y-x; .L4: # x <= y eval = Else_Expr ; conditional branch return result; movq %rsi, %rax nt = ! Test ; } Both values computed subq %rdi, %rax if (nt) result = eval; ret Overwrite “then”-value with return result; “else”-value if condition doesn’t hold Branch version absdiff: Register Use(s) movq %rdi, %rax # x Conditional moves do not ntest = ! Test ; %rdi Argument x subq %rsi, %rax # result = x-y transfer control if (ntest) goto Else; movq %rsi, %rdx %rsi Argument y val = Then_Expr ; subq %rdi, %rdx # eval = y-x goto Done; %rax Return value cmpq %rsi, %rdi # x:y Else: cmovle %rdx, %rax # if <=, result = eval val = Else_Expr ; ret Done: – 15 – – 16 – 4
12/22/2016 Practice problem 3.21 When not to use Conditional Move /* x in %rdi, y in %rsi */ long test(long x, long y) Expensive computations test: { leaq 0(,%rdi,8), %rax val = Test(x) ? Hard1(x) : Hard2(x); testq %rsi, %rsi 8*x long val = ____________ ; jle .L2 y > 0 if ( ____________ ) { movq %rsi, %rax subq %rdi, %rax Both Hard1(x) and Hard2(x) computed x < y if ( ____________ ) movq %rdi, %rdx y-x andq %rsi, %rdx val = ____________ ; Use branching when “then” and “else” expressions are more cmpq %rsi, %rdi expensive than branch misprediction else cmovge %rdx, %rax ret x&y val = ____________ ; Computations with side effects .L2: y <= -2 } else if ( ____________ ) addq %rsi, %rdi val = x > 0 ? x*=7 : x+=3; cmpq $-2, %rsi x+y val = ____________ ; cmovle %rdi, %rax return val; ret Executing both values causes incorrect behavior } Condition must hold to prevent fault Null pointer check – 17 – – 18 – Loops C example long factorial_do(long x) Implemented in assembly via tests and jumps { long result = 1; Compilers implement most loops as do-while do { Add additional check at beginning to get “ while-do ” result *= x; x = x-1; } while (x > 1); do { return result; body-statements } } while (test-expr); factorial_do: movq $1, %rax ; result = 1 .L2: imulq %rdi, %rax ; result *= x subq $1, %rdi ; x = x - 1 cmpq $1, %rdi ; if x > 1 jg .L2 ; goto loop ret ; return result http://thefengs.com/wuchang/courses/cs201/class/07 – 19 – – 20 – 5
12/22/2016 Are these equivalent? C code of while-do Assembly of while-do C code of do-while Assembly of do-while long factorial_do(long x) long factorial_while(long x) factorial_do: factorial_while: movq $1, %rax movq $1, %rax { { .L2: jmp .L2 long result = 1; long result = 1; imulq %rdi, %rax .L3: do { while (x > 1) { subq $1, %rdi imulq %rdi, %rax cmpq $1, %rdi subq $1, %rdi result *= x; result *= x; jg .L2 .L2: x = x-1; x = x-1; ret cmpq $1, %rdi } while (x > 1); } jg .L3 return result; return result; rep ret } } http://thefengs.com/wuchang/courses/cs201/class/07 diff factorial_do.s factorial_while.s – 21 – – 22 – “For” Loop Example “For” Loop Example General Form long factorial_for(long x) factorial_while: factorial_for: movq $1, %rax movq $1, %rax { for ( Init ; Test ; Update ) jmp .L2 jmp .L2 long result; .L3: .L3: Body for (result=1; x > 1; x=x-1) { imulq %rdi, %rax imulq %rdi, %rax result *= x; subq $1, %rdi subq $1, %rdi .L2: .L2: } cmpq $1, %rdi cmpq $1, %rdi return result; jg .L3 jg .L3 } ret ret Init Test Update result = 1 x > 1 x = x - 1 { http://thefengs.com/wuchang/courses/cs201/class/07 result *= x; Body diff factorial_for.s factorial_while.s } Is this code equivalent to the do-while version or the while-do version? – 23 – – 24 – 6
Recommend
More recommend