X86 Control Flow 5.2

X86 Control Flow 5.2

5.1 CS356 Unit 5 x86 Control Flow 5.2 JUMP/BRANCHING OVERVIEW 5.3 Concept of Jumps/Branches • Assembly is executed in sequential movq addq order by default ---- ---- • Jump instruction (aka "branches") ---- cause execution to skip ahead or ---- back to some other location movq • Jumps are used to implement control addq structures like if statements & loops ---- jmp ---- if( x < 0 ){ while ( x > 0 ){ ---- } else { } } 5.4 Jump/Branch Instructions • Jump (aka "branch") instructions allow us to jump backward or forward in our code • How? By manipulating the Program Counter (PC) • Operation: PC = PC + displacement – Compiler/programmer specifies a "label" for the instruction to branch to; then the assembler will determine the displacement Instrucs. In Memory Instrucs. In Memory Proc. Proc. 0x400 label ---- 0x400 ---- 0x404 PC/IP 0x400 0x404 jmp label PC/IP 0x424 ---- 0x408 0x408 ---- ---- . ---- . ---- . ---- 0x424 jmp label 0x424 label ---- ---- Jump Forward => Conditional Jump Back => Loop 5.5 Conditional vs. Unconditional Jumps • Two kinds of jumps/branches if( x < 0 ){ < ---- • Conditional ---- >= } – Jump only if a condition is true, else { otherwise continue sequentially } – x86 instructions: je, jne, jge, … (see next slides) while ( x < 0 ){ < – Need a way to compare and check >= conditions F } – Needed for if, while, for L1: jge L2 • Unconditional ---- ---- – Always jump to a new location jmp L1 – x86 instruction: jmp label L2: ---- x86 View 5.6 Condition Codes MAKING A DECISION 5.7 Condition Codes (Flags) CS:APP 3.6.1 Processor • The processor hardware performs several %rax = 1 tests on the result of most instructions %rcx = 0x80000000 • Each test generates a True/False (1 or 0) outcome which are recorded in various bits of %rdx = 2 the FLAGS register in the process EFLAGS Reg • The tests and associated bits are: – SF = Sign Flag 31 11 7 6 0 • Tests if the result is negative (just a copy of the 0 0 0 0 MSB of the result of the instruction) – ZF = Zero Flag OF SF ZF CF • Tests if the result is equal to 0 subl %edx, %eax – OF = 2’s complement Overflow Flag 0 1 0 1 • Set if signed overflow has occurred OF SF ZF CF – CF = Carry Flag Unsigned Overflow • Not just the carry-out; 1 if unsigned overflow • Unsigned Overflow: if (ADD and Cout=1) or (SUB and Cout=0) 5.8 cmp and test Instructions • cmp[bwql] src1, src2 – Compares src2 to src1 (e.g. src2 < src1, src2 == src1) – Performs (src2 – src1) and sets the condition codes based on the result – src1 & src2 is not changed (subtraction result is only used for condition codes and then discarded) • test[bwql] src1, src2 – Performs (src1 & src2) and sets condition codes – src2 is not changed – Often used with the src1 = src2 (i.e. test %eax, %eax) to check if a value is 0 or negative 5.9 Condition Code Exercises Processor Registers 0000 0000 0000 0001 rax EFLAGS Reg 0000 0000 0000 0000 rbx 31 11 7 6 0 0000 0000 0000 8801 rcx ? ? ? ? 0000 0000 0000 0002 rdx OF SF ZF CF – addl $0x7fffffff,%rdx 0000 0000 8000 0001 rdx 1 1 0 0 – andb %al, %bl OF SF ZF CF 0 0 1 0 0000 0000 0000 0000 rbx OF SF ZF CF – addb $0xff, %al 0 0 1 1 0000 0000 0000 0000 rax OF SF ZF CF – cmpw $0x7000, %cx 0000 0000 0000 1801 result 1 0 0 0 0000 0000 0000 8801 rcx OF SF ZF CF 5.10 Conditional Branches Processor • Comparison in x86 is usually a 2-step %rax = 1 (2-instruction) process %rdx = 2 • Step 1: cmpl %edx, %eax – Execute an instruction that will compare or examine the data (e.g. cmp, test, etc.) EFLAGS Reg – Results of comparison will be saved in the EFLAGS register via the condition 31 11 7 6 0 codes 0 1 0 1 • Step 2: OF SF ZF CF – Use a conditional jump (je, jne, jl, etc.) that will check for a certain comparison jne L1 # jump if ZF=0 result of the previous instruction 0 1 0 0 OF SF ZF CF 5.11 Conditional Jump Instructions CS:APP 3.6.3 • Figure 3.15 from CS:APP, 3e Instruction Synonym Jump Condition Description jmp label jmp *(Operand) je label jz ZF Equal / zero jne label jnz ~ZF Not equal / not zero js label SF Negative jns label ~SF Non-negative jg label jnle ~(SF ^ OF) & ~ZF Greater (signed >) jge label jnl ~(SF ^ OF) Greater or Equal (signed >=) jl label jnge (SF ^ OF) Less (signed <) jle label jng (SF ^ OF) | ZF Less of equal (signed <=) ja label jnbe ~CF & ~ZF Above (unsigned >) jae label jnb ~CF Above or equal (unsigned >=) jb label jnae CF Below (unsigned <) jbe label jna CF | ZF Below or equal (unsigned <=) Reminder: For all jump instructions other than jmp (which is unconditional), some previous instruction (cmp, test, etc.) is needed to set the condition codes to be examined by the jmp 5.12 Condition Code Exercises Processor Registers 0000 0000 0000 0001 rax 0000 0000 0000 0002 rbx 0000 0000 ffff fffe rcx 0000 0000 0000 0000 rdx Order: f1: OF SF ZF CF __1__ testl %edx, %edx 0 0 1 0 __2__ je L2 __5___ L1: cmpw %bx, %ax 0 1 0 1 __6___ jge L3 __3,7_ L2: incl %ecx 0 1 0 0 0 0 1 1 __4,8_ js L1 ____9_ L3: ret 5.13 Control Structure Examples 1 CS:APP 3.6.5 // x = %edi, y = %esi, res = %rdx func1: void func1(int x, int y, int *res) cmpl %esi, %edi { jge .L2 movl %edi, (%rdx) if(x < y) *res = x; ret else *res = y; .L2: movl %esi, (%rdx) gcc -S -Og func1.c } ret // x = %edi, y = %esi, res = %rdx func2: void func2(int x, int y, int *res) cmpl $-1, %edi je .L6 { cmpl $-1, %esi if(x == -1 || y == -1) je .L6 *res = y-1; testl %edi, %edi else if(x > 0 && y < x) jle .L5 *res = x+1; cmpl %esi, %edi jle .L5 else addl $1, %edi *res = 0; movl %edi, (%rdx) ret } .L5: gcc -S –O3 func2.c movl $0, (%rdx) ret .L6: subl $1, %esi movl %esi, (%rdx) ret 5.14 Control Structure Examples 2 CS:APP 3.6.7 // str = %rdi func3: int func3(char str[]) movl $0, %eax { jmp .L2 .L3: int i = 0; addl $1, %eax while(str[i] != 0){ .L2: i++; movslq %eax, %rdx gcc -S -Og func3.c } cmpb $0, (%rdi,%rdx) return i; jne .L3 } ret func4: // dat = %rdi, len = %esi movl (%rdi), %eax int func4(int dat[], int len) movl $1, %edx { jmp .L2 int i, min = dat[0]; .L4: for(i=1; i < len; i++){ movslq %edx, %rcx movl (%rdi,%rcx,4), %ecx if(dat[i] < min){ cmpl %ecx, %eax min = dat[i]; jle .L3 } movl %ecx, %eax } gcc -S -Og func4.c .L3: return min; addl $1, %edx .L2: } cmpl %esi, %edx jl .L4 ret 5.15 Branch Displacements CS:APP 3.6.4 // dat = %rdi, len = %esi • Recall: Jumps perform PC = PC + displacement int func4(int dat[], int len) { • int i, min = dat[0]; Assembler converts jumps and labels to for(i=1; i < len; i++){ appropriate displacements if(dat[i] < min){ min = dat[i]; } • Examine the disassembled output (below) } return min; especially the machine code in the left column } – Displacements are in the 2nd byte of the instruction C Code – Recall: PC increments to point at next instruction while jump is fetched and BEFORE the jump is executed func4: movl (%rdi), %eax 0000000000000000 <func4>: movl $1, %edx 0: 8b 07 mov (%rdi),%eax jmp .L2 2: ba 01 00 00 00 mov $0x1,%edx .L4: 7: eb 0f jmp 18 <func4+0x18> movslq %edx, %rcx 9: 48 63 ca movslq %edx,%rcx movl (%rdi,%rcx,4), %ecx c: 8b 0c 8f mov (%rdi,%rcx,4),%ecx cmpl %ecx, %eax f: 39 c8 cmp %ecx,%eax jle .L3 11: 7e 02 jle 15 <func4+0x15> movl %ecx, %eax 13: 89 c8 mov %ecx,%eax .L3: 15: 83 c2 01 add $0x1,%edx addl $1, %edx 18: 39 f2 cmp %esi,%edx .L2: 1a: 7c ed jl 9 <func4+0x9> cmpl %esi, %edx 1c: f3 c3 retq jl .L4 ret x86 Disassembled Output x86 Assembler 5.16 CONDITIONAL MOVES 5.17 Cost of Jumps CS:APP 3.6.6 func1: • Fact: Modern processors execute multiple instructions cmpl $-1, %edi je .L6 at one time cmpl $-1, %esi je .L6 – While earlier instructions are executing the processor testl %edi, %edi jle .L5 can be fetching and decoding later instructions cmpl %esi, %edi jl .L5 – This overlapped execution is known as pipelining and is addl $1, %edi movl %edi, (%rdx) key to obtaining good performance ret .L5: • Problem: Conditional jumps limit pipelining because movl $0, (%rdx) ret when we reach a jump, the comparison results it relies .L6: subl $1, %esi on may not be computed yet movl %esi, (%rdx) ret – It is unclear which instruction to fetch next – To be safe we have to stop and wait for the jump condition to be known time cmpl fetch decode execute jne fetch decode execute ??? fetch 5.18 Cost of Jumps func1: • Solution: When modern processors reach a Currently executing cmpl $-1, %edi Fetching here je .L6 jump before the comparison condition is cmpl $-1, %esi known, it will predict whether the jump Should we go je .L6 sequentially or jump? testl %edi, %edi condition will be true (aka "branch jle .L5 cmpl %esi, %edi prediction") and "speculatively" execute down jl .L5 addl $1, %edi the chosen path movl %edi, (%rdx) ret – If the guess is right…we win and get good .L5: performance movl $0, (%rdx) ret – If the guess is wrong…we lose and will have to .L6: subl $1, %esi throw away the wrongly fetched/decoded movl %esi, (%rdx) instructions once we realize the jump was ret mispredicted 5.19 Conditional Move Concept int cmove1(int x, int* res) { if(x > 5) *res = x+1; • Potential better solution: Be more else *res = x-1; pipelining friendly and compute both } results and only store the correct result C Code cmove1: when the condition is known cmpl $5, %edi jle .L2 • Allows for pure sequential execution addl $1, %edi movl %edi, (%rsi) – ret With jumps, we had to choose which .L2: instruction to fetch next subl $1, %edi movl %edi, (%rsi) – With conditional moves, we only need to ret choose whether to save or discard a With Jumps (-Og Optimization) computed result cmove1: int cmove1(int x) leal 1(%rdi), %edx { leal -1(%rdi), %eax int then_val = x+1; cmpl $6, %edi int temp = x-1; cmovge %edx, %eax if(x > 5) temp = then_val; movl %eax, (%rsi) *res = temp; ret } Equivalent C code With Conditional Moves (-O3 Optimization) 5.20 Conditional Move Instruction • Similar to (cond) ? x : y • Syntax: cmov[cond] src, reg – Cond = Same conditions as jumps (e, ne, l, le, g, ge) – Destination must be a register – If condition is true, reg = src – If condition is false, reg is unchanged (i.e.

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    32 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