Download presentation
Presentation is loading. Please wait.
Published byBeverley Conley Modified over 9 years ago
1
1 Machine-Level Programming III: Arithmetic & Condition Codes Comp 21000: Introduction to Computer Organization & Systems March 2015 Systems book chapter 3* * Modified slides from the book “Computer Systems: a Programmer’s Perspective”, Randy Bryant & David O’Hallaron, 2011
2
2 Today Complete addressing mode, address computation (leal) Arithmetic operations Control: Condition codes Conditional branches While loops
3
3 Some Arithmetic Operations Two Operand Instructions: FormatComputation addl Src,DestDest = Dest + Src subl Src,DestDest = Dest Src imull Src,DestDest = Dest * Src sall Src,DestDest = Dest << SrcAlso called shll sarl Src,DestDest = Dest >> SrcArithmetic shrl Src,DestDest = Dest >> SrcLogical xorl Src,DestDest = Dest ^ Src andl Src,DestDest = Dest & Src orl Src,DestDest = Dest | Src Watch out for argument order! No distinction between signed and unsigned int (why?) No way to store result in different register in the instruction. Note the order: Dest is subtracted from
4
4 Some Arithmetic Operations One Operand Instructions incl DestDest = Dest + 1 decl DestDest = Dest 1 negl DestDest = Dest notl DestDest = ~Dest See book for more instructions
5
5 Arithmetic Expression Example int arith(int x, int y, int z) { int t1 = x+y; int t2 = z+t1; int t3 = x+4; int t4 = y * 48; int t5 = t3 + t4; int rval = t2 * t5; return rval; } int arith(int x, int y, int z) { int t1 = x+y; int t2 = z+t1; int t3 = x+4; int t4 = y * 48; int t5 = t3 + t4; int rval = t2 * t5; return rval; } arith: pushl%ebp movl%esp, %ebp movl8(%ebp), %ecx movl12(%ebp), %edx leal(%edx,%edx,2), %eax sall$4, %eax leal4(%ecx,%eax), %eax addl%ecx, %edx addl16(%ebp), %edx imull%edx, %eax leave ret Body Set Up Finish this is similar to what you’d see with optimization level 1 With optimization level 0 you won’t see lea instructions this is similar to what you’d see with optimization level 1 With optimization level 0 you won’t see lea instructions
6
6 16z 12y 8x 4Rtn Addr 0Old %ebp Understanding arith movl8(%ebp), %ecx movl12(%ebp), %edx leal(%edx,%edx,2), %eax sall$4, %eax leal4(%ecx,%eax), %eax addl%ecx, %edx addl16(%ebp), %edx imull%edx, %eax %ebp Offset int arith(int x, int y, int z) { int t1 = x+y; int t2 = z+t1; int t3 = x+4; int t4 = y * 48; int t5 = t3 + t4; int rval = t2 * t5; return rval; } int arith(int x, int y, int z) { int t1 = x+y; int t2 = z+t1; int t3 = x+4; int t4 = y * 48; int t5 = t3 + t4; int rval = t2 * t5; return rval; }
7
7 16z 12y 8x 4Rtn Addr 0Old %ebp Understanding arith %ebp Offset Stack int arith(int x, int y, int z) { int t1 = x+y; int t2 = z+t1; int t3 = x+4; int t4 = y * 48; int t5 = t3 + t4; int rval = t2 * t5; return rval; } int arith(int x, int y, int z) { int t1 = x+y; int t2 = z+t1; int t3 = x+4; int t4 = y * 48; int t5 = t3 + t4; int rval = t2 * t5; return rval; } movl8(%ebp), %ecx# ecx = x movl12(%ebp), %edx# edx = y leal(%edx,%edx,2), %eax# eax = y*3 sall$4, %eax# eax *= 16 (t4) leal4(%ecx,%eax), %eax# eax = t4 +x+4 (t5) addl%ecx, %edx# edx = x+y (t1) addl16(%ebp), %edx# edx += z (t2) imull%edx, %eax# eax = t2 * t5 (rval)
8
8 Observations about arith Instructions in different order from C code Some expressions require multiple instructions Some instructions cover multiple expressions Get exact same code when compile: (x+y+z)*(x+4+48*y) movl8(%ebp), %ecx# ecx = x movl12(%ebp), %edx# edx = y leal(%edx,%edx,2), %eax# eax = y*3 sall$4, %eax# eax *= 16 (t4) leal4(%ecx,%eax), %eax# eax = t4 +x+4 (t5) addl%ecx, %edx# edx = x+y (t1) addl16(%ebp), %edx# edx += z (t2) imull%edx, %eax# eax = t2 * t5 (rval) int arith(int x, int y, int z) { int t1 = x+y; int t2 = z+t1; int t3 = x+4; int t4 = y * 48; int t5 = t3 + t4; int rval = t2 * t5; return rval; } int arith(int x, int y, int z) { int t1 = x+y; int t2 = z+t1; int t3 = x+4; int t4 = y * 48; int t5 = t3 + t4; int rval = t2 * t5; return rval; }
9
9 Another Example int logical(int x, int y) { int t1 = x^y; int t2 = t1 >> 17; int mask = (1<<13) - 7; int rval = t2 & mask; return rval; } int logical(int x, int y) { int t1 = x^y; int t2 = t1 >> 17; int mask = (1<<13) - 7; int rval = t2 & mask; return rval; } logical: pushl %ebp movl %esp,%ebp movl 12(%ebp),%eax xorl 8(%ebp),%eax sarl $17,%eax andl $8185,%eax popl %ebp ret Body Set Up Finish movl 12(%ebp),%eax# eax = y xorl 8(%ebp),%eax# eax = x^y (t1) sarl $17,%eax# eax = t1>>17 (t2) andl $8185,%eax# eax = t2 & mask (rval)
10
10 Another Example int logical(int x, int y) { int t1 = x^y; int t2 = t1 >> 17; int mask = (1<<13) - 7; int rval = t2 & mask; return rval; } int logical(int x, int y) { int t1 = x^y; int t2 = t1 >> 17; int mask = (1<<13) - 7; int rval = t2 & mask; return rval; } logical: pushl %ebp movl %esp,%ebp movl 12(%ebp),%eax xorl 8(%ebp),%eax sarl $17,%eax andl $8185,%eax popl %ebp ret Body Set Up Finish movl 12(%ebp),%eax# eax = y xorl 8(%ebp),%eax# eax = x^y (t1) sarl $17,%eax# eax = t1>>17 (t2) andl $8185,%eax# eax = t2 & mask (rval)
11
11 Another Example int logical(int x, int y) { int t1 = x^y; int t2 = t1 >> 17; int mask = (1<<13) - 7; int rval = t2 & mask; return rval; } int logical(int x, int y) { int t1 = x^y; int t2 = t1 >> 17; int mask = (1<<13) - 7; int rval = t2 & mask; return rval; } logical: pushl %ebp movl %esp,%ebp movl 12(%ebp),%eax xorl 8(%ebp),%eax sarl $17,%eax andl $8185,%eax popl %ebp ret Body Set Up Finish movl 12(%ebp),%eax# eax = y xorl 8(%ebp),%eax# eax = x^y (t1) sarl $17,%eax# eax = t1>>17 (t2) andl $8185,%eax# eax = t2 & mask (rval)
12
12 Another Example int logical(int x, int y) { int t1 = x^y; int t2 = t1 >> 17; int mask = (1<<13) - 7; int rval = t2 & mask; return rval; } int logical(int x, int y) { int t1 = x^y; int t2 = t1 >> 17; int mask = (1<<13) - 7; int rval = t2 & mask; return rval; } logical: pushl %ebp movl %esp,%ebp movl 12(%ebp),%eax xorl 8(%ebp),%eax sarl $17,%eax andl $8185,%eax popl %ebp ret Body Set Up Finish movl 12(%ebp),%eax# eax = y xorl 8(%ebp),%eax# eax = x^y (t1) sarl $17,%eax# eax = t1>>17 (t2) andl $8185,%eax# eax = t2 & mask (rval) 2 13 = 8192, 2 13 – 7 = 8185
13
13 Special Arithmetic Operations InstructionEffectDescription imull S mull S R[%edx]:R[%eax] S x R[%eax] Signed full multiply Unsigned full multiply cltd R[%edx]:R[%eax] SignExtend( R[%eax]) Convert to quad word idivl S R[%edx] R[%edx]:R[%eax] mod S; R[%eax] R[%edx]:R[%eax] / SSigned divide divl S R[%edx] R[%edx]:R[%eax] mod S; R[%edx] R[%edx]:R[%eax] / SUnsigned divide See explanation on next page.
14
14 iMull Note that there are two forms of imull, one with two operands and one with one operand. imull S, D Does 32-bit multiplication 32 bit Result is stored in D There may be overflow imull S Does 32-bit multiplication Multiplies 32 bits from S times 32 bits in %eax Result is 64 bits and is stored in %eax and %edx (always). High ordered bits are in %edx, low order bits in %eax.
15
15 Today Complete addressing mode, address computation (leal) Arithmetic operations Control: Condition codes Conditional branches Loops
16
16 Processor State (IA32, Partial) Information about currently executing program Temporary data ( %eax, … ) Location of runtime stack ( %ebp, %esp ) Location of current code control point ( %eip, … ) Status of recent tests ( CF, ZF, SF, OF ) %eip General purpose registers Current stack top Current stack frame Instruction pointer CFZFSFOF Condition codes %eax %ecx %edx %ebx %esi %edi %esp %ebp
17
17 Condition Codes (Implicit Setting) Single bit registers CF Carry Flag (for unsigned)SF Sign Flag (for signed) ZF Zero FlagOF Overflow Flag (for signed) Implicitly set (think of it as side effect) by arithmetic operations Example: addl/addq Src,Dest ↔ t = a+b CF set if carry out from most significant bit (unsigned overflow) ZF set if t == 0 SF set if t < 0 (as signed) OF set if two’s-complement (signed) overflow (a>0 && b>0 && t =0) Not set by lea instruction Full documentation Full documentation (IA32), link on course website
18
18 Condition Codes Examples: assume %eax contains 20 addl $10, %eaxCF 0 ZF 0 SF 0 OF 0 subl $50, %eaxCF 0 ZF 0 SF 1 OF 0
19
19 Condition Codes Single Bit Registers CF Carry Flag SF Sign Flag ZF Zero Flag OF Overflow Flag Also implicitly Set By logical Operations xorl Src,Dest C analog: t = a ^ b(a = Src, b = Dest) CF set to 0 ZF set if t == 0 SF set if t < 0 OF set to 0 For shift operations: CF set to last bit shifted out OF set to 0
20
20 Condition Codes (Implicit Setting) There are no Boolean types in assembly language. There is no concept of Boolean operators in assembly language. So what is there? Bits All we can do is look at bits. What those bits mean is determined by the context of the program. Instructions set flags. Other instructions take action based on the bits in those flags. Don’t think about it as comparison as in the C language sense.
21
21 Condition Codes (Explicit Setting: Compare) Explicit Setting by Compare Instruction cmpl/cmpq Src2, Src1 cmpl b,a like computing a-b without setting destination CF set if carry out from most significant bit (used for unsigned comparisons) ZF set if a == b SF set if (a-b) < 0 (as signed) OF set if two’s-complement (signed) overflow (a>0 && b 0 && (a-b)>0) Note: notice that the operands are in reverse order; b is the first operand, but we compute a – b! Note 2: there are also cmpw and cmpb instructions.
22
22 Example cmpl %eax, %ecx do %ecx - %eax then set condition codes NO other action taken! %eax 0000 %ecx 00000010 %edx 0000 %ebx 0000 %esi %edi %esp %ebp CFZFSFOF Condition codes ??
23
23 Example cmpl %eax, %ecx do %ecx - %eax then set condition codes NO other action taken! %eax 0000 %ecx 00000010 %edx 0000 %ebx 0000 %esi %edi %esp %ebp CFZFSFOF Condition codes 0000
24
24 Condition Codes (Explicit Setting: Test) Explicit Setting by Test instruction testl / testq Src2, Src1 testl b,a like computing a&b without setting destination Sets condition codes based on value of Src1 & Src2 Useful to have one of the operands be a mask CF set to 0 ZF set when a&b == 0 SF set when a&b < 0 OF set to 0 Note: typically the same operand is repeated to test whether it is negative, zero, or positive: testl %eax, %eax sets the condition codes depending on the value in %eax Note 2: there are also testw and testb instructions. Remember that bitwise operations are more efficient than arithmetic
25
25 Reading Condition Codes SetX Instructions (the ‘X’ is replaced by some letter) Set single byte (with 0x00 or 0x01) based on combinations of condition codes The first instruction that reacts to a condition code! SetXConditionDescription sete DZF Equal / Zero D ZF setne D~ZF Not Equal / Not Zero D ~ZF sets DSF Negative D SF setns D~SF Nonnegative D ~SF setg D~(SF^OF)&~ZF Greater (Signed) D ~(SF^OF)&~ZF setge D~(SF^OF) Greater or Equal (Signed) D ~(SF^OF) setl D(SF^OF) Less (Signed) D (SF^OF) setle D(SF^OF)|ZF Less or Equal (Signed) D (SF^OF) | ZF seta D~CF&~ZF Above (unsigned) D ~CF&~ZF setb DCF Below (unsigned) D CF
26
26 Reading condition codes Consider: setl D (SF^OF)Less (Signed <)D (SF^OF ) First compare two numbers, a and b where both are in 2’s complement form using an arithmetic, logical, test or cmp instruction Then use setX to set a register with the result of the test cmpl%eax, %edx setl %al puts the result in byte register %al
27
27 Reading condition codes (cont) Assume a is in %eax and b in %edx cmpl%eax, %edx setl %al puts the result in byte register %al First instruction sets the condition code. cmpl computes b – a If b < a then b – a < 0 If there is no overflow, this is indicated by SF If there is positive overflow (b – a is large), we have b – a < 0 but OF is set If there is negative overflow (b – a is very small), we have b – a > 0 but OF is set In either case the sign flag will indicate the opposite of the sign of the true difference. Hence, use exclusive-or of the OF and SF Second instruction sets the %al register to 00000000 or 00000001 depending on the value of (SF^OF) setl D ; D (SF^OF )
28
28 Reading condition codes (cont) Example: assume %eax holds 20 and %edx holds 50 cmpl%eax, %edx 50 – 20, SF 0, OF 0 setl %al %al 0 ^ 0 = 00000000 Example: assume %eax holds 0x8000001 and %edx holds 20 cmpl%eax, %edx 20 – (-2147483647), SF 1, OF 1 setl %al %al 1 ^ 1 = 00000000setl gives false; 20 is not less than -2147483647 setl D ; D (SF^OF )
29
29 Reading condition codes (cont) Example: assume %eax holds 20 and %edx holds 0x8000001 cmpl%eax, %edx (-2147483647) - 20, SF 0, OF 1 0x80000001 + 0xFFFFFFEC = 0x7FFFFFED (note that 7 = 0111) setl %al %al 0 ^ 1 = 00000001setl gives true; -2147483647 is less than 20
30
30 Setg Greater (Signed) ~(SF^OF)&~ZF CFZFSFOF Condition codes ~SF&~OF If this is zero, can’t be > If the overflow flag is set, can’t be > if we did a cmpl or testl as the previous instruction. Why? First do an arith, logical, cmp or test. Then use the flags
31
31 movl 12(%ebp),%eax# eax = y cmpl %eax,8(%ebp)# Compare x - y setg %al# al = x > y movzbl %al,%eax# Zero rest of %eax Reading Condition Codes (Cont.) SetX Instructions (where X = g, l, le, etc): Set single byte(with 0x01) based on combination of condition codes One of 8 addressable byte registers Does not alter remaining 3 bytes Typically use movzbl to finish job int gt (int x, int y) { return x > y; } int gt (int x, int y) { return x > y; } Body 16 12y 8x 4Rtn Addr 0Old %ebp %ebp Offset Stack
32
32 Reading Condition Codes (Cont.) %eax %edx %ecx %ebx %esi %edi %esp %ebp %al%ah %dl%dh %cl%ch %bl%bh int gt (int x, int y) { return x > y; } movl 12(%ebp),%eax# eax = y cmpl %eax,8(%ebp)# Compare x : y setg %al# al = x > y movzbl %al,%eax# Zero rest of %eax Body y x Rtn adr Old % ebp %ebp 0 4 8 12 Offset Stack 16 All 0’s: 0000000000000000000000000 Either 00000000 or 00000001
33
33 0x0000000100000e42 :movl 12(%ebp),%eax 0x0000000100000e45 :cmpl %eax,8(%ebp) 0x0000000100000e48 :setg %al 0x0000000100000e4b :movzbl %al,%eax Reading Condition Codes (Cont.) To walk through this code in gdb: Compile with –g flag In gdb Set breakpoint e.g. at line 5 to see assembly code: disassemble gt run Then step through assembly code with nexti Examine registers with p/x $eax or for all registers: info registers To see which flags are set: info register eflags To determine where you are: (gdb) where #0 0x0000000100000e45 in gt (x=5, y=4) at setEx.c:5 #1 0x0000000100000e8f in main at setEx.c:14 int gt (int x, int y) { return x > y; } int gt (int x, int y) { return x > y; } $ not % One line of C may translate to many lines of assembly
34
34 Reading Condition Codes: x86-64 int gt (long x, long y) { return x > y; } int gt (long x, long y) { return x > y; } cmpl %esi, %edi setg %al movzbl %al, %eax Bodies long lgt (long x, long y) { return x > y; } long lgt (long x, long y) { return x > y; } SetX Instructions: Set single byte based on combination of condition codes Does not alter remaining 3 bytes Is %rax zero? Yes: 32-bit instructions set high order 32 bits to 0! cmpq %rsi, %rdi setg %al movzbl %al, %eax
35
35 Today Complete addressing mode, address computation (leal) Arithmetic operations x86-64 Control: Condition codes Conditional branches & Moves Loops
36
36 Jumping A jump instruction causes execution to jump to a new address Really just puts the argument of the jump into the EIP Jump destinations are usually indicated by a label A label marks a place in code 1xorl%eax, %eax 2jmp.L1 3movl(%eax), %edx 4.L1: popl %edx The instruction jmp.L1 causes program to skip line 3 jmp is an unconditional jump instruction Note that we wouldn’t really use the code this way!
37
37 Jumping A jump instruction has two types of arguments Direct jumps. Target is part of the instruction Use a label Indirect jumps. Target read from a register or memory. Use a ‘*’ followed by an operand specifier jmp *%eax or jmp *(%eax) Any addressing mode can be used Note that jmp is an unconditional jump instruction
38
38 Jumping Other jump instructions are conditional Either jump or continue executing at next instruction in the code Depends on some combination of the condition codes Names and conditions match the set instructions. Conditional jumps can only be direct Assembler changes labels into actual memory addresses See section 3.6.3 of the book Not very important now; will be very important in chapter 7
39
39 Jumping jX Instructions (the ‘X’ stands for a letter below) Jump to different part of code depending on condition codes jXConditionDescription jmp1 Unconditional jeZF Equal / Zero jne~ZF Not Equal / Not Zero jsSF Negative jns~SF Nonnegative jg~(SF^OF)&~ZF Greater (Signed) 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) jbCF Below (unsigned)
40
40 jg Greater (Signed) ~(SF^OF)&~ZF CFZFSFOF Condition codes ~SF&~OF If this is zero, can’t be > If the overflow flag is set, can’t be > if we did a cmpl or testl as the previous instruction. Why? First do an arith, logical, cmp or test. Then use the flags
41
41 Compiling code Reminder. You can obtain the assembly code with the command: gcc –O0 –m32 –S source.c Produces file code.s-S means stop after compiling If you want to gdb use the following command gcc -O0 -m32 -g -o executableName sourceName.c Use the –o0 flag (dash uppercase ‘O’ number zero) to eliminate optimization. Otherwise you’ll get strange register moving. Use the –g flag to have gcc generate the symbol table information that gdb will need. Use the –m32 flag to have gcc generate IA32 assembly (as opposed to 64 bit code)
42
42 Conditional Branch Example int absdiff(int x, int y) { int result; if (x > y) { result = x-y; } else { result = y-x; } return result; } int absdiff(int x, int y) { int result; if (x > y) { result = x-y; } else { result = y-x; } return result; } absdiff: pushl %ebp movl %esp, %ebp movl 8(%ebp), %edx movl 12(%ebp), %eax cmpl %eax, %edx jle.L6 subl %eax, %edx movl %edx, %eax jmp.L7.L6: subl %edx, %eax.L7: popl %ebp ret Body1 Setup Finish Body2b Body2a y x Rtn adr Old % ebp %ebp 0 4 8 12 Offset Stack x stored in %edx y stored in %eax
43
43 Conditional Branch Example (Cont.) int goto_ad(int x, int y) { int result; if (x <= y) goto Else; result = x-y; goto Exit; Else: result = y-x; Exit: return result; } int goto_ad(int x, int y) { int result; if (x <= y) goto Else; result = x-y; goto Exit; Else: result = y-x; Exit: return result; } C allows “goto” as means of transferring control Closer to machine-level programming style Generally considered bad coding style Body1 Setup Finish Body2b Body2a
44
44 Conditional Branch Example (Cont.) int goto_ad(int x, int y) { int result; if (x <= y) goto Else; result = x-y; goto Exit; Else: result = y-x; Exit: return result; } int goto_ad(int x, int y) { int result; if (x <= y) goto Else; result = x-y; goto Exit; Else: result = y-x; Exit: return result; } absdiff: pushl %ebp movl %esp, %ebp movl 8(%ebp), %edx movl 12(%ebp), %eax cmpl %eax, %edx jle.L6 subl %eax, %edx movl %edx, %eax jmp.L7.L6: subl %edx, %eax.L7: popl %ebp ret Body1 Setup Finish Body2b Body2a
45
45 Conditional Branch Example (Cont.) int goto_ad(int x, int y) { int result; if (x <= y) goto Else; result = x-y; goto Exit; Else: result = y-x; Exit: return result; } int goto_ad(int x, int y) { int result; if (x <= y) goto Else; result = x-y; goto Exit; Else: result = y-x; Exit: return result; } absdiff: pushl %ebp movl %esp, %ebp movl 8(%ebp), %edx movl 12(%ebp), %eax cmpl %eax, %edx jle.L6 subl %eax, %edx movl %edx, %eax jmp.L7.L6: subl %edx, %eax.L7: popl %ebp ret Body1 Setup Finish Body2b Body2a
46
46 Conditional Branch Example (Cont.) int goto_ad(int x, int y) { int result; if (x <= y) goto Else; result = x-y; goto Exit; Else: result = y-x; Exit: return result; } int goto_ad(int x, int y) { int result; if (x <= y) goto Else; result = x-y; goto Exit; Else: result = y-x; Exit: return result; } absdiff: pushl %ebp movl %esp, %ebp movl 8(%ebp), %edx movl 12(%ebp), %eax cmpl %eax, %edx jle.L6 subl %eax, %edx movl %edx, %eax jmp.L7.L6: subl %edx, %eax.L7: popl %ebp ret Body1 Setup Finish Body2b Body2a
47
47 C Code val = Test ? Then_Expr : Else_Expr; Goto Version nt = !Test; if (nt) goto Else; val = Then_Expr; goto Done; Else: val = Else_Expr; Done:... nt = !Test; if (nt) goto Else; val = Then_Expr; goto Done; Else: val = Else_Expr; Done:... General Conditional Expression Translation Test is expression returning integer = 0 interpreted as false ≠ 0 interpreted as true Create separate code regions for then & else expressions Execute appropriate one val = x>y ? x-y : y-x;
48
48 Example 2 Download ifStmt.c gcc –O0 –m32 –o ifStmt ifStmt.c gdb ifStmt In gdb: disass testIf1 int testIf1(int x, int y) { int result; if (x < y) result = x << 2; else result = y << 2; return result; }
49
49 Example 2 continued… Dump of assembler code for function testIf1: 0x00001e00 :push %ebp 0x00001e01 :mov %esp,%ebp 0x00001e03 :sub $0x14,%esp 0x00001e06 :mov 0xc(%ebp),%eax 0x00001e09 :mov 0x8(%ebp),%ecx 0x00001e0c :mov %ecx,-0x4(%ebp) 0x00001e0f :mov %eax,-0x8(%ebp) 0x00001e12 :mov -0x4(%ebp),%eax 0x00001e15 :mov -0x8(%ebp),%ecx Setting up the runtime stack Setting up local variables
50
50 Example 2 continued… 0x00001e18 :cmp %ecx,%eax 0x00001e1a :jge 0x1e2b 0x00001e1c :mov -0x4(%ebp),%eax 0x00001e1f :lea 0x0(,%eax,4),%eax 0x00001e26 :mov %eax,-0x14(%ebp) 0x00001e29 :jmp 0x1e38 0x00001e2b :mov -0x8(%ebp),%eax 0x00001e2e :lea 0x0(,%eax,4),%eax 0x00001e35 :mov %eax,-0x14(%ebp) 0x00001e38 :mov -0x14(%ebp),%eax 0x00001e3b :mov %eax,-0x10(%ebp) 0x00001e3e :mov -0x10(%ebp),%eax 0x00001e41 :mov %eax,-0xc(%ebp) 0x00001e44 :mov -0xc(%ebp),%eax 0x00001e47 :add $0x14,%esp 0x00001e4a :pop %ebp 0x00001e4b :ret End of assembler dump. if x >= y jump if x >= y jump else calculate y=y*4 and jump else calculate y=y*4 and jump calculate x=x*4 Set up the return value
51
51 C Code val = Test ? Then_Expr : Else_Expr; val = Test ? Then_Expr : Else_Expr; Goto Version tval = Then_Expr ; result = Else_Expr; t = Test; if (t) result = tval; return result; tval = Then_Expr ; result = Else_Expr; t = Test; if (t) result = tval; return result; Using Conditional Moves Conditional Move Instructions Instruction supports: if (Test) Dest Src Supported in post-1995 x86 processors GCC does not always use them Wants to preserve compatibility with ancient processors Enabled for x86-64 Use switch –march=686 for IA32 Why? Branches are very disruptive to instruction flow through pipelines Conditional move do not require control transfer
52
52 Conditional Move Example: x86-64 int absdiff(int x, int y) { int result; if (x > y) { result = x-y; } else { result = y-x; } return result; } int absdiff(int x, int y) { int result; if (x > y) { result = x-y; } else { result = y-x; } return result; } absdiff: movl%edi, %edx subl%esi, %edx# tval = x-y movl%esi, %eax subl%edi, %eax# result = y-x cmpl%esi, %edi# Compare x:y cmovg%edx, %eax # If >, result = tval ret x in %edi y in %esi
53
53 Expensive Computations Bad Cases for Conditional Move Both values get computed Only makes sense when computations are very simple val = Test(x) ? Hard1(x) : Hard2(x); Risky Computations Both values get computed May have undesirable effects val = p ? *p : 0; Computations with side effects Both values get computed Must be side-effect free val = x > 0 ? x*=7 : x+=3;
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.