eax - University of Washington

University of Washington
Roadmap
C:
Java:
car *c = malloc(sizeof(car));
c->miles = 100;
c->gals = 17;
float mpg = get_mpg(c);
free(c);
Car c = new Car();
c.setMiles(100);
c.setGals(17);
float mpg =
c.getMPG();
Assembly
language:
Machine
code:
get_mpg:
pushq
movq
...
popq
ret
%rbp
%rsp, %rbp
Memory & data
Integers & floats
Machine code & C
x86 assembly
Procedures & stacks
Arrays & structs
Memory & caches
Processes
Virtual memory
Memory allocation
Java vs. C
%rbp
OS:
0111010000011000
100011010000010000000010
1000100111000010
110000011111101000011111
Computer
system:
Autumn 2014
x86 Programming
1
University of Washington
Next x86 topics




Autumn 2014
Move instructions, registers, and operands
Memory addressing modes
swap example: 32-bit vs. 64-bit
Arithmetic operations
x86 Programming
2
University of Washington
What Is A Register (again)?

A location in the CPU that stores a small amount of data,
which can be accessed very quickly (once every clock cycle)

Registers have names, not addresses.

Registers are at the heart of assembly programming
 They are a precious commodity in all architectures, but especially x86
Autumn 2014
x86 Programming
3
University of Washington
general purpose
Integer Registers (IA32)
Origin
(mostly obsolete)
%eax
accumulate
%ecx
counter
%edx
data
%ebx
base
%esi
source
index
%edi
destination
index
stack
pointer
base
pointer
%esp
%ebp
32-bits wide
Autumn 2014
x86 Programming
4
University of Washington
general purpose
Integer Registers (IA32)
Origin
(mostly obsolete)
%eax
%ax
%ah
%al
accumulate
%ecx
%cx
%ch
%cl
counter
%edx
%dx
%dh
%dl
data
%ebx
%bx
%bh
%bl
base
%esi
%si
source
index
%edi
%di
destination
index
%esp
%sp
%ebp
%bp
stack
pointer
base
pointer
16-bit virtual registers
(backwards compatibility)
Autumn 2014
x86 Programming
5
University of Washington
x86-64 Integer Registers
64-bits wide
%rax
%eax
%r8
%r8d
%rbx
%ebx
%r9
%r9d
%rcx
%ecx
%r10
%r10d
%rdx
%edx
%r11
%r11d
%rsi
%esi
%r12
%r12d
%rdi
%edi
%r13
%r13d
%rsp
%esp
%r14
%r14d
%rbp
%ebp
%r15
%r15d
 Extend existing registers, and add 8 new ones; all accessible as 8, 16, 32, 64 bits.
Autumn 2014
x86 Programming
6
University of Washington
Assembly Data Types

“Integer” data of 1, 2, 4 (IA32), or 8 (just in x86-64) bytes
 Data values
 Addresses (untyped pointers)

Floating point data of 4, 8, or 10 bytes

What about “aggregate” types such as arrays?
 Just contiguous memory locations
Autumn 2014
x86 Programming
7
University of Washington
Three Basic Kinds of Instructions

Transfer data between memory and register
 Load data from memory into register
Remember:
memory is indexed
just like an array[]
of bytes!
%reg = Mem[address]
 Store register data into memory
 Mem[address] = %reg


Perform arithmetic function on register or memory data
 c = a + b;

z = x << y;
i = h & g;
Transfer control: what instruction to execute next
 Unconditional jumps to/from procedures
 Conditional branches
Autumn 2014
x86 Programming
8
University of Washington
Moving Data: IA32

%eax
%ecx
%edx
%ebx
%esi
%edi
%esp
%ebp
Moving Data
 movx Source, Dest
 x is one of {b, w, l}
 movl Source, Dest:
Move 4-byte “long word”
 movw Source, Dest:
Move 2-byte “word”
 movb Source, Dest:
Move 1-byte “byte”

confusing historical terms…
not the current machine word size
Lots of these in typical code
Autumn 2014
x86 Programming
9
University of Washington
Moving Data: IA32

Moving Data
movl Source, Dest:

Operand Types
 Immediate: Constant integer data
%eax
%ecx
%edx
%ebx
%esi
%edi
%esp
%ebp
Example: $0x400, $-533
 Like C constant, but prefixed with ‘$’
 Encoded with 1, 2, or 4 bytes
 Register: One of 8 integer registers
 Example: %eax, %edx
 But %esp and %ebp reserved for special use
 Others have special uses for particular instructions
 Memory: 4 consecutive bytes of memory at address given by register
 Simplest example: (%eax)
 Various other “address modes”

Autumn 2014
x86 Programming
10
University of Washington
movl Operand Combinations
Source
movl
Dest
Src,Dest
C Analog
Imm
Reg movl $0x4,%eax
Mem movl $-147,(%eax)
var_a = 0x4;
Reg
Reg movl %eax,%edx
Mem movl %eax,(%edx)
var_d = var_a;
Mem
Reg
movl (%eax),%edx
*p_a = -147;
*p_d = var_a;
var_d = *p_a;
Cannot do memory-memory transfer with a single instruction.
How would you do it?
Autumn 2014
x86 Programming
11
University of Washington
Memory vs. registers



Autumn 2014
What is the main difference?
Addresses vs. Names
Big vs. Small
x86 Programming
12
University of Washington
Memory Addressing Modes: Basic

Indirect
(R)
Mem[Reg[R]]
 Register R specifies the memory address
movl (%ecx),%eax

Displacement D(R)
Mem[Reg[R]+D]
 Register R specifies a memory address

(e.g. the start of some memory region)
 Constant displacement D specifies the offset from that address
