You are on page 1of 23

Machine-Level Programming:

Branching
Vassar College

Setting Condition Codes Explicitly with Compare


• Compare Instruction: cmp S1, S2
• Similar to the sub (subtract) instruction
• Sets the condition codes according to the differences of their two operands (S2 – S1)
but without setting the destination operand
• Used to compare two numbers
• Example: cmp b,a
Read as: a compare b (also as a:b)
• Operands are reversed for a compare
• Why? AT&T vs Intel assembler syntax
• In Intel syntax, operands are reversed
• We use AT&T style syntax, so remember to switch the order of operands for
compare

2
Vassar College

Reading Condition Codes (SetX instrutions)


• SetX Instructions Instruction Synonym Effect Set condition
sete D setz D  ZF Equal / zero
• Set destination to 0
or 1 based on setne D setnz D  ~ZF Not equal / not zero
combinations of sets D D  SF Negative
condition codes setns D D  ~SF Nonnegative
• Destination must setg D setnle D  ~(SF ^ OF) & ~ZF Greater (signed >)
be a low-order setge D setnl D  ~(SF ^ OF) Greater or equal (signed >=)
byte register or setl D setnge D  SF ^ OF Less (signed <)
single byte setle D setng D  (SF ^ OF) | ZF Less or equal (signed <=)
memory location seta D setnbe D  ~CF & ~ZF Above (unsigned >)
• Does not alter setae D setnb D  ~CF Above or equal (unsigned >=)
remaining 7 bytes setb D setnae D  CF Below (unsigned <)
for register
setbe D setna D  CF | ZF Below or equal (unsigned <=)
destinations
3
Vassar College

Jumps
Instruction Synonym Jump condition Description
jmp Label 1 Direct jump
je Label jz ZF Equal / zero
jne Label jnz ~ZF Not Equal / not zero
js Label SF Negative
jns Label ~SF Nonnegative
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 or 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 <=)

4
Vassar College

Expressing with test and goto Code


• C has a goto statement (but don’t use it in your own code!)
• Jump to position designated by label
long absdiff_j(long x, long y)
long absdiff(long x, long y) {
{ long result;
long result; int ntest = x <= y;
if (x > y) if (ntest) goto Else;
result = x-y; result = x-y;
else return result;
result = y-x; Else:
return result; result = y-x;
} return result;
}

5
Vassar College

Branch Example
• Generation
linux> gcc –Og -S –fno-if-conversion control.c

long absdiff_j(long x, long y) absdiff:


{ cmpq %rsi, %rdi # x:y
long result; jle .L4
int ntest = x <= y; movq %rdi, %rax # x in %rax
if (ntest) goto Else; subq %rsi, %rax # x-y
result = x-y; ret
return result; .L4: # x <= y
Else: movq %rsi, %rax # y in %rax
result = y-x; subq %rdi, %rax # y-x
return result; ret
}
Register Use(s)
%rdi Argument x
Note: the jump condition is the logical not of the if condition! %rsi Argument y
%rax Return value 6
Vassar College

Branching with Unmodified Test


long bonus(long x) { long bonus(long x) {
if (x > 100) { if (x > 100) goto IF;
return 100; return add_bonus(x);
} IF:
else { return 100;
return add_bonus(x); }
}
}

bonus:
cmpq $100, %rdi
jg .L4
call add_bonus
ret
.L4: Register Use(s)
movl $100, %eax
%rdi Argument x
ret
%rax Return value

7
Vassar College

Conditional Example
long conditional(long x, long y, long z)
{
return x ? y : z;
}

Register Use(s)
conditional_with_jmp:
movq %rdx, %rax # z to %rax %rdi Argument x
testq %rdi, %rdi # CC set on x %rsi Argument y
je .L2 # jump if x == 0 %rdx Argument z
movq %rsi, %rax # return y
.L2: %rax Return value
ret

8
Vassar College

