University
of
Washington
Condi3onal
Branch
Example
int absdiff(int x, int y)
{
int result;
if (x > y) {
result = x-y;
} else {
result = y-x;
}
return result;
}
absdiff:
pushl
movl
movl
movl
cmpl
jle
subl
movl
.L8:
leave
ret
.L7:
subl
jmp
x86
%ebp
%esp, %ebp
8(%ebp), %edx
12(%ebp), %eax
%eax, %edx
.L7
%eax, %edx
%edx, %eax
Setup
Body1
Finish
%edx, %eax
.L8
Body2
University
of
Washington
Condi3onal
Branch
Example
(Cont.)
int goto_ad(int x, int y)
{
int result;
if (x <= y) goto Else;
result = x-y;
Exit:
return result;
Else:
result = y-x;
goto Exit;
}
int absdiff(int x, int y)
{
int result;
if (x > y) {
result = x-y;
} else {
result = y-x;
}
return result;
}
¢
¢
x86
C
allows
“goto”
as
means
of
transferring
control
§ Closer
to
machine-‐level
programming
style
Generally
considered
bad
coding
style
University
of
Washington
Condi3onal
Branch
Example
(Cont.)
absdiff:
pushl
movl
movl
movl
cmpl
jle
subl
movl
.L8:
leave
ret
.L7:
subl
jmp
int goto_ad(int x, int y)
{
int result;
if (x <= y) goto Else;
result = x-y;
Exit:
return result;
Else:
result = y-x;
goto Exit;
}
int x
int y
%edx
%eax
x86
%ebp
%esp, %ebp
8(%ebp), %edx
12(%ebp), %eax
%eax, %edx
.L7
%eax, %edx
%edx, %eax
%edx, %eax
.L8
University
of
Washington
Condi3onal
Branch
Example
(Cont.)
absdiff:
pushl
movl
movl
movl
cmpl
jle
subl
movl
.L8:
leave
ret
.L7:
subl
jmp
int goto_ad(int x, int y)
{
int result;
if (x <= y) goto Else;
result = x-y;
Exit:
return result;
Else:
result = y-x;
goto Exit;
}
int x
int y
%edx
%eax
x86
%ebp
%esp, %ebp
8(%ebp), %edx
12(%ebp), %eax
%eax, %edx
.L7
%eax, %edx
%edx, %eax
%edx, %eax
.L8
University
of
Washington
Condi3onal
Branch
Example
(Cont.)
absdiff:
pushl
movl
movl
movl
cmpl
jle
subl
movl
.L8:
leave
ret
.L7:
subl
jmp
int goto_ad(int x, int y)
{
int result;
if (x <= y) goto Else;
result = x-y;
Exit:
return result;
Else:
result = y-x;
goto Exit;
}
int x
int y
%edx
%eax
x86
%ebp
%esp, %ebp
8(%ebp), %edx
12(%ebp), %eax
%eax, %edx
.L7
%eax, %edx
%edx, %eax
%edx, %eax
.L8
University
of
Washington
Condi3onal
Branch
Example
(Cont.)
absdiff:
pushl
movl
movl
movl
cmpl
jle
subl
movl
.L8:
leave
ret
.L7:
subl
jmp
int goto_ad(int x, int y)
{
int result;
if (x <= y) goto Else;
result = x-y;
Exit:
return result;
Else:
result = y-x;
goto Exit;
}
int x
int y
%edx
%eax
x86
%ebp
%esp, %ebp
8(%ebp), %edx
12(%ebp), %eax
%eax, %edx
.L7
%eax, %edx
%edx, %eax
%edx, %eax
.L8
University
of
Washington
Condi3onal
Branch
Example
(Cont.)
absdiff:
pushl
movl
movl
movl
cmpl
jle
subl
movl
.L8:
leave
ret
.L7:
subl
jmp
int goto_ad(int x, int y)
{
int result;
if (x <= y) goto Else;
result = x-y;
Exit:
return result;
Else:
result = y-x;
goto Exit;
}
int x
int y
%edx
%eax
x86
%ebp
%esp, %ebp
8(%ebp), %edx
12(%ebp), %eax
%eax, %edx
.L7
%eax, %edx
%edx, %eax
%edx, %eax
.L8
University
of
Washington
General
Condi3onal
Expression
Transla3on
C
Code
val = Test ? Then-‐Expr : Else-‐Expr;
result = x>y ? x-y : y-x;
if (Test)
val = Then-‐Expr;
else
val = Else-‐Expr;
§ Test
is
expression
returning
integer
Goto
Version
=
0
interpreted
as
false
≠0
interpreted
as
true
§ Create
separate
code
regions
for
then
&
else
expressions
§ Execute
appropriate
one
nt = !Test;
if (nt) goto Else;
val = Then-‐Expr;
Done:
. . .
Else:
val = Else-‐Expr;
goto Done;
§ How
might
you
make
this
more
efficient?
x86
University
of
Washington
Condi3onals:
x86-‐64
int absdiff(
int x, int y)
{
int result;
if (x > y) {
result = x-y;
} else {
result = y-x;
}
return result;
}
¢
absdiff:
movl
movl
subl
subl
cmpl
cmovle
ret
# x in %edi, y in %esi
%edi, %eax # eax = x
%esi, %edx # edx = y
%esi, %eax # eax = x-y
%edi, %edx # edx = y-x
%esi, %edi # x:y
%edx, %eax # eax=edx if <=
Condi3onal
move
instruc3on
§
§
§
§
cmovC
src,
dest
Move
value
from
src
to
dest
if
condiBon
C
holds
More
efficient
than
condiBonal
branching
(simple
control
flow)
But
overhead:
both
branches
are
evaluated
x86
University
of
Washington
PC
Rela3ve
Addressing
0x100
0x102
0x104
…
0x172
l
l
cmp
je
…
…
add
r2, r3
0x70
r3, r4
PC
rela3ve
branches
are
relocatable
Absolute
branches
are
not
x86
0x1000
0x1002
0x1004
…
0x1072