movl 8(%ebp),%edx
Autumn 2014
x86 Programming
13
University of Washington
Using Basic Addressing Modes
void swap(int *xp, int *yp)
{
int t0 = *xp;
int t1 = *yp;
*xp = t1;
*yp = t0;
}
swap:
pushl %ebp
movl %esp,%ebp
pushl %ebx
movl
movl
movl
movl
movl
movl
12(%ebp),%ecx
8(%ebp),%edx
(%ecx),%eax
(%edx),%ebx
%eax,(%edx)
%ebx,(%ecx)
movl -4(%ebp),%ebx
movl %ebp,%esp
popl %ebp
ret
Autumn 2014
x86 Programming
Set
Up
Body
Finish
14
Understanding Swap
Register
%ecx
%edx
%eax
%ebx
Value
yp
xp
t1
t0
register <-> variable
mapping
Autumn 2014
lower addresses
void swap(int *xp, int *yp)
{
int t0 = *xp;
int t1 = *yp;
*xp = t1;
*yp = t0;
}
higher addresses
University of Washington
movl
movl
movl
movl
movl
movl
Offset
12
yp
8
xp
4
Rtn adr
Stack
(in memory)
0 Old %ebp
%ebp
-4 Old %ebx
12(%ebp),%ecx
8(%ebp),%edx
(%ecx),%eax
(%edx),%ebx
%eax,(%edx)
%ebx,(%ecx)
x86 Programming
•
•
•
#
#
#
#
#
#
ecx
edx
eax
ebx
*xp
*yp
=
=
=
=
=
=
yp
xp
*yp (t1)
*xp (t0)
eax
ebx
15
123
456
0x120
0x11c
%eax
0x118
Offset
%edx
%ecx
%ebx
%esi
Autumn 2014
12
0x120
0x110
xp
8
0x124
0x10c
4
Rtn adr
0x108
0
0x104
-4
%esp
%ebp
yp
%ebp
%edi
0x114
0x104
movl
movl
movl
movl
movl
movl
12(%ebp),%ecx
8(%ebp),%edx
(%ecx),%eax
(%edx),%ebx
%eax,(%edx)
%ebx,(%ecx)
x86 Programming
#
#
#
#
#
#
ecx
edx
eax
ebx
*xp
*yp
0x100
=
=
=
=
=
=
lower addresses
Understanding Swap
Address
0x124
higher addresses
University of Washington
yp
xp
*yp (t1)
*xp (t0)
eax
ebx
16
University of Washington
Understanding Swap
123
Address
0x124
456
0x120
0x11c
%eax
0x118
Offset
%edx
%ecx 0x120
%ebx
%esi
Autumn 2014
12
0x120
0x110
xp
8
0x124
0x10c
4
Rtn adr
0x108
0
0x104
-4
%esp
%ebp
yp
%ebp
%edi
0x114
0x104
movl
movl
movl
movl
movl
movl
12(%ebp),%ecx
8(%ebp),%edx
(%ecx),%eax
(%edx),%ebx
%eax,(%edx)
%ebx,(%ecx)
x86 Programming
#
#
#
#
#
#
ecx
edx
eax
ebx
*xp
*yp
0x100
=
=
=
=
=
=
yp
xp
*yp (t1)
*xp (t0)
eax
ebx
17
University of Washington
Understanding Swap
123
Address
0x124
456
0x120
0x11c
%eax
0x118
%edx
0x124
%ecx
0x120
Offset
%ebx
%esi
Autumn 2014
12
0x120
0x110
xp
8
0x124
0x10c
4
Rtn adr
0x108
0
0x104
-4
%esp
%ebp
yp
%ebp
%edi
0x114
0x104
movl
movl
movl
movl
movl
movl
12(%ebp),%ecx
8(%ebp),%edx
(%ecx),%eax
(%edx),%ebx
%eax,(%edx)
%ebx,(%ecx)
x86 Programming
#
#
#
#
#
#
ecx
edx
eax
ebx
*xp
*yp
0x100
=
=
=
=
=
=
yp
xp
*yp (t1)
*xp (t0)
eax
ebx
18
University of Washington
Understanding Swap
123
Address
0x124
456
0x120
0x11c
%eax
456
%edx
0x124
%ecx
0x120
0x118
Offset
%ebx
%esi
Autumn 2014
12
0x120
0x110
xp
8
0x124
0x10c
4
Rtn adr
0x108
0
0x104
-4
%esp
%ebp
yp
%ebp
%edi
0x114
0x104
movl
movl
movl
movl
movl
movl
12(%ebp),%ecx
8(%ebp),%edx
(%ecx),%eax
(%edx),%ebx
%eax,(%edx)
%ebx,(%ecx)
x86 Programming
#
#
#
#
#
#
ecx
edx
eax
ebx
*xp
*yp
0x100
=
=
=
=
=
=
yp
xp
*yp (t1)
*xp (t0)
eax
ebx
19
University of Washington
Understanding Swap
123
Address
0x124
456
0x120
0x11c
%eax
456
%edx
0x124
%ecx
0x120
%ebx
0x118
Offset
123
%esi
Autumn 2014
12
0x120
0x110
xp
8
0x124
0x10c
4
Rtn adr
0x108
0
0x104
-4
%esp
%ebp
yp
%ebp
%edi
0x114
0x104
movl
movl
movl
movl
movl
movl
12(%ebp),%ecx
8(%ebp),%edx
(%ecx),%eax
(%edx),%ebx
%eax,(%edx)
%ebx,(%ecx)
x86 Programming
#
#
#
#
#
#
ecx
edx
eax
ebx
*xp
*yp
0x100
=
=
=
=
=
=
yp
xp
*yp (t1)
*xp (t0)
eax
ebx
20
University of Washington
Understanding Swap
456
Address
0x124
456
0x120
0x11c
%eax
456
456
%edx
0x124
%ecx
0x120
%ebx
0x118
Offset
123
%esi
Autumn 2014
12
0x120
0x110
xp
8
0x124
0x10c
4
Rtn adr
0x108
0
0x104
-4
%esp
%ebp
yp
%ebp
%edi
0x114
0x104
movl
movl
movl
movl
movl
movl
12(%ebp),%ecx
8(%ebp),%edx
(%ecx),%eax
(%edx),%ebx
%eax,(%edx)
%ebx,(%ecx)
x86 Programming
#
#
#
#
#
#
ecx
edx
eax
ebx
*xp
*yp
0x100
=
=
=
=
=
=
yp
xp
*yp (t1)
*xp (t0)
eax
ebx
21
University of Washington
Understanding Swap
456
Address
0x124
123
0x120
0x11c
%eax
456
%edx
0x124
%ecx
0x120
%ebx
0x118
Offset
123
%esi
Autumn 2014
12
0x120
0x110
xp
8
0x124
0x10c
4
Rtn adr
0x108
0
0x104
-4
%esp
%ebp
yp
%ebp
%edi
0x114
0x104
movl
movl
movl
movl
movl
movl
12(%ebp),%ecx
8(%ebp),%edx
(%ecx),%eax
(%edx),%ebx
%eax,(%edx)
%ebx,(%ecx)
x86 Programming
#
#
#
#
#
#
ecx
edx
eax
ebx
*xp
*yp
0x100
=
=
=
=
=
=
yp
xp
*yp (t1)
*xp (t0)
eax
ebx
22
University of Washington
x86-64 Integer Registers
64-bits wide
%rax
%eax
%r8
%r8d
%rbx
%ebx
%r9
%r9d
%rcx
%ecx
%r10
%r10d
%rdx
%edx
%r11
%r11d
%rsi
%esi
%r12
%r12d
%rdi
%edi
%r13
%r13d
%rsp
%esp
%r14
%r14d
%rbp
%ebp
%r15
%r15d
 Extend existing registers, and add 8 new ones; all accessible as 8, 16, 32, 64 bits.
Autumn 2014
x86 Programming
23
University of Washington
32-bit vs. 64-bit operands

Long word l (4 Bytes) ↔ Quad word q (8 Bytes)

New instruction forms:





again, confusing historical terms…
not the current machine word size
movl → movq
addl → addq
sall → salq
etc.
x86-64 can still use 32-bit instructions that generate 32-bit
results
 Higher-order bits of destination register are just set to 0
 Example: addl