long switch_eg(long x, long y, long z){ Switch Statement


long w = 1;
switch(x) { Example
case 1:
w = y*z;
break; • Multiple case labels
case 2:
w = y-z; • Here: 5 & 6
/* Fall Through */
case 3:
• Fall through cases
w += z; • Here: 2
break;
case 5: • Missing cases
case 6: • Here: 4
w -= z;
break;
default:
w = 2;
}
return w;
}
9
Vassar College

Jump Table Structure


Switch Form Jump Table Jump Targets
switch(x) { jtab: Targ0 Targ0: Code Block
case val_0: 0
Block 0 Targ1
case val_1: Targ2 Targ1:
Block 1 Code Block
• 1
• • • •
case val_n-1: •
Block n–1 Targ2: Code Block
} Targn-1
2


Translation (Extended C) •
goto *JTab[x]; •

Targn-1: Code Block


n–1
10
Vassar College

Switch Statement Example


Register Use(s)
long switch_eg(long x, long y, long z){ %rdi Argument x
long w = 1; %rsi Argument y
switch(x) {
. . . %rdx Argument z
} %rax Return value
return w;
} Jump table
.section .rodata
.align 8
Setup: .L4:
.quad .L8 # x = 0
switch_eg: .quad .L3 # x = 1
.quad .L5 # x = 2
cmpq $6, %rdi # x:6 .quad .L9 # x = 3
ja .L8 # Use default .quad .L8 # x = 4
Indirect jmp *.L4(,%rdi,8) # goto *JTab[x] .quad .L7 # x = 5
jump .quad .L7 # x = 6

11
Vassar College

Jump Table Explanation


• Table Structure
• Each target requires 8 bytes
Jump table
• Base address at .L4
.section .rodata
.align 8
.L4:
• Jumping .quad
.quad
.L8 # x
.L3 # x
=
=
0
1
• Direct: jmp .L8 .quad
.quad
.L5 # x
.L9 # x
=
=
2
3
• Jump target is denoted by label .L8 .quad .L8 # x = 4
.quad .L7 # x = 5
.quad .L7 # x = 6
• Indirect: jmp *.L4(,%rdi,8)
• Start of jump table: .L4
• Must scale by factor of 8 (addresses are 8 bytes)
• Fetch target from effective Address .L4 + x*8
• Only for 0 ≤ x ≤ 6

12
Vassar College

Jump Table
Jump table
switch(x) {
.section .rodata case 1: // .L3
.align 8 w = y*z;
.L4: break;
.quad .L8 # x = 0
.quad .L3 # x = 1 case 2: // .L5
.quad .L5 # x = 2 w = yz;
.quad .L9 # x = 3 /* Fall Through */
.quad .L8 # x = 4
.quad .L7 # x = 5
case 3: // .L9
.quad .L7 # x = 6 w += z;
break;
case 5:
case 6: // .L7
w -= z;
• .L8 handles the default case break;
default: // .L8
w = 2;
}
13
Vassar College

Code Blocks (x == 1)
switch(x) { .L3:
case 1: // .L3 movq %rsi, %rax # y
w = y*z; imulq %rdx, %rax # y*z
break; ret
. . .
}

Register Use(s)
%rdi Argument x
%rsi Argument y
%rdx Argument z
%rax Return value

14
Vassar College

Handling Fall-Through

long w = 1;
. . .
switch(x) { case 2:
. . . w = y-z;
case 2: goto merge;
w = y-z;
/* Fall Through */
case 3:
w += z;
break;
. . .
case 3:
}
w = 1;

merge:
w += z;

15
Vassar College

Code Blocks (x == 2, x == 3)
.L5: # Case 2
long w = 1; movq %rsi, %rax # y
. . . subq %rdx, %rax # y-z
switch(x) { jmp .L6 # goto merge
. . . .L9: # Case 3
case 2: movl $1, %eax # w = 1
w = y-z; .L6: # merge:
/* Fall Through */ addq %rdx, %rax # w += z
case 3: ret
w += z;
break;
. . .
Register Use(s)
}
%rdi Argument x
%rsi Argument y
%rdx Argument z
%rax Return value