Autumn 2014
x86 Programming
24
University of Washington
Swap Ints in 32-bit Mode
void swap(int *xp, int *yp)
{
int t0 = *xp;
int t1 = *yp;
*xp = t1;
*yp = t0;
}
Offset
•
•
•
12
yp
8
xp
Autumn 2014
movl
movl
movl
movl
movl
movl
12(%ebp),%ecx
8(%ebp),%edx
(%ecx),%eax
(%edx),%ebx
%eax,(%edx)
%ebx,(%ecx)
movl -4(%ebp),%ebx
movl %ebp,%esp
popl %ebp
ret
4
Rtn adr
0 Old %ebp
-4 Old %ebx
swap:
pushl %ebp
movl %esp,%ebp
pushl %ebx
Setup
Body
Finish
%ebp
x86 Programming
25
University of Washington
Swap Ints in 64-bit Mode
void swap(int *xp, int *yp)
{
int t0 = *xp;
int t1 = *yp;
*xp = t1;
*yp = t0;
}

swap:
movl
movl
movl
movl
retq
(%rdi), %edx
(%rsi), %eax
%eax, (%rdi)
%edx, (%rsi)
Arguments passed in registers (why useful?)
 First (xp) in %rdi, second (yp) in %rsi
 64-bit pointers


No stack operations required: faster
32-bit data
 Data held in registers %eax and %edx
 movl operation (the l refers to data width, not address width)
Autumn 2014
x86 Programming
26
University of Washington
Swap Long Ints in 64-bit Mode
void swap_l
(long int *xp, long int *yp)
{
long int t0 = *xp;
long int t1 = *yp;
*xp = t1;
*yp = t0;
}

swap_l:
movq
movq
movq
movq
retq
(%rdi), %rdx
(%rsi), %rax
%rax, (%rdi)
%rdx, (%rsi)
64-bit data
 Data held in registers %rax and %rdx
 movq operation
 “q” stands for quad-word
Autumn 2014
x86 Programming
27
University of Washington
Complete Memory Addressing Modes


Remember, the addresses used for accessing memory in mov (and
other) instructions can be computed in several different ways
Most General Form:
D(Rb,Ri,S)





D:
Rb:
Ri:
S:
Mem[Reg[Rb] + S*Reg[Ri] + D]
Constant “displacement” value represented in 1, 2, or 4 bytes
Base register: Any of the 8/16 integer registers
Index register: Any, except for %esp or %rsp; %ebp unlikely
Scale: 1, 2, 4, or 8 (why these numbers?)
Special Cases: can use any combination of D, Rb, Ri and S
(Rb,Ri)
Mem[Reg[Rb]+Reg[Ri]]
(S=1, D=0)
D(Rb,Ri)
Mem[Reg[Rb]+Reg[Ri]+D] (S=1)
(Rb,Ri,S)
Mem[Reg[Rb]+S*Reg[Ri]] (D=0)
Autumn 2014
x86 Programming
28
University of Washington
Address Computation Examples
Autumn 2014
%edx
0xf000
%ecx
0x100
(Rb,Ri)
D(,Ri,S)
(Rb,Ri,S)
D(Rb)
Mem[Reg[Rb]+Reg[Ri]]
Mem[S*Reg[Ri]+D]
Mem[Reg[Rb]+S*Reg[Ri]]
Mem[Reg[Rb] +D]
Expression
Address Computation
Address
0x8(%edx)
0xf000 + 0x8
0xf008
(%edx,%ecx)
0xf000 + 0x100
0xf100
(%edx,%ecx,4)
0xf000 + 4*0x100
0xf400
0x80(,%edx,2)
2*0xf000 + 0x80
0x1e080
x86 Programming
29
University of Washington
Address Computation Instruction

leal Src,Dest
 Src is address mode expression
 Set Dest to address computed by expression
(lea stands for load effective address)
 Example: leal (%edx,%ecx,4), %eax


Uses
 Computing addresses without a memory reference

E.g., translation of p = &x[i];
 Computing arithmetic expressions of the form x + k*i

Autumn 2014
k = 1, 2, 4, or 8
x86 Programming
30
University of Washington
Some Arithmetic Operations

Two Operand (Binary) Instructions:
Format
addl Src,Dest
Computation
Dest = Dest + Src
subl Src,Dest
Dest = Dest - Src
imull Src,Dest
Dest = Dest * Src
shll Src,Dest
Dest = Dest << Src
Also called sall
sarl Src,Dest
Dest = Dest >> Src
Arithmetic
shrl Src,Dest
Dest = Dest >> Src
Logical
xorl Src,Dest
Dest = Dest ^ Src
andl Src,Dest
Dest = Dest & Src
orl
Dest = Dest | Src
Src,Dest
Watch out for argument order! (especially subl)
 No distinction between signed and unsigned int (why?)

 except arithmetic vs. logical shift right
Autumn 2014
x86 Programming
31
University of Washington
Some Arithmetic Operations

One Operand (Unary) Instructions
incl Dest
Dest = Dest + 1
increment
decl Dest
Dest = Dest – 1
decrement
negl Dest
Dest = -Dest
negate
notl Dest
Dest = ~Dest
bitwise complement
See textbook section 3.5.5 for more instructions: mull, cltd,
idivl, divl

Autumn 2014
x86 Programming
32
University of Washington
Using leal for Arithmetic Expressions (IA32)
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;
}
Autumn 2014
arith:
pushl %ebp
movl %esp,%ebp
movl 8(%ebp),%eax
movl 12(%ebp),%edx
leal (%edx,%eax),%ecx
leal (%edx,%edx,2),%edx
sall $4,%edx
addl 16(%ebp),%ecx
leal 4(%edx,%eax),%eax
imull %ecx,%eax
movl %ebp,%esp
popl %ebp
ret
x86 Programming
Set
Up
Body
Finish
33
University of Washington
Understanding arith (IA32)
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;
}
movl 8(%ebp),%eax
movl 12(%ebp),%edx
leal (%edx,%eax),%ecx
leal (%edx,%edx,2),%edx
sall $4,%edx
addl 16(%ebp),%ecx
leal 4(%edx,%eax),%eax
imull %ecx,%eax
Autumn 2014
Offset
•
•
•
16
z
12
y
8
x
4
Rtn adr
0 Old %ebp
#
#
#
#
#
#
#
#
eax
edx
ecx
edx
edx
ecx
eax
eax
=
=
=
=
=
=
=
=
x86 Programming
Stack
%ebp
x
y
x+y (t1)
y + 2*y = 3*y
48*y (t4)
z+t1 (t2)
4+t4+x (t5)
t5*t2 (rval)
34
University of Washington
Understanding arith (IA32)
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;
}
movl 8(%ebp),%eax
movl 12(%ebp),%edx
leal (%edx,%eax),%ecx
leal (%edx,%edx,2),%edx
sall $4,%edx
addl 16(%ebp),%ecx
leal 4(%edx,%eax),%eax
imull %ecx,%eax
Autumn 2014
Offset
•
•
•
16
z
12
y
8
x
4
Rtn adr
0 Old %ebp
#
#
#
#
#
#
#
#
eax
edx
ecx
edx
edx
ecx
eax
eax
=
=
=
=
=
=
=
=
x86 Programming
Stack
%ebp
x
y
x+y (t1)
y + 2*y = 3*y
48*y (t4)
z+t1 (t2)
4+t4+x (t5)
t5*t2 (rval)
35
University of Washington
Understanding arith (IA32)
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;
}
movl 8(%ebp),%eax
movl 12(%ebp),%edx
leal (%edx,%eax),%ecx
leal (%edx,%edx,2),%edx
sall $4,%edx
addl 16(%ebp),%ecx
leal 4(%edx,%eax),%eax
imull %ecx,%eax
Autumn 2014
Offset
•
•
•
16
z
12
y
8
x
4
Rtn adr
0 Old %ebp
#
#
#
#
#
#
#
#
eax
edx
ecx
edx
edx
ecx
eax
eax
=
=
=
=
=
=
=
=
x86 Programming
Stack
%ebp
x
y
x+y (t1)
y + 2*y = 3*y
48*y (t4)
z+t1 (t2)
4+t4+x (t5)
t5*t2 (rval)
36
University of Washington
Understanding arith (IA32)
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;
}
movl 8(%ebp),%eax
movl 12(%ebp),%edx
leal (%edx,%eax),%ecx
leal (%edx,%edx,2),%edx
sall $4,%edx
addl 16(%ebp),%ecx
leal 4(%edx,%eax),%eax
imull %ecx,%eax
Autumn 2014
Offset
•
•
•
16
z
12
y
8
x
4
Rtn adr
0 Old %ebp
#
#
#
#
#
#
#
#
eax
edx
ecx
edx
edx
ecx
eax
eax
=
=
=
=
=
=
=
=
x86 Programming
Stack
%ebp
x
y
x+y (t1)
y + 2*y = 3*y
48*y (t4)
z+t1 (t2)
4+t4+x (t5)
t5*t2 (rval)
37
University of Washington
Observations about arith
 Assembly Instructions in
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;
}
movl 8(%ebp),%eax
movl 12(%ebp),%edx
leal (%edx,%eax),%ecx
leal (%edx,%edx,2),%edx
sall $4,%edx
addl 16(%ebp),%ecx
leal 4(%edx,%eax),%eax
imull %ecx,%eax
Autumn 2014




#
#
#
#
#
#
#
#
eax
edx
ecx
edx
edx
ecx
eax
eax
=
=
=
=
=
=
=
=
x86 Programming
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)
x
y
x+y (t1)
y + 2*y = 3*y
48*y (t4)
z+t1 (t2)
4+t4+x (t5)
t5*t2 (rval)
38
University of Washington
Another Example (IA32)
logical:
pushl %ebp
movl %esp,%ebp
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;
}
movl
xorl
sarl
andl
Set
Up
8(%ebp),%eax
12(%ebp),%eax
$17,%eax
$8185,%eax
Body
movl %ebp,%esp
popl %ebp
ret
movl
xorl
sarl
andl
Autumn 2014
8(%ebp),%eax
12(%ebp),%eax
$17,%eax
$8185,%eax
#
#
#
#
eax
eax
eax
eax
=
=
=
=
x
x^y
t1>>17
t2 & 8185
x86 Programming
Offset
Finish
•
•
•
12
y
8
x
4
Rtn adr
0
Old %ebp
Stack
%ebp
39
University of Washington
Another Example (IA32)
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
xorl
sarl
andl
8(%ebp),%eax
12(%ebp),%eax
$17,%eax
$8185,%eax
Body
movl %ebp,%esp
popl %ebp
ret
movl
xorl
sarl
andl
Autumn 2014
8(%ebp),%eax
12(%ebp),%eax
$17,%eax
$8185,%eax
Set
Up
eax
eax
eax
eax
=
=
=
=
x86 Programming
Finish
x
x^y
(t1)
t1>>17 (t2)
t2 & 8185
40
University of Washington
Another Example (IA32)
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
xorl
sarl
andl
8(%ebp),%eax
12(%ebp),%eax
$17,%eax
$8185,%eax
Body
movl %ebp,%esp
popl %ebp
ret
movl
xorl
sarl
andl
Autumn 2014
8(%ebp),%eax
12(%ebp),%eax
$17,%eax
$8185,%eax
Set
Up
eax
eax
eax
eax
=
=
=
=
x86 Programming
Finish
x
x^y
(t1)
t1>>17 (t2)
t2 & 8185
41
University of Washington
Another Example (IA32)
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
xorl
sarl
andl
Autumn 2014
8(%ebp),%eax
12(%ebp),%eax
$17,%eax
$8185,%eax
8(%ebp),%eax
12(%ebp),%eax
$17,%eax
$8185,%eax
Body
213 = 8192,
213 – 7 = 8185
…0010000000000000, …0001111111111001
movl
xorl
sarl
andl
Set
Up
eax
eax
eax
eax
movl %ebp,%esp
popl %ebp
ret
=
=
=
=
Finish
x
x^y
(t1)
t1>>17 (t2)
t2 & 8185
compiler
optimization
x86 Programming
42
University of Washington
Topics: control flow



Autumn 2014
Condition codes
Conditional and unconditional branches
Loops
x86 Programming
43
University of Washington
Conditionals and Control Flow

A conditional branch is sufficient to implement most control
flow constructs offered in higher level languages





Unconditional branches implement some related control flow
constructs


Autumn 2014
if (condition) then {...} else {…}
while (condition) {…}
do {…} while (condition)
for (initialization; condition; iterative) {...}
break, continue
In x86, we’ll refer to branches as “jumps” (either conditional
or unconditional)
x86 Programming
44
University of Washington
Jumping

jX Instructions
 Jump to different part of code depending on condition codes
 Takes address as argument
Autumn 2014
jX
Condition
Description
jmp
1
Unconditional
je
ZF
Equal / Zero
jne
~ZF
Not Equal / Not Zero
js
SF
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)
jb
CF
Below (unsigned)
x86 Programming
45
University of Washington
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
%eax
%ecx
%edx
%ebx
%esi
General purpose
registers
%edi
%esp
%ebp
Current stack top
%eip
Instruction pointer
CF ZF SF OF
Condition codes
Current stack frame
( CF,ZF,SF,OF )
Autumn 2014
x86 Programming
46
University of Washington
Condition Codes (Implicit Setting)

Single-bit registers
CF Carry Flag (for unsigned)
ZF Zero Flag

SF Sign Flag (for signed)
OF 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) || (a<0 && b<0 && t>=0)
Not set by lea instruction (beware!)
 Full documentation (IA32): http://www.jegerlehner.ch/intel/IntelCodeTable.pdf

Autumn 2014
x86 Programming
47
University of Washington
Condition Codes (Explicit Setting: Compare)

Single-bit registers
CF Carry Flag (for unsigned)
ZF Zero Flag

SF Sign Flag (for signed)
OF Overflow Flag (for signed)
Explicit Setting by Compare Instruction