16
Vassar College

Code Blocks (x == 5, x == 6, default)


switch(x) { .L7: # Case 5,6
. . . movl $1, %eax # w = 1
case 5: // .L7 subq %rdx, %rax # w -= z
case 6: // .L7 ret
w -= z; .L8: # Default:
break; movl $2, %eax # 2
default: // .L8 ret
w = 2;
}

Register Use(s)
%rdi Argument x
%rsi Argument y
%rdx Argument z
%rax Return value

17
Conditional Moves
Instruction Synonym Move Condition Description
• Destination must be
cmove S,R cmovz ZF Equal / zero
a register
cmovne S,R cmovnz ~ZF Not equal / not zero
cmovs S,R SF Negative • Source can be
register or memory
cmovns S,R ~SF Nonnegative
location
cmovg S,R cmovnle ~(SF ^ OF) & ~ZF Greater (signed >)
cmovge S,R cmovnl ~(SF ^ OF) Greater or equal (signed >=) • Length is determined
by the name of the
cmovl S,R cmovnge SF ^ OF Less (signed <) destination register
cmovle S,R cmovng (SF ^ OF) | ZF Less or equal (signed <=)
cmova S,R cmovnbe ~CF & ~ZF Above (unsigned >)
cmovae S,R cmovnb ~CF Above or equal (Unsigned >=)
cmovb S,R cmovnae CF Below (unsigned <)
cmovbe S,R cmovna CF | ZF Below or equal (unsigned <=)

18
Using Conditional Moves
• Conditional Move Instructions
• Instruction supports: C Code
if (Test) Dest  Src val = Test ? Then_Expr : Else_Expr;
• Supported in post-1995 x86 processors
• GCC tries to use them
• But only when known to be safe Conditional Move Pseudo Code
val = Else_Expr;
eval = Then_Expr;
if (Test) val = eval;

19
Vassar College

Conditional Example
long conditional(long x, long y, long z)
{
return x ? y : z;
}

conditional_with_jmp: conditional_with_cmove:
movq %rdx, %rax # z to %rax testq %rdi, %rdi # CC set on x
testq %rdi, %rdi # CC set on x movq %rdx, %rax # z to %rax
je .L2 # jump if x == 0 cmovne %rsi, %rax # y to %rax if x!=0
movq %rsi, %rax # return y ret
.L2:
ret Register Use(s)
%rdi Argument x
%rsi Argument y
%rdx Argument z
%rax Return value
20
Vassar College

Conditional Move Example


long absdiff(long x, long y) absdiff:
{ movq %rdi, %rax # x
long result; subq %rsi, %rax # result = x-y
if (x > y) movq %rsi, %rdx # y
result = x-y; subq %rdi, %rdx # eval = y-x
else /* x <= y */ cmpq %rsi, %rdi # x:y
result = y-x; cmovle %rdx, %rax # if x<=y, result = eval
return result; ret
}
Register Use(s)
%rdi Argument x
%rsi Argument y
%rax Return value

21
Vassar College

Bad Cases for Conditional Move


Expensive Computations
val = Test(x) ? Hard1(x) : Hard2(x);

• Both values get computed


• Only makes sense when computations are very simple

Risky Computations
val = p ? *p : 0;

• Both values get computed


• May have undesirable effects
Computations with side effects
val = x > 0 ? x*=7 : x+=3;

• Both values get computed


• Must be side-effect free

22
Summary
• jXX family of instructions are a conditional goto
• Changes the flow of instructions
• If statements
• If !(test) to jump to else branch
• Reorder code so else comes first and if (test) to jump to then branch
• Conditional moves
• Switch statements
• Often implemented as a jump table to handle cases
• Have to account for default and fall-through cases

23

You might also like