Autumn 2014
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) || (a<0 && b>0 && (a-b)>0)
x86 Programming
48
University of Washington
Condition Codes (Explicit Setting: Test)

Single-bit registers
CF Carry Flag (for unsigned)
ZF Zero Flag

SF Sign Flag (for signed)
OF Overflow Flag (for signed)
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
 ZF set if a&b == 0
 SF set if a&b < 0
 testl %eax, %eax

Autumn 2014
Sets SF and ZF, check if eax is +,0,-
x86 Programming
49
University of Washington
Reading Condition Codes

SetX Instructions
 Set a single byte to 0 or 1 based on combinations of condition codes
SetX
sete
setne
sets
setns
setg
setge
setl
setle
seta
setb
Autumn 2014
Condition
ZF
~ZF
SF
~SF
~(SF^OF)&~ZF
~(SF^OF)
(SF^OF)
(SF^OF)|ZF
~CF&~ZF
CF
Description
Equal / Zero
Not Equal / Not Zero
Negative
Nonnegative
Greater (Signed)
Greater or Equal (Signed)
Less (Signed)
Less or Equal (Signed)
Above (unsigned)
Below (unsigned)
x86 Programming
50
University of Washington
Reading Condition Codes (Cont.)


SetX Instructions:
%eax
%ah %al
Set single byte to 0 or 1 based on combination of
condition codes
%ecx
%ch %cl
One of 8 addressable byte registers
%edx
%dh %dl
 Does not alter remaining 3 bytes
 Typically use movzbl to finish job
%ebx
%bh %bl
int gt (int x, int y)
{
return x > y;
}
%esi
%edi
%esp
%ebp
Body: y at 12(%ebp), x at 8(%ebp)
movl 12(%ebp),%eax
cmpl %eax,8(%ebp)
setg %al
movzbl %al,%eax
Autumn 2014
# eax = y
# Compare
x :each
y
What does
of
#these
al = instructions
x > y
do?
# Zero rest of %eax
x86 Programming
51
University of Washington
Reading Condition Codes (Cont.)


SetX Instructions:
%eax
%ah %al
Set single byte to 0 or 1 based on combination of
condition codes
%ecx
%ch %cl
One of 8 addressable byte registers
%edx
%dh %dl
 Does not alter remaining 3 bytes
 Typically use movzbl to finish job
%ebx
%bh %bl
int gt (int x, int y)
{
return x > y;
}
%esi
%edi
%esp
%ebp
Body: y at 12(%ebp), x at 8(%ebp)
movl 12(%ebp),%eax
cmpl %eax,8(%ebp)
setg %al
movzbl %al,%eax
Autumn 2014
#
#
#
#
eax = y
Compare x and y
al = x > y
Zero rest of %eax
x86 Programming
(x – y)
52
University of Washington
Jumping

jX Instructions
 Jump to different part of code depending on condition codes
 Takes address as argument
Autumn 2014
jX
Condition
Description
jmp
1
Unconditional
je
ZF
Equal / Zero
jne
~ZF
Not Equal / Not Zero
js
SF
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)
jb
CF
Below (unsigned)
x86 Programming
53
University of Washington
Conditional Branch Example
int absdiff(int x, int y)
{
int result;
if (x > y) {
result = x-y;
} else {
result = y-x;
}
return result;
}
Autumn 2014
absdiff:
pushl
movl
movl
movl
cmpl
jle
subl
movl
.L8:
leave
ret
.L7:
subl
jmp
x86 Programming
%ebp
%esp, %ebp
8(%ebp), %edx
12(%ebp), %eax
%eax, %edx
.L7
%eax, %edx
%edx, %eax
Setup
Body1
Finish
%edx, %eax
.L8
Body2
54
University of Washington
Conditional 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;
}


Autumn 2014
x86 Programming
C allows “goto” as means of
transferring control
 Closer to machine-level
programming style
Generally considered bad coding
style
55
University of Washington
Conditional 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 x
int y
Autumn 2014
%edx
%eax
absdiff:
pushl
movl
movl
movl
cmpl
jle
subl
movl
.L8:
leave
ret
.L7:
subl
jmp
x86 Programming
%ebp
%esp, %ebp
8(%ebp), %edx
12(%ebp), %eax
%eax, %edx
.L7
%eax, %edx
%edx, %eax
%edx, %eax
.L8
56
University of Washington
Conditional 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 x
int y
Autumn 2014
%edx
%eax
absdiff:
pushl
movl
movl
movl
cmpl
jle
subl
movl
.L8:
leave
ret
.L7:
subl
jmp
x86 Programming
%ebp
%esp, %ebp
8(%ebp), %edx
12(%ebp), %eax
%eax, %edx
.L7
%eax, %edx
%edx, %eax
%edx, %eax
.L8
57
University of Washington
Conditional 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 x
int y
Autumn 2014
%edx
%eax
absdiff:
pushl
movl
movl
movl
cmpl
jle
subl
movl
.L8:
leave
ret
.L7:
subl
jmp
x86 Programming
%ebp
%esp, %ebp
8(%ebp), %edx
12(%ebp), %eax
%eax, %edx
.L7
%eax, %edx
%edx, %eax
%edx, %eax
.L8
58
University of Washington
Conditional 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 x
int y
Autumn 2014
%edx
%eax
absdiff:
pushl
movl
movl
movl
cmpl
jle
subl
movl
.L8:
leave
ret
.L7:
subl
jmp
x86 Programming
%ebp
%esp, %ebp
8(%ebp), %edx
12(%ebp), %eax
%eax, %edx
.L7
%eax, %edx
%edx, %eax
%edx, %eax
.L8
59
University of Washington
Conditional 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 x
int y
Autumn 2014
%edx
%eax
absdiff:
pushl
movl
movl
movl
cmpl
jle
subl
movl
.L8:
leave
ret
.L7:
subl
jmp
x86 Programming
%ebp
%esp, %ebp
8(%ebp), %edx
12(%ebp), %eax
%eax, %edx
.L7
%eax, %edx
%edx, %eax
%edx, %eax
.L8
60
University of Washington
General Conditional Expression Translation
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
nt = !Test;
if (nt) goto Else;
val = Then-Expr;
Done:
. . .
Else:
val = Else-Expr;
goto Done;
Autumn 2014
= 0 interpreted as false
0 interpreted as true
 Create separate code regions for
then & else expressions
 Execute appropriate one
 How might you make this more
efficient?
x86 Programming
61
University of Washington
Conditionals: 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 <=
Conditional move instruction
 cmovC src, dest
 Move value from src to dest if condition C holds
 Why is this good?
Autumn 2014
x86 Programming
62
University of Washington
Conditionals: x86-64
int absdiff(
int x, int y)
{
int result;
if (x > y) {
result = x-y;
} else {
result = y-x;
}
return result;
}

# 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 <=
Conditional move instruction




Autumn 2014
absdiff:
movl
movl
subl
subl
cmpl
cmovle
ret
cmovC src, dest
Move value from src to dest if condition C holds
More efficient than conditional branching (simple control flow)
But overhead: both branches are evaluated
x86 Programming
63
University of Washington
PC Relative Addressing
0x100
0x102
0x104
…
0x172


Autumn 2014
cmp
je
…
…
add
r2, r3
0x70
r3, r4
0x1000
0x1002
0x1004
…
0x1072
PC relative branches are relocatable
Absolute branches are not
x86 Programming
64
University of Washington
Compiling Loops
C/Java code:
while ( sum != 0 ) {
<loop body>
}
Machine code:
loopTop:
cmpl $0, %eax
je
loopDone
<loop body code>
jmp
loopTop
loopDone:

How to compile other loops should be straightforward
 The only slightly tricky part is to be sure where the conditional branch
occurs: top or bottom of the loop
Autumn 2014
x86 Programming
65
University of Washington
“Do-While” Loop Example
C Code
int fact_do(int x)
{
int result = 1;
do {
result *= x;
x = x-1;
} while (x > 1);
return result;
}


Autumn 2014
Goto Version
int fact_goto(int x)
{
int result = 1;
loop:
result *= x;
x = x-1;
if (x > 1) goto loop;
return result;
}
Use backward branch to continue looping
Only take branch when “while” condition holds
x86 Programming
66
University of Washington
“Do-While” Loop Compilation
Goto Version
Assembly
Registers:
%edx
%eax
x
result
int
fact_goto(int x)
{
int result = 1;
fact_goto:
pushl %ebp
movl %esp,%ebp
movl $1,%eax
movl 8(%ebp),%edx
#
#
#
#
Setup
Setup
eax = 1
edx = x
loop:
result *= x;
x = x-1;
if (x > 1)
goto loop;
.L11:
imull %edx,%eax
decl %edx
cmpl $1,%edx
jg .L11
#
#
#
#
result *= x
Translation?
x-Compare x : 1
if > goto loop
return result;
}
Autumn 2014
movl %ebp,%esp
popl %ebp
ret
x86 Programming
# Finish
# Finish
# Finish
67
University of Washington
“Do-While” Loop Compilation
Goto Version
Assembly
Registers:
%edx
%eax
x
result
int
fact_goto(int x)
{
int result = 1;
fact_goto:
pushl %ebp
movl %esp,%ebp
movl $1,%eax
movl 8(%ebp),%edx
#
#
#
#
Setup
Setup
eax = 1
edx = x
loop:
result *= x;
x = x-1;
if (x > 1)
goto loop;
.L11:
imull %edx,%eax
decl %edx
cmpl $1,%edx
jg .L11
#
#
#
#
result *= x
x-Compare x : 1
if > goto loop
return result;
}
Autumn 2014
movl %ebp,%esp
popl %ebp
ret
x86 Programming
# Finish
# Finish
# Finish
68
University of Washington
General “Do-While” Translation
Goto Version
C Code
do
Body
while (Test);

Body: {
}

Autumn 2014
loop:
Body
if (Test)
goto loop
Statement1;
Statement2;
…
Statementn;
Test returns integer
= 0 interpreted as false
 0 interpreted as true
x86 Programming
69
University of Washington
“While” Loop Translation
C Code
int fact_while(int x)
{
int result = 1;
while (x > 1) {
result *= x;
x = x-1;
}
return result;
}
Goto Version
int fact_while_goto(int x)
{
int result = 1;
goto middle;
loop:
result *= x;
x = x-1;
middle:
if (x > 1)
goto loop;
return result;
}
Used by GCC for both IA32 & x86-64
 First iteration jumps over body computation within loop straight to test

Autumn 2014
x86 Programming
70
University of Washington
“While” Loop Example
int fact_while(int x)
{
int result = 1;
while (x > 1) {
result *= x;
x--;
};
return result;
}
Autumn 2014
# x in %edx, result in %eax
jmp
.L34
#
goto Middle
.L35:
# Loop:
imull %edx, %eax #
result *= x
decl %edx
#
x-.L34:
# Middle:
cmpl $1, %edx
#
x:1
jg
.L35
#
if >, goto
#
Loop
x86 Programming
71
University of Washington
“For” Loop Example: Square-and-Multiply
/* Compute x raised to nonnegative power p */
int ipwr_for(int x, unsigned int p)
{
int result;
for (result = 1; p != 0; p = p>>1) {
if (p & 0x1)
result *= x;
x = x*x;
xm * xn = xm+n
}
0
... 0
1 1 0 1 = 13
return result;
}
12^31 * ... * 116 * x8 * x4 * 12 * x1 = x13

1 = x 0 x = x1
Algorithm
 Exploit bit representation: p = p0 + 2p1 + 22p2 + … 2n–1pn–1
 Gives: xp = z0 · z1 2 · (z2 2) 2 · … · (…((zn –12) 2 )…) 2
zi = 1 when pi = 0
n–1 times
zi = x when pi = 1
 Complexity O(log p) = O(sizeof(p))
Autumn 2014
x86 Programming
Example
310 = 32 * 38
= 32 * ((32)2)2
72
University of Washington
ipwr Computation
/* Compute x raised to nonnegative power p */
int ipwr_for(int x, unsigned int p)
{
int result;
for (result = 1; p != 0; p = p>>1) {
if (p & 0x1)
result *= x;
x = x*x;
}
return result;
}
before iteration
result
x=3
p=10
1
2
3
4
5
1
1
9
9
59049
3
9
81
6561
43046721
10=10102
5= 1012
2= 102
1=
12
02
Autumn 2014
x86 Programming
73
University of Washington
“For” Loop Example
int result;
for (result = 1; p != 0; p = p>>1)
{
if (p & 0x1)
result *= x;
x = x*x;
}
General Form
for (Initialize; Test; Update)
Body
Init
result = 1
Test
p != 0
Update
p = p >> 1
Body
{
if (p & 0x1)
result *= x;
x = x*x;
}
Autumn 2014
x86 Programming
74
University of Washington
“For” “While”
For Version
for (Initialize; Test; Update )
Body
Goto Version
Initialize;
goto middle;
loop:
Body
Update ;
middle:
if (Test)
goto loop;
done:
While Version
Initialize;
while (Test ) {
Body
Update ;
}
Autumn 2014
x86 Programming
75
University of Washington
For-Loop: Compilation
For Version
for (Initialize; Test; Update )
Body
for (result = 1; p != 0; p = p>>1)
{
if (p & 0x1)
result *= x;
x = x*x;
}
Goto Version
Initialize;
goto middle;
loop:
Body
Update ;
middle:
if (Test)
goto loop;
done:
Autumn 2014
result = 1;
goto middle;
loop:
if (p & 0x1)
result *= x;
x = x*x;
p = p >> 1;
middle:
if (p != 0)
goto loop;
done:
x86 Programming
76
University of Washington
long switch_eg (unsigned
long x, long y, long z)
{
long w = 1;
switch(x) {
case 1:
w = y*z;
break;
case 2:
w = y/z;
/* Fall Through */
case 3:
w += z;
break;
case 5:
case 6:
w -= z;
break;
default:
w = 2;
}
return w;
}
Autumn 2014
Switch Statement
Example

Multiple case labels
 Here: 5, 6

Fall through cases
 Here: 2

Missing cases
 Here: 4

x86 Programming
Lots to manage, we
need a jump table
77
University of Washington
Jump Table Structure
switch(x) {
case val_0:
Block 0
case val_1:
Block 1
• • •
case val_n-1:
Block n–1
}
Jump Targets
Jump Table
Switch Form
JTab:
Targ0
Targ0:
Targ1
Targ2
•
•
•
Targn-1
Targ1:
Targ2:
Code Block
1
Code Block
2
•
•
•
Approximate Translation
target = JTab[x];
goto target;
Targn-1:
Autumn 2014
Code Block
0
x86 Programming
Code Block
n–1
78
University of Washington
Jump Table Structure
Memory
C code:
switch(x) {
case 1: <some code>
break;
case 2: <some code>
case 3: <some code>
break;
case 5:
case 6: <some code>
break;
default: <some code>
}
Code
Blocks
We can use the jump table when x <= 6:
if (x <= 6)
target = JTab[x];
goto target;
else
goto default;
Autumn 2014
Jump
Table
x86 Programming
0
1
2
3
4
5
6
79
University of Washington
Jump Table (IA32)
declaring data, not instructions
Jump table
.section .rodata
.align 4
.L62:
.long
.L61 #
.long
.L56 #
.long
.L57 #
.long
.L58 #
.long
.L61 #
.long
.L60 #
.long
.L60 #
4-byte memory alignment
x
x
x
x
x
x
x
=
=
=
=
=
=
=
switch(x) {
case 1:
// .L56
w = y*z;
break;
case 2:
// .L57
w = y/z;
/* Fall Through */
case 3:
// .L58
w += z;
break;
case 5:
case 6:
// .L60
w -= z;
break;
default:
// .L61
w = 2;
}
0
1
2
3
4
5
6
“long” as in movl: 4 bytes
would be .quad in x86-64
Autumn 2014
x86 Programming
80
University of Washington
Switch Statement Example (IA32)
long switch_eg(unsigned long x, long y,
long z)
{
long w = 1;
switch(x) {
. . .
}
return w;
}
Setup:
Autumn 2014
switch_eg:
pushl %ebp
movl %esp, %ebp
pushl %ebx
movl $1, %ebx
movl 8(%ebp), %edx
movl 16(%ebp), %ecx
cmpl $6, %edx
ja
.L61
jmp
*.L62(,%edx,4)
#
#
#
#
#
#
#
#
#
x86 Programming
Jump table
.section .rodata
.align 4
.L62:
.long
.L61 #
.long
.L56 #
.long
.L57 #
.long
.L58 #
.long
.L61 #
.long
.L60 #
.long
.L60 #
Setup
Setup
Setup
w = 1
edx = x
ecx = z
x:6
if Translation?
> goto default
goto JTab[x]
x
x
x
x
x
x
x
=
=
=
=
=
=
=
0
1
2
3
4
5
6
81
University of Washington
Switch Statement Example (IA32)
long switch_eg(unsigned long x, long y,
long z)
{
long w = 1;
switch(x) {
. . .
Jump table
}
.section .rodata
return w;
.align 4
}
.L62:
.long
.L61 #
switch_eg:
Setup:
.long
.L56 #
pushl %ebp
# Setup
.long
.L57 #
movl %esp, %ebp
# Setup
.long
.L58 #
.long
.L61 #
pushl %ebx
# Setup
.long
.L60 #
movl $1, %ebx
# w = 1
jump above
.long
.L60 #
movl
8(%ebp),
%edx
#
edx
=
x
(like jg, but
movl 16(%ebp), %ecx # ecx = z
unsigned)
cmpl $6, %edx
# x:6
Indirect
ja
.L61
# if > 6 goto
jump
default
jmp
*.L62(,%edx,4)
# goto JTab[x]
Autumn 2014
x86 Programming
x
x
x
x
x
x
x
=
=
=
=
=
=
=
0
1
2
3
4
5
6
82
University of Washington
Assembly Setup Explanation (IA32)

Table Structure
 Each target requires 4 bytes
 Base address at .L62

Jump table
Jumping: different address modes
for target
Direct: jmp .L61
 Jump target is denoted by label .L61
.section .rodata
.align 4
.L62:
.long
.L61 #
.long
.L56 #
.long
.L57 #
.long
.L58 #
.long
.L61 #
.long
.L60 #
.long
.L60 #
x
x
x
x
x
x
x
=
=
=
=
=
=
=
0
1
2
3
4
5
6
Indirect: jmp *.L62(,%edx,4)
 Start of jump table: .L62
 Must scale by factor of 4 (labels are 32-bits = 4 bytes on IA32)
 Fetch target from effective address .L62 + edx*4
 target = JTab[x]; goto target; (only for 0  x  6)
Autumn 2014
x86 Programming
83
University of Washington
Code Blocks (Partial)
switch(x) {
. . .
case 2:
// .L57
w = y/z;
/* Fall Through */
case 3:
// .L58
w += z;
break;
. . .
default:
// .L61
w = 2;
}
return w;
Autumn 2014
.L61: // Default case
movl $2, %ebx
# w = 2
jmp .L63
.L57: // Case 2:
movl 12(%ebp), %eax # y
cltd
# Div prep
idivl %ecx
# y/z
movl %eax, %ebx # w = y/z
# Fall through – no jmp
.L58: // Case 3:
addl %ecx, %ebx # w+= z
jmp .L63
...
.L63
movl %ebx, %eax # return w
popl %ebx
leave
ret
x86 Programming
84
University of Washington
Code Blocks (Rest)
switch(x) {
case 1:
// .L56
w = y*z;
break;
. . .
case 5:
case 6:
// .L60
w -= z;
break;
. . .
}
return w;
Autumn 2014
.L60: // Cases 5&6:
subl %ecx, %ebx # w –= z
jmp .L63
.L56: // Case 1:
movl 12(%ebp), %ebx # w = y
imull %ecx, %ebx
# w*= z
jmp .L63
...
.L63
movl %ebx, %eax
popl %ebx
leave
ret
x86 Programming
# return w
85
University of Washington
Code Blocks (Partial, return inlined)
switch(x) {
. . .
case 2:
// .L57
w = y/z;
/* Fall Through */
case 3:
// .L58
w += z;
break;
. . .
default:
// .L61
w = 2;
}
The compiler might choose to pull the
return statement in to each relevant
case rather than jumping out to it.
Autumn 2014
.L61: // Default case
movl $2, %ebx
# w = 2
movl %ebx, %eax # Return w
popl %ebx
leave
ret
.L57: // Case 2:
movl 12(%ebp), %eax # y
cltd
# Div prep
idivl %ecx
# y/z
movl %eax, %ebx # w = y/z
# Fall through – no jmp
.L58: // Case 3:
addl %ecx, %ebx # w+= z
movl %ebx, %eax # Return w
popl %ebx
leave
ret
x86 Programming
86
University of Washington
Code Blocks (Rest, return inlined)
switch(x) {
case 1:
// .L56
w = y*z;
break;
. . .
case 5:
case 6:
// .L60
w -= z;
break;
. . .
}
The compiler might choose to pull the
return statement in to each relevant
case rather than jumping out to it.
Autumn 2014
.L60: //
subl
movl
popl
leave
ret
.L56: //
movl
imull
movl
popl
leave
ret
x86 Programming
Cases 5&6:
%ecx, %ebx # w –= z
%ebx, %eax # Return w
%ebx
Case 1:
12(%ebp), %ebx # w = y
%ecx, %ebx
# w*= z
%ebx, %eax # Return w
%ebx
87
University of Washington
IA32 Object Code
Setup

 Label .L61 becomes address 0x08048630
 Label .L62 becomes address 0x080488dc
Assembly Code
switch_eg:
. . .
ja
.L61
# if > goto default
jmp
*.L62(,%edx,4) # goto JTab[x]
Disassembled Object Code
08048610 <switch_eg>:
. . .
08048622: 77 0c
08048624: ff 24 95 dc 88 04 08
Autumn 2014
x86 Programming
ja
jmp
8048630
*0x80488dc(,%edx,4)
88
University of Washington
IA32 Object Code (cont.)

Jump Table
 Doesn’t show up in disassembled code
 Can inspect using GDB
gdb asm-cntl
(gdb) x/7xw 0x080488dc
 Examine 7 hexadecimal format “words” (4-bytes each)
 Use command “help x” to get format documentation
0x080488dc:
0x08048630
0x08048650
0x0804863a
0x08048642
0x08048630
0x08048649
0x08048649
Autumn 2014
x86 Programming
89
University of Washington
Disassembled Targets
8048630:
8048635:
8048637:
8048638:
8048639:
804863a:
804863d:
804863e:
8048640:
8048642:
8048644:
8048646:
8048647:
8048648:
8048649:
804864b:
804864d:
804864e:
804864f:
8048650:
8048653:
8048656:
8048658:
8048659:
804865a:
Autumn 2014
bb
89
5b
c9
c3
8b
99
f7
89
01
89
5b
c9
c3
29
89
5b
c9
c3
8b
0f
89
5b
c9
c3
02 00 00 00
d8
45 0c
f9
c3
cb
d8
cb
d8
5d 0c
af d9
d8
x86 Programming
mov
mov
pop
leave
ret
mov
cltd
idiv
mov
add
mov
pop
leave
ret
sub
mov
pop
leave
ret
mov
imul
mov
pop
leave
ret
$0x2,%ebx
%ebx,%eax
%ebx
0xc(%ebp),%eax
%ecx
%eax,%ebx
%ecx,%ebx
%ebx,%eax
%ebx
%ecx,%ebx
%ebx,%eax
%ebx
0xc(%ebp),%ebx
%ecx,%ebx
%ebx,%eax
%ebx
90
University of Washington
Matching Disassembled Targets
0x08048630
0x08048650
0x0804863a
0x08048642
0x08048630
0x08048649
0x08048649
Autumn 2014
8048630:
8048635:
8048637:
8048638:
8048639:
804863a:
804863d:
804863e:
8048640:
8048642:
8048644:
8048646:
8048647:
8048648:
8048649:
804864b:
804864d:
804864e:
804864f:
8048650:
8048653:
8048656:
8048658:
8048659:
804865a:
x86 Programming
bb
89
5b
c9
c3
8b
99
f7
89
01
89
5b
c9
c3
29
89
5b
c9
c3
8b
0f
89
5b
c9
c3
02 00 00 00
d8
45 0c
f9
c3
cb
d8
cb
d8
5d 0c
af d9
d8
mov
mov
pop
leave
ret
mov
cltd
idiv
mov
add
mov
pop
leave
ret
sub
mov
pop
leave
ret
mov
imul
mov
pop
leave
ret
91
University of Washington
Question

Would you implement this with a jump table?
switch(x) {
case 0:
<some code>
break;
case 10:
<some code>
break;
case 52000: <some code>
break;
default:
<some code>
break;
}

Probably not:
 Don’t want a jump table with 52001 entries for only 4 cases (too big)
 about 200KB = 200,000 bytes
 text of this switch statement = about 200 bytes
Autumn 2014
x86 Programming
92
University of Washington
Quick Review

x86-64 vs. IA32
 Integer registers: 16 x 64-bit vs. 8 x 32-bit
 movq, addq, … vs. movl, addl, …
movq -> “move quad word” or 4*16-bits
 x86-64: better support for passing
function arguments in registers


%rax
%eax
%r8
%r8d
%rbx
%edx
%r9
%r9d
%rcx
%ecx
%r10
%r10d
%rdx
%ebx
%r11
%r11d
%rsi
%esi
%r12
%r12d
%rdi
%edi
%r13
%r13d
%rsp
%esp
%r14
%r14d
%rbp
%ebp
%r15
%r15d
Complete memory addressing mode
 (%eax), 17(%eax), 2(%ebx, %ecx, 8), …

Immediate (constant), Register, and Memory Operands




Autumn 2014
subl %eax, %ecx
sall $4,%edx
addl 16(%ebp),%ecx
imull %ecx,%eax
#
#
#
#
x86 Programming
ecx
edx
ecx
eax
=
=
=
=
ecx
edx
ecx
eax
- eax
<< 4
+ Mem[16+ebp]
* ecx
93
University of Washington
Quick Review

Control
 1-bit condition code registers
CF ZF SF OF
 Set as side effect by arithmetic instructions or by cmp, test
 Used:




Read out by setx instructions (setg, setle, …)
Or by conditional jumps (jle .L4, je .L10, …)
Or by conditional moves (cmovle %edx, %eax)
Arithmetic operations also set condition codes
 subl, addl, imull, shrl, etc.

Load Effective Address does NOT set condition codes
 leal 4(%edx,%eax),%eax
Autumn 2014
# eax = 4 + edx + eax
x86 Programming
94
University of Washington
Quick Review

Do-While loop
C Code
do
Body
while (Test);

loop:
Body
if (Test)
goto loop
While-Do loop
Do-While Version
While version
while (Test)
Body
if (!Test)
goto done;
do
Body
while(Test);
done:
or
Autumn 2014
Goto Version
x86 Programming
Goto Version
if (!Test)
goto done;
loop:
Body
if (Test)
goto loop;
done:
goto middle;
loop:
Body
middle:
if (Test)
goto loop;
95
University of Washington
Control Flow Summary


C Control
 if-then-else
 do-while
 while, for
 switch

Assembler Control
 Conditional jump
 Conditional move
 Indirect jump
 Compiler
 Must generate assembly code

Standard Techniques
 Loops converted to do-while form
 Large switch statements use jump tables
 Sparse switch statements may use
decision trees (see textbook)
Conditions in CISC
 CISC machines generally have condition
code registers
to implement more complex control
Autumn 2014
x86 Programming
96