0% found this document useful (0 votes)
18 views96 pages

Roadmap: Java: C

The document discusses x86 assembly programming concepts including registers, data types, instruction types, and moving data between registers and memory. It covers integer registers and their sizes in 32-bit and 64-bit x86 architectures. It also discusses the three basic types of instructions - data transfer, arithmetic, and control transfer.

Uploaded by

oreh2345
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views96 pages

Roadmap: Java: C

The document discusses x86 assembly programming concepts including registers, data types, instruction types, and moving data between registers and memory. It covers integer registers and their sizes in 32-bit and 64-bit x86 architectures. It also discusses the three basic types of instructions - data transfer, arithmetic, and control transfer.

Uploaded by

oreh2345
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 96

University of Washington

Roadmap Memory & data


Integers & floats
Machine code & C
C: Java:
x86 assembly
car *c = malloc(sizeof(car)); Car c = new Car(); Procedures & stacks
c->miles = 100; c.setMiles(100);
Arrays & structs
c->gals = 17; c.setGals(17);
float mpg = get_mpg(c); float mpg =
Memory & caches
free(c); c.getMPG(); Processes
Virtual memory
Assembly get_mpg: Memory allocation
language: pushq %rbp Java vs. C
movq %rsp, %rbp
...
popq %rbp
ret
OS:
Machine 0111010000011000
100011010000010000000010
code: 1000100111000010
110000011111101000011111

Computer
system:

Autumn 2013 x86 Programming 1


University of Washington

Next x86 topics

¢ Move instructions, registers, and operands


¢ Memory addressing modes
¢ swap example: 32-bit vs. 64-bit
¢ Arithmetic operations

Autumn 2013 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 2013 x86 Programming 3


University of Washington

Integer Registers (IA32) Origin


(mostly obsolete)

%eax accumulate

%ecx counter
general purpose

%edx data

%ebx base

source
%esi index

destination
%edi index
stack
%esp pointer
base
%ebp pointer

32-bits wide
Autumn 2013 x86 Programming 4
University of Washington

Integer Registers (IA32) Origin


(mostly obsolete)

%eax %ax %ah %al accumulate

%ecx %cx %ch %cl counter


general purpose

%edx %dx %dh %dl data

%ebx %bx %bh %bl base

source
%esi %si index

destination
%edi %di index
stack
%esp %sp pointer
base
%ebp %bp
pointer

16-bit virtual registers


(backwards compatibility)
Autumn 2013 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 2013 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 2013 x86 Programming 7


University of Washington

Three Basic Kinds of Instructions


¢ Transfer data between memory and register
§ Load data from memory into register
§ %reg = Mem[address] Remember:
§ Store register data into memory memory is indexed
just like an array[]
§ Mem[address] = %reg
of bytes!

¢ 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 2013 x86 Programming 8


University of Washington

Moving Data: IA32 %eax


%ecx
¢ Moving Data %edx
§ movx Source, Dest
%ebx
§ x is one of {b, w, l}
%esi
§ movl Source, Dest: %edi
Move 4-byte “long word” %esp
§ movw Source, Dest:
%ebp
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 2013 x86 Programming 9


University of Washington

Moving Data: IA32 %eax


¢ Moving Data %ecx
movl Source, Dest: %edx
¢ Operand Types %ebx
§ Immediate: Constant integer data %esi
§Example: $0x400, $-533 %edi
§ Like C constant, but prefixed with ‘$’
%esp
§ Encoded with 1, 2, or 4 bytes
§ Register: One of 8 integer registers
%ebp
§ 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 2013 x86 Programming 10
University of Washington

movl Operand Combinations

Source Dest Src,Dest C Analog

Reg movl $0x4,%eax var_a = 0x4;


Imm
Mem movl $-147,(%eax) *p_a = -147;

movl Reg Reg movl %eax,%edx var_d = var_a;


Mem movl %eax,(%edx) *p_d = var_a;

Mem Reg movl (%eax),%edx var_d = *p_a;

Cannot do memory-memory transfer with a single instruction.


How would you do it?
Autumn 2013 x86 Programming 11
University of Washington

Memory vs. registers


¢ What is the main difference?
¢ Addresses vs. Names
¢ Big vs. Small

Autumn 2013 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 2013 x86 Programming 13


University of Washington

Using Basic Addressing Modes


swap:
pushl %ebp
movl %esp,%ebp Set
void swap(int *xp, int *yp) pushl %ebx Up
{
int t0 = *xp; movl 12(%ebp),%ecx
int t1 = *yp; movl 8(%ebp),%edx
*xp = t1; movl (%ecx),%eax
*yp = t0; Body
movl (%edx),%ebx
}
movl %eax,(%edx)
movl %ebx,(%ecx)

movl -4(%ebp),%ebx
movl %ebp,%esp
popl %ebp Finish
ret

Autumn 2013 x86 Programming 14


University of Washington

Understanding Swap

higher addresses
void swap(int *xp, int *yp) •
{ • Stack
int t0 = *xp; • (in memory)
Offset
int t1 = *yp;
*xp = t1; 12 yp
*yp = t0;

lower addresses
8 xp
}
4 Rtn adr
0 Old %ebp %ebp
-4 Old %ebx
Register Value
%ecx yp movl 12(%ebp),%ecx # ecx = yp
%edx xp movl 8(%ebp),%edx # edx = xp
%eax t1 movl (%ecx),%eax # eax = *yp (t1)
%ebx t0 movl (%edx),%ebx # ebx = *xp (t0)
register <-> variable movl %eax,(%edx) # *xp = eax
mapping movl %ebx,(%ecx) # *yp = ebx
Autumn 2013 x86 Programming 15
University of Washington
Address
Understanding Swap 123 0x124

higher addresses
456 0x120
0x11c
%eax 0x118
%edx Offset
0x114
%ecx yp 12 0x120 0x110
xp 8 0x124

lower addresses
%ebx 0x10c
4 Rtn adr 0x108
%esi
%ebp 0 0x104
%edi -4
0x100
%esp
movl 12(%ebp),%ecx # ecx = yp
%ebp 0x104 movl 8(%ebp),%edx # edx = xp
movl (%ecx),%eax # eax = *yp (t1)
movl (%edx),%ebx # ebx = *xp (t0)
movl %eax,(%edx) # *xp = eax
movl %ebx,(%ecx) # *yp = ebx
Autumn 2013 x86 Programming 16
University of Washington
Address
Understanding Swap 123 0x124
456 0x120
0x11c
%eax 0x118
%edx Offset
0x114
%ecx 0x120 yp 12 0x120 0x110
xp 8 0x124 0x10c
%ebx
4 Rtn adr 0x108
%esi
%ebp 0 0x104
%edi -4
0x100
%esp
movl 12(%ebp),%ecx # ecx = yp
%ebp 0x104 movl 8(%ebp),%edx # edx = xp
movl (%ecx),%eax # eax = *yp (t1)
movl (%edx),%ebx # ebx = *xp (t0)
movl %eax,(%edx) # *xp = eax
movl %ebx,(%ecx) # *yp = ebx
Autumn 2013 x86 Programming 17
University of Washington
Address
Understanding Swap 123 0x124
456 0x120
0x11c
%eax 0x118
%edx 0x124 Offset
0x114
%ecx 0x120 yp 12 0x120 0x110
xp 8 0x124 0x10c
%ebx
4 Rtn adr 0x108
%esi
%ebp 0 0x104
%edi -4
0x100
%esp
movl 12(%ebp),%ecx # ecx = yp
%ebp 0x104 movl 8(%ebp),%edx # edx = xp
movl (%ecx),%eax # eax = *yp (t1)
movl (%edx),%ebx # ebx = *xp (t0)
movl %eax,(%edx) # *xp = eax
movl %ebx,(%ecx) # *yp = ebx
Autumn 2013 x86 Programming 18
University of Washington
Address
Understanding Swap 123 0x124
456 0x120
0x11c
%eax 456 0x118
%edx 0x124 Offset
0x114
%ecx 0x120 yp 12 0x120 0x110
xp 8 0x124 0x10c
%ebx
4 Rtn adr 0x108
%esi
%ebp 0 0x104
%edi -4
0x100
%esp
movl 12(%ebp),%ecx # ecx = yp
%ebp 0x104 movl 8(%ebp),%edx # edx = xp
movl (%ecx),%eax # eax = *yp (t1)
movl (%edx),%ebx # ebx = *xp (t0)
movl %eax,(%edx) # *xp = eax
movl %ebx,(%ecx) # *yp = ebx
Autumn 2013 x86 Programming 19
University of Washington
Address
Understanding Swap 123 0x124
456 0x120
0x11c
%eax 456 0x118
%edx 0x124 Offset
0x114
%ecx 0x120 yp 12 0x120 0x110
xp 8 0x124 0x10c
%ebx 123
4 Rtn adr 0x108
%esi
%ebp 0 0x104
%edi -4
0x100
%esp
movl 12(%ebp),%ecx # ecx = yp
%ebp 0x104 movl 8(%ebp),%edx # edx = xp
movl (%ecx),%eax # eax = *yp (t1)
movl (%edx),%ebx # ebx = *xp (t0)
movl %eax,(%edx) # *xp = eax
movl %ebx,(%ecx) # *yp = ebx
Autumn 2013 x86 Programming 20
University of Washington
Address
Understanding Swap 456 0x124
456 0x120
0x11c
%eax 456
456 0x118
%edx 0x124 Offset
0x114
%ecx 0x120 yp 12 0x120 0x110
xp 8 0x124 0x10c
%ebx 123
4 Rtn adr 0x108
%esi
%ebp 0 0x104
%edi -4
0x100
%esp
movl 12(%ebp),%ecx # ecx = yp
%ebp 0x104 movl 8(%ebp),%edx # edx = xp
movl (%ecx),%eax # eax = *yp (t1)
movl (%edx),%ebx # ebx = *xp (t0)
movl %eax,(%edx) # *xp = eax
movl %ebx,(%ecx) # *yp = ebx
Autumn 2013 x86 Programming 21
University of Washington
Address
Understanding Swap 456 0x124
123 0x120
0x11c
%eax 456 0x118
%edx 0x124 Offset
0x114
%ecx 0x120 yp 12 0x120 0x110
xp 8 0x124 0x10c
%ebx 123
4 Rtn adr 0x108
%esi
%ebp 0 0x104
%edi -4
0x100
%esp
movl 12(%ebp),%ecx # ecx = yp
%ebp 0x104 movl 8(%ebp),%edx # edx = xp
movl (%ecx),%eax # eax = *yp (t1)
movl (%edx),%ebx # ebx = *xp (t0)
movl %eax,(%edx) # *xp = eax
movl %ebx,(%ecx) # *yp = ebx
Autumn 2013 x86 Programming 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 2013 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:


§ movl → movq again, confusing historical terms…
not the current machine word size
§ 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 2013 x86 Programming 24


University of Washington

Swap Ints in 32-bit Mode


void swap(int *xp, int *yp) swap:
{ pushl %ebp
int t0 = *xp; movl %esp,%ebp Setup
int t1 = *yp; pushl %ebx
*xp = t1;
*yp = t0; movl 12(%ebp),%ecx
} movl 8(%ebp),%edx
movl (%ecx),%eax
Body
movl (%edx),%ebx
• movl %eax,(%edx)
• movl %ebx,(%ecx)

Offset
movl -4(%ebp),%ebx
12 yp movl %ebp,%esp
Finish
8 xp popl %ebp
4 Rtn adr ret
0 Old %ebp %ebp
-4 Old %ebx
Autumn 2013 x86 Programming 25
University of Washington

Swap Ints in 64-bit Mode


void swap(int *xp, int *yp) swap:
{ movl (%rdi), %edx
int t0 = *xp; movl (%rsi), %eax
int t1 = *yp; movl %eax, (%rdi)
*xp = t1; movl %edx, (%rsi)
*yp = t0; retq
}

¢ 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 2013 x86 Programming 26
University of Washington

Swap Long Ints in 64-bit Mode


void swap_l swap_l:
(long int *xp, long int *yp) movq (%rdi), %rdx
{ movq (%rsi), %rax
long int t0 = *xp; movq %rax, (%rdi)
long int t1 = *yp; movq %rdx, (%rsi)
*xp = t1; retq
*yp = t0;
}

¢ 64-bit data
§ Data held in registers %rax and %rdx
§ movq operation
§ “q” stands for quad-word

Autumn 2013 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) Mem[Reg[Rb] + S*Reg[Ri] + D]
§ D: Constant “displacement” value represented in 1, 2, or 4 bytes
§ Rb: Base register: Any of the 8/16 integer registers
§ Ri: Index register: Any, except for %esp or %rsp; %ebp unlikely
§ S: 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 2013 x86 Programming 28
University of Washington

Address Computation Examples


(Rb,Ri) Mem[Reg[Rb]+Reg[Ri]]
%edx 0xf000 D(,Ri,S) Mem[S*Reg[Ri]+D]
(Rb,Ri,S) Mem[Reg[Rb]+S*Reg[Ri]]
%ecx 0x100
D(Rb) 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

Autumn 2013 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
§ k = 1, 2, 4, or 8

Autumn 2013 x86 Programming 30


University of Washington

Some Arithmetic Operations


¢ Two Operand (Binary) Instructions:
Format Computation
addl Src,Dest 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 Src,Dest Dest = Dest | Src
¢ Watch out for argument order! (especially subl)
¢ No distinction between signed and unsigned int (why?)

§ except arithmetic vs. logical shift right


Autumn 2013 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 2013 x86 Programming 32


University of Washington

Using leal for Arithmetic Expressions (IA32)


arith:
pushl %ebp
Set
int arith movl %esp,%ebp
Up
(int x, int y, int z)
{ movl 8(%ebp),%eax
int t1 = x+y; movl 12(%ebp),%edx
int t2 = z+t1; leal (%edx,%eax),%ecx
int t3 = x+4; leal (%edx,%edx,2),%edx
int t4 = y * 48; sall $4,%edx Body
int t5 = t3 + t4; addl 16(%ebp),%ecx
int rval = t2 * t5; leal 4(%edx,%eax),%eax
return rval; imull %ecx,%eax
}
movl %ebp,%esp
popl %ebp Finish
ret

Autumn 2013 x86 Programming 33


University of Washington

Understanding arith (IA32)


int arith
(int x, int y, int z) •
• Stack
{
Offset •
int t1 = x+y;
int t2 = z+t1; 16 z
int t3 = x+4;
int t4 = y * 48; 12 y
int t5 = t3 + t4; 8 x
int rval = t2 * t5; 4 Rtn adr
return rval;
} 0 Old %ebp %ebp

movl 8(%ebp),%eax # eax = x


movl 12(%ebp),%edx # edx = y
leal (%edx,%eax),%ecx # ecx = x+y (t1)
leal (%edx,%edx,2),%edx # edx = y + 2*y = 3*y
sall $4,%edx # edx = 48*y (t4)
addl 16(%ebp),%ecx # ecx = z+t1 (t2)
leal 4(%edx,%eax),%eax # eax = 4+t4+x (t5)
imull %ecx,%eax # eax = t5*t2 (rval)
Autumn 2013 x86 Programming 34
University of Washington

Understanding arith (IA32)


int arith
(int x, int y, int z) •
• Stack
{
Offset •
int t1 = x+y;
int t2 = z+t1; 16 z
int t3 = x+4;
int t4 = y * 48; 12 y
int t5 = t3 + t4; 8 x
int rval = t2 * t5; 4 Rtn adr
return rval;
} 0 Old %ebp %ebp

movl 8(%ebp),%eax # eax = x


movl 12(%ebp),%edx # edx = y
leal (%edx,%eax),%ecx # ecx = x+y (t1)
leal (%edx,%edx,2),%edx # edx = y + 2*y = 3*y
sall $4,%edx # edx = 48*y (t4)
addl 16(%ebp),%ecx # ecx = z+t1 (t2)
leal 4(%edx,%eax),%eax # eax = 4+t4+x (t5)
imull %ecx,%eax # eax = t5*t2 (rval)
Autumn 2013 x86 Programming 35
University of Washington

Understanding arith (IA32)


int arith
(int x, int y, int z) •
• Stack
{
Offset •
int t1 = x+y;
int t2 = z+t1; 16 z
int t3 = x+4;
int t4 = y * 48; 12 y
int t5 = t3 + t4; 8 x
int rval = t2 * t5; 4 Rtn adr
return rval;
} 0 Old %ebp %ebp

movl 8(%ebp),%eax # eax = x


movl 12(%ebp),%edx # edx = y
leal (%edx,%eax),%ecx # ecx = x+y (t1)
leal (%edx,%edx,2),%edx # edx = y + 2*y = 3*y
sall $4,%edx # edx = 48*y (t4)
addl 16(%ebp),%ecx # ecx = z+t1 (t2)
leal 4(%edx,%eax),%eax # eax = 4+t4+x (t5)
imull %ecx,%eax # eax = t5*t2 (rval)
Autumn 2013 x86 Programming 36
University of Washington

Understanding arith (IA32)


int arith
(int x, int y, int z) •
• Stack
{
Offset •
int t1 = x+y;
int t2 = z+t1; 16 z
int t3 = x+4;
int t4 = y * 48; 12 y
int t5 = t3 + t4; 8 x
int rval = t2 * t5; 4 Rtn adr
return rval;
} 0 Old %ebp %ebp

movl 8(%ebp),%eax # eax = x


movl 12(%ebp),%edx # edx = y
leal (%edx,%eax),%ecx # ecx = x+y (t1)
leal (%edx,%edx,2),%edx # edx = y + 2*y = 3*y
sall $4,%edx # edx = 48*y (t4)
addl 16(%ebp),%ecx # ecx = z+t1 (t2)
leal 4(%edx,%eax),%eax # eax = 4+t4+x (t5)
imull %ecx,%eax # eax = t5*t2 (rval)
Autumn 2013 x86 Programming 37
University of Washington

Observations about arith


int arith § Instructions in different
(int x, int y, int z) order from C code
{
int t1 = x+y;
§ Some expressions require
int t2 = z+t1; multiple instructions
int t3 = x+4; § Some instructions cover
int t4 = y * 48; multiple expressions
int t5 = t3 + t4;
§ Get exact same code when
int rval = t2 * t5;
return rval;
compile:
} § (x+y+z)*(x+4+48*y)

movl 8(%ebp),%eax # eax = x


movl 12(%ebp),%edx # edx = y
leal (%edx,%eax),%ecx # ecx = x+y (t1)
leal (%edx,%edx,2),%edx # edx = y + 2*y = 3*y
sall $4,%edx # edx = 48*y (t4)
addl 16(%ebp),%ecx # ecx = z+t1 (t2)
leal 4(%edx,%eax),%eax # eax = 4+t4+x (t5)
imull %ecx,%eax # eax = t5*t2 (rval)
Autumn 2013 x86 Programming 38
University of Washington

Another Example (IA32)


logical:
int logical(int x, int y) pushl %ebp Set
{ movl %esp,%ebp Up
int t1 = x^y;
int t2 = t1 >> 17; movl 8(%ebp),%eax
int mask = (1<<13) - 7; xorl 12(%ebp),%eax
int rval = t2 & mask; sarl $17,%eax
return rval; andl $8185,%eax
} Body
movl %ebp,%esp
popl %ebp Finish
ret

movl 8(%ebp),%eax # eax = x Stack



Offset
xorl 12(%ebp),%eax # eax = x^y •

sarl $17,%eax # eax = t1>>17
12 y
andl $8185,%eax # eax = t2 & 8185
8 x
4 Rtn adr
0 Old %ebp %ebp
Autumn 2013 x86 Programming 39
University of Washington

Another Example (IA32)


logical:
int logical(int x, int y) pushl %ebp Set
{ movl %esp,%ebp Up
int t1 = x^y;
int t2 = t1 >> 17; movl 8(%ebp),%eax
int mask = (1<<13) - 7; xorl 12(%ebp),%eax
int rval = t2 & mask; sarl $17,%eax
return rval; andl $8185,%eax
} Body
movl %ebp,%esp
popl %ebp Finish
ret

movl 8(%ebp),%eax eax = x


xorl 12(%ebp),%eax eax = x^y (t1)
sarl $17,%eax eax = t1>>17 (t2)
andl $8185,%eax eax = t2 & 8185

Autumn 2013 x86 Programming 40


University of Washington

Another Example (IA32)


logical:
int logical(int x, int y) pushl %ebp Set
{ movl %esp,%ebp Up
int t1 = x^y;
int t2 = t1 >> 17; movl 8(%ebp),%eax
int mask = (1<<13) - 7; xorl 12(%ebp),%eax
int rval = t2 & mask; sarl $17,%eax
return rval; andl $8185,%eax
} Body
movl %ebp,%esp
popl %ebp Finish
ret

movl 8(%ebp),%eax eax = x


xorl 12(%ebp),%eax eax = x^y (t1)
sarl $17,%eax eax = t1>>17 (t2)
andl $8185,%eax eax = t2 & 8185

Autumn 2013 x86 Programming 41


University of Washington

Another Example (IA32)


logical:
int logical(int x, int y) pushl %ebp Set
{ movl %esp,%ebp Up
int t1 = x^y;
int t2 = t1 >> 17; movl 8(%ebp),%eax
int mask = (1<<13) - 7; xorl 12(%ebp),%eax
int rval = t2 & mask; sarl $17,%eax
return rval; andl $8185,%eax
} Body
movl %ebp,%esp
213 = 8192, 213 – 7 = 8185 popl %ebp Finish
…0010000000000000, …0001111111111001 ret

movl 8(%ebp),%eax eax = x


xorl 12(%ebp),%eax eax = x^y (t1)
sarl $17,%eax eax = t1>>17 (t2)
andl $8185,%eax eax = t2 & 8185

Autumn 2013
compiler optimization
x86 Programming 42
University of Washington

Topics: control flow


¢ Condition codes
¢ Conditional and unconditional branches
¢ Loops

Autumn 2013 x86 Programming 43


University of Washington

Conditionals and Control Flow


l A conditional branch is sufficient to implement most control
flow constructs offered in higher level languages
l if (condition) then {...} else {…}
l while (condition) {…}
l do {…} while (condition)
l for (initialization; condition; iterative) {...}

l Unconditional branches implement some related control flow


constructs
l break, continue

l In x86, we’ll refer to branches as “jumps” (either conditional


or unconditional)

Autumn 2013 x86 Programming 44


University of Washington

Jumping
¢ jX Instructions
§ Jump to different part of code depending on condition codes
§ Takes address as argument

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)
Autumn 2013 x86 Programming 45
University of Washington

Processor State (IA32, Partial)


¢ Information about %eax
currently executing %ecx
program
%edx General purpose
§ Temporary data registers
( %eax, …) %ebx
§ Location of runtime %esi
stack %edi
( %ebp,%esp)
%esp Current stack top
§ Location of current
code control point %ebp Current stack frame
( %eip )
§ Status of recent tests %eip Instruction pointer
( CF,ZF,SF,OF )
CF ZF SF OF Condition codes
Autumn 2013 x86 Programming 46
University of Washington

Condition Codes (Implicit Setting)


¢ Single-bit registers
CF Carry Flag (for unsigned) SF Sign Flag (for signed)
ZF Zero Flag 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 2013 x86 Programming 47


University of Washington

Condition Codes (Explicit Setting: Compare)


¢ Single-bit registers
CF Carry Flag (for unsigned) SF Sign Flag (for signed)
ZF Zero Flag OF Overflow Flag (for signed)
¢ 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) || (a<0 && b>0 && (a-b)>0)

Autumn 2013 x86 Programming 48


University of Washington

Condition Codes (Explicit Setting: Test)


¢ Single-bit registers
CF Carry Flag (for unsigned) SF Sign Flag (for signed)
ZF Zero Flag 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


§ Sets SF and ZF, check if eax is +,0,-

Autumn 2013 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 Condition Description


sete ZF Equal / Zero
setne ~ZF Not Equal / Not Zero
sets SF Negative
setns ~SF Nonnegative
setg ~(SF^OF)&~ZF Greater (Signed)
setge ~(SF^OF) Greater or Equal (Signed)
setl (SF^OF) Less (Signed)
setle (SF^OF)|ZF Less or Equal (Signed)
seta ~CF&~ZF Above (unsigned)
setb CF Below (unsigned)

Autumn 2013 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 %ebx %bh %bl
§ Typically use movzbl to finish job %esi
int gt (int x, int y) %edi
{
return x > y; %esp
} %ebp

Body: y at 12(%ebp), x at 8(%ebp)


movl 12(%ebp),%eax # eax = y
cmpl %eax,8(%ebp) What does
# Compare x :each
y of
setg %al #these
al = instructions
x > y do?
movzbl %al,%eax # Zero rest of %eax
Autumn 2013 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 %ebx %bh %bl
§ Typically use movzbl to finish job %esi
int gt (int x, int y) %edi
{
return x > y; %esp
} %ebp

Body: y at 12(%ebp), x at 8(%ebp)


movl 12(%ebp),%eax # eax = y
cmpl %eax,8(%ebp) # Compare x and y (x – y)
setg %al # al = x > y
movzbl %al,%eax # Zero rest of %eax
Autumn 2013 x86 Programming 52
University of Washington

Jumping
¢ jX Instructions
§ Jump to different part of code depending on condition codes
§ Takes address as argument

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)
Autumn 2013 x86 Programming 53
University of Washington

Conditional Branch Example


absdiff:
int absdiff(int x, int y)
pushl %ebp
{ Setup
movl %esp, %ebp
int result;
movl 8(%ebp), %edx
if (x > y) {
movl 12(%ebp), %eax
result = x-y;
cmpl %eax, %edx
} else { Body1
jle .L7
result = y-x;
subl %eax, %edx
}
movl %edx, %eax
return result;
.L8:
}
leave Finish
ret
.L7:
subl %edx, %eax Body2
jmp .L8

Autumn 2013 x86 Programming 54


University of Washington

Conditional Branch Example (Cont.)


int goto_ad(int x, int y)
int absdiff(int x, int y) {
{ int result;
int result; if (x <= y) goto Else;
if (x > y) { result = x-y;
result = x-y; Exit:
} else { return result;
result = y-x; Else:
} result = y-x;
return result; goto Exit;
} }

¢ 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) absdiff:
{ pushl %ebp
int result; movl %esp, %ebp
if (x <= y) goto Else; movl 8(%ebp), %edx
result = x-y; movl 12(%ebp), %eax
Exit: cmpl %eax, %edx
return result; jle .L7
Else: subl %eax, %edx
result = y-x; movl %edx, %eax
goto Exit; .L8:
} leave
ret
.L7:
subl %edx, %eax
int x %edx jmp .L8
int y %eax

Autumn 2013 x86 Programming 56


University of Washington

Conditional Branch Example (Cont.)


int goto_ad(int x, int y) absdiff:
{ pushl %ebp
int result; movl %esp, %ebp
if (x <= y) goto Else; movl 8(%ebp), %edx
result = x-y; movl 12(%ebp), %eax
Exit: cmpl %eax, %edx
return result; jle .L7
Else: subl %eax, %edx
result = y-x; movl %edx, %eax
goto Exit; .L8:
} leave
ret
.L7:
subl %edx, %eax
int x %edx jmp .L8
int y %eax

Autumn 2013 x86 Programming 57


University of Washington

Conditional Branch Example (Cont.)


int goto_ad(int x, int y) absdiff:
{ pushl %ebp
int result; movl %esp, %ebp
if (x <= y) goto Else; movl 8(%ebp), %edx
result = x-y; movl 12(%ebp), %eax
Exit: cmpl %eax, %edx
return result; jle .L7
Else: subl %eax, %edx
result = y-x; movl %edx, %eax
goto Exit; .L8:
} leave
ret
.L7:
subl %edx, %eax
int x %edx jmp .L8
int y %eax

Autumn 2013 x86 Programming 58


University of Washington

Conditional Branch Example (Cont.)


int goto_ad(int x, int y) absdiff:
{ pushl %ebp
int result; movl %esp, %ebp
if (x <= y) goto Else; movl 8(%ebp), %edx
result = x-y; movl 12(%ebp), %eax
Exit: cmpl %eax, %edx
return result; jle .L7
Else: subl %eax, %edx
result = y-x; movl %edx, %eax
goto Exit; .L8:
} leave
ret
.L7:
subl %edx, %eax
int x %edx jmp .L8
int y %eax

Autumn 2013 x86 Programming 59


University of Washington

Conditional Branch Example (Cont.)


int goto_ad(int x, int y) absdiff:
{ pushl %ebp
int result; movl %esp, %ebp
if (x <= y) goto Else; movl 8(%ebp), %edx
result = x-y; movl 12(%ebp), %eax
Exit: cmpl %eax, %edx
return result; jle .L7
Else: subl %eax, %edx
result = y-x; movl %edx, %eax
goto Exit; .L8:
} leave
ret
.L7:
subl %edx, %eax
int x %edx jmp .L8
int y %eax

Autumn 2013 x86 Programming 60


University of Washington

General Conditional Expression Translation


C Code if (Test)
val = Then-Expr;
val = Test ? Then-Expr : Else-Expr; else
val = Else-Expr;
result = x>y ? x-y : y-x;

§ Test is expression returning integer


Goto Version = 0 interpreted as false
nt = !Test; ¹0 interpreted as true
if (nt) goto Else; § Create separate code regions for
val = Then-Expr;
then & else expressions
Done:
. . . § Execute appropriate one
Else:
val = Else-Expr;
§ How might you make this more
goto Done;
efficient?

Autumn 2013 x86 Programming 61


University of Washington

Conditionals: x86-64
int absdiff( absdiff: # x in %edi, y in %esi
int x, int y) movl %edi, %eax # eax = x
{ movl %esi, %edx # edx = y
int result; subl %esi, %eax # eax = x-y
if (x > y) { subl %edi, %edx # edx = y-x
result = x-y; cmpl %esi, %edi # x:y
} else { cmovle %edx, %eax # eax=edx if <=
result = y-x; ret
}
return result;
}

¢ Conditional move instruction


§ cmovC src, dest
§ Move value from src to dest if condition C holds
§ Why is this good?

Autumn 2013 x86 Programming 62


University of Washington

Conditionals: x86-64
int absdiff( absdiff: # x in %edi, y in %esi
int x, int y) movl %edi, %eax # eax = x
{ movl %esi, %edx # edx = y
int result; subl %esi, %eax # eax = x-y
if (x > y) { subl %edi, %edx # edx = y-x
result = x-y; cmpl %esi, %edi # x:y
} else { cmovle %edx, %eax # eax=edx if <=
result = y-x; ret
}
return result;
}

¢ Conditional move instruction


§ 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
Autumn 2013 x86 Programming 63
University of Washington

PC Relative Addressing

0x100 cmp r2, r3 0x1000


0x102 je 0x70 0x1002
0x104 … 0x1004
… … …
0x172 add r3, r4 0x1072

l PC relative branches are relocatable


l Absolute branches are not

Autumn 2013 x86 Programming 64


University of Washington

Compiling Loops
C/Java code: Machine code:
while ( sum != 0 ) { loopTop: cmpl $0, %eax
<loop body> 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

65
University of Washington

“Do-While” Loop Example


C Code Goto Version
int fact_do(int x) int fact_goto(int x)
{ {
int result = 1; int result = 1;
do { loop:
result *= x; result *= x;
x = x-1; x = x-1;
} while (x > 1); if (x > 1) goto loop;
return result; return result;
} }

¢ Use backward branch to continue looping


¢ Only take branch when “while” condition holds

66
University of Washington

“Do-While” Loop Compilation Registers:


%edx x
Goto Version Assembly %eax result
int fact_goto:
fact_goto(int x) pushl %ebp # Setup
{ movl %esp,%ebp # Setup
int result = 1; movl $1,%eax # eax = 1
movl 8(%ebp),%edx # edx = x

loop: .L11:
result *= x; imull %edx,%eax # result *= x
x = x-1; decl %edx # Translation?
x--
if (x > 1) cmpl $1,%edx # Compare x : 1
goto loop; jg .L11 # if > goto loop

return result; movl %ebp,%esp # Finish


} popl %ebp # Finish
ret # Finish

Autumn 2013 x86 Programming 67


University of Washington

“Do-While” Loop Compilation Registers:


%edx x
Goto Version Assembly %eax result
int fact_goto:
fact_goto(int x) pushl %ebp # Setup
{ movl %esp,%ebp # Setup
int result = 1; movl $1,%eax # eax = 1
movl 8(%ebp),%edx # edx = x

loop: .L11:
result *= x; imull %edx,%eax # result *= x
x = x-1; decl %edx # x--
if (x > 1) cmpl $1,%edx # Compare x : 1
goto loop; jg .L11 # if > goto loop

return result; movl %ebp,%esp # Finish


} popl %ebp # Finish
ret # Finish

Autumn 2013 x86 Programming 68


University of Washington

General “Do-While” Translation


C Code Goto Version
do loop:
Body Body
while (Test); if (Test)
goto loop

¢ Body: {
Statement1;
Statement2;

Statementn;
}

¢ Test returns integer


= 0 interpreted as false
¹ 0 interpreted as true
69
University of Washington

“While” Loop Translation


C Code Goto Version
int fact_while(int x) int fact_while_goto(int x)
{ {
int result = 1; int result = 1;
while (x > 1) { goto middle;
result *= x; loop:
x = x-1; result *= x;
} x = x-1;
return result; 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

70
University of Washington

“While” Loop Example


int fact_while(int x) # x in %edx, result in %eax
{ jmp .L34 # goto Middle
int result = 1; .L35: # Loop:
while (x > 1) { imull %edx, %eax # result *= x
result *= x; decl %edx # x--
x--; .L34: # Middle:
}; cmpl $1, %edx # x:1
return result; jg .L35 # if >, goto
} # Loop

Autumn 2013 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
}
return result; 0 ... 0 1 1 0 1 = 13
} 12^31 * ... * 116 * x8 * x4 * 12 * x1 = x13
1 = x0 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
Example
zi = 1 when pi = 0
n–1 times 310 = 32 * 38
zi = x when pi = 1
§ Complexity O(log p) = O(sizeof(p)) = 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 1 3 10=10102
2 1 9 5= 1012
3 9 81 2= 102
4 9 6561 1= 12
5 59049 43046721 02
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 Test Update Body


result = 1 p != 0 p = p >> 1 {
if (p & 0x1)
result *= x;
x = x*x;
}
74
University of Washington

“For”® “While”
For Version
for (Initialize; Test; Update )
Body

Goto Version
Initialize;
goto middle;
loop:
While Version Body
Initialize; Update ;
while (Test ) { middle:
Body if (Test)
Update ; goto loop;
} done:

75
University of Washington

For-Loop: Compilation
for (result = 1; p != 0; p = p>>1)
For Version {
for (Initialize; Test; Update ) if (p & 0x1)
result *= x;
Body x = x*x;
}

Goto Version
result = 1;
Initialize; goto middle;
goto middle; loop:
loop: if (p & 0x1)
Body result *= x;
Update ; x = x*x;
middle: p = p >> 1;
if (Test) middle:
if (p != 0)
goto loop;
goto loop;
done: done:
76
University of Washington

long switch_eg (unsigned


long x, long y, long z) Switch Statement
{
long w = 1; Example
switch(x) {
case 1:
w = y*z; ¢ Multiple case labels
break;
case 2: § Here: 5, 6
w = y/z; ¢ Fall through cases
/* Fall Through */
case 3: § Here: 2
w += z; ¢ Missing cases
break;
case 5:
§ Here: 4
case 6:
w -= z;
break;
default: ¢ Lots to manage, we
w = 2; need a jump table
}
return w;
}
77
University of Washington

Jump Table Structure


Switch Form Jump Table Jump Targets
switch(x) { JTab: Targ0 Targ0: Code Block
case val_0: 0
Targ1
Block 0
case val_1: Targ2
Targ1: Code Block
Block 1 •
• • • 1

case val_n-1: •
Block n–1 Targ2: Code Block
Targn-1
} 2


Approximate Translation •
target = JTab[x]; •
goto target;
Targn-1: Code Block
n–1
78
University of Washington

Jump Table Structure


C code: Memory
switch(x) {
case 1: <some code>
break;
case 2: <some code>
case 3: <some code>
break; Code
case 5: Blocks
case 6: <some code>
break;
default: <some code>
}

We can use the jump table when x <= 6: 0


1
if (x <= 6) Jump 2
target = JTab[x];
goto target; Table 3
4
else 5
goto default; 6

79
University of Washington

declaring data, not instructions Jump Table (IA32)


4-byte memory alignment
Jump table
.section .rodata switch(x) {
.align 4 case 1: // .L56
.L62: w = y*z;
.long .L61 # x = 0 break;
.long .L56 # x = 1 case 2: // .L57
.long .L57 # x = 2 w = y/z;
.long .L58 # x = 3 /* Fall Through */
.long .L61 # x = 4 case 3: // .L58
.long .L60 # x = 5 w += z;
.long .L60 # x = 6 break;
case 5:
case 6: // .L60
“long” as in movl: 4 bytes w -= z;
would be .quad in x86-64 break;
default: // .L61
w = 2;
}
80
University of Washington

Switch Statement Example (IA32)


long switch_eg(unsigned long x, long y,
long z)
{
long w = 1;
switch(x) {
. . .
} Jump table
return w; .section .rodata
.align 4
} .L62:
Setup: switch_eg: .long .L61 # x = 0
.long .L56 # x = 1
pushl %ebp # Setup .long .L57 # x = 2
movl %esp, %ebp # Setup .long .L58 # x = 3
pushl %ebx # Setup .long .L61 # x = 4
movl $1, %ebx # w = 1 .long .L60 # x = 5
.long .L60 # x = 6
movl 8(%ebp), %edx # edx = x
movl 16(%ebp), %ecx # ecx = z
cmpl $6, %edx # x:6
ja .L61 # if Translation?
> goto default
jmp *.L62(,%edx,4) # goto JTab[x]
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
return w; .section .rodata
.align 4
} .L62:
Setup: switch_eg: .long .L61 # x = 0
pushl %ebp # Setup .long .L56 # x = 1
.long .L57 # x = 2
movl %esp, %ebp # Setup .long .L58 # x = 3
pushl %ebx # Setup .long .L61 # x = 4
movl $1, %ebx # w = 1 .long .L60 # x = 5
jump above .long .L60 # x = 6
(like jg, but movl 8(%ebp), %edx # edx = x
unsigned) movl 16(%ebp), %ecx # ecx = z
cmpl $6, %edx # x:6
Indirect ja .L61 # if > 6 goto
jump default
jmp *.L62(,%edx,4) # goto JTab[x] 82
University of Washington

Assembly Setup Explanation (IA32)


¢ Table Structure
§ Each target requires 4 bytes Jump table
§ Base address at .L62 .section .rodata
.align 4
.L62:
¢ Jumping: different address modes .long .L61 # x = 0
.long .L56 # x = 1
for target .long .L57 # x = 2
Direct: jmp .L61 .long .L58 # x = 3
§ Jump target is denoted by label .L61 .long .L61 # x = 4
.long .L60 # x = 5
.long .L60 # x = 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)
83
University of Washington

Code Blocks (Partial)


switch(x) { .L61: // Default case
. . . movl $2, %ebx # w = 2
case 2: // .L57 jmp .L63
w = y/z; .L57: // Case 2:
/* Fall Through */ movl 12(%ebp), %eax # y
case 3: // .L58 cltd # Div prep
w += z; idivl %ecx # y/z
break; movl %eax, %ebx # w = y/z
. . . # Fall through – no jmp
default: // .L61 .L58: // Case 3:
w = 2; addl %ecx, %ebx # w+= z
} jmp .L63
return w; ...
.L63
movl %ebx, %eax # return w
popl %ebx
leave
ret

84
University of Washington

Code Blocks (Rest)


switch(x) { .L60: // Cases 5&6:
case 1: // .L56 subl %ecx, %ebx # w –= z
w = y*z; jmp .L63
break; .L56: // Case 1:
. . . movl 12(%ebp), %ebx # w = y
case 5: imull %ecx, %ebx # w*= z
case 6: // .L60 jmp .L63
w -= z;
break;
. . . ...
} .L63
return w; movl %ebx, %eax # return w
popl %ebx
leave
ret

85
University of Washington

Code Blocks (Partial, return inlined)


switch(x) { .L61: // Default case
. . . movl $2, %ebx # w = 2
case 2: // .L57 movl %ebx, %eax # Return w
w = y/z; popl %ebx
/* Fall Through */ leave
case 3: // .L58 ret
w += z; .L57: // Case 2:
break; movl 12(%ebp), %eax # y
. . . cltd # Div prep
default: // .L61 idivl %ecx # y/z
w = 2; movl %eax, %ebx # w = y/z
} # Fall through – no jmp
.L58: // Case 3:
The compiler might choose to pull the addl %ecx, %ebx # w+= z
return statement in to each relevant movl %ebx, %eax # Return w
case rather than jumping out to it. popl %ebx
leave
ret

86
University of Washington

Code Blocks (Rest, return inlined)


switch(x) { .L60: // Cases 5&6:
case 1: // .L56 subl %ecx, %ebx # w –= z
w = y*z; movl %ebx, %eax # Return w
break; popl %ebx
. . . leave
case 5: ret
case 6: // .L60 .L56: // Case 1:
w -= z; movl 12(%ebp), %ebx # w = y
break; imull %ecx, %ebx # w*= z
. . . movl %ebx, %eax # Return w
} popl %ebx
leave
ret
The compiler might choose to pull the
return statement in to each relevant
case rather than jumping out to it.

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 ja 8048630
08048624: ff 24 95 dc 88 04 08 jmp *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
89
University of Washington

Disassembled Targets
8048630: bb 02 00 00 00 mov $0x2,%ebx
8048635: 89 d8 mov %ebx,%eax
8048637: 5b pop %ebx
8048638: c9 leave
8048639: c3 ret
804863a: 8b 45 0c mov 0xc(%ebp),%eax
804863d: 99 cltd
804863e: f7 f9 idiv %ecx
8048640: 89 c3 mov %eax,%ebx
8048642: 01 cb add %ecx,%ebx
8048644: 89 d8 mov %ebx,%eax
8048646: 5b pop %ebx
8048647: c9 leave
8048648: c3 ret
8048649: 29 cb sub %ecx,%ebx
804864b: 89 d8 mov %ebx,%eax
804864d: 5b pop %ebx
804864e: c9 leave
804864f: c3 ret
8048650: 8b 5d 0c mov 0xc(%ebp),%ebx
8048653: 0f af d9 imul %ecx,%ebx
8048656: 89 d8 mov %ebx,%eax
8048658: 5b pop %ebx
8048659: c9 leave
804865a: c3 ret
90
University of Washington

Matching Disassembled Targets


8048630: bb 02 00 00 00 mov
8048635: 89 d8 mov
8048637: 5b pop
8048638: c9 leave
8048639: c3 ret
804863a: 8b 45 0c mov
804863d: 99 cltd
0x08048630 804863e: f7 f9 idiv
0x08048650 8048640: 89 c3 mov
8048642: 01 cb add
0x0804863a 8048644: 89 d8 mov
8048646: 5b pop
0x08048642 8048647: c9 leave
8048648: c3 ret
0x08048630 8048649: 29 cb sub
804864b: 89 d8 mov
0x08048649 804864d: 5b pop
0x08048649 804864e: c9 leave
804864f: c3 ret
8048650: 8b 5d 0c mov
8048653: 0f af d9 imul
8048656: 89 d8 mov
8048658: 5b pop
8048659: c9 leave
804865a: c3 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
92
University of Washington

Quick Review
¢ x86-64 vs. IA32
%rax %eax %r8 %r8d
§ Integer registers: 16 x 64-bit vs. 8 x 32-bit %rbx %edx %r9 %r9d
§ movq, addq, … vs. movl, addl, … %rcx %ecx %r10 %r10d
%rdx %ebx %r11 %r11d
§movq -> “move quad word” or 4*16-bits %rsi %esi %r12 %r12d

§ x86-64: better support for passing %rdi %edi %r13 %r13d

function arguments in registers %rsp


%rbp
%esp
%ebp
%r14
%r15
%r14d
%r15d

¢ Complete memory addressing mode


§ (%eax), 17(%eax), 2(%ebx, %ecx, 8), …
¢ Immediate (constant), Register, and Memory Operands
§ subl %eax, %ecx # ecx = ecx + eax
§ sall $4,%edx # edx = edx << 4
§ addl 16(%ebp),%ecx # ecx = ecx + Mem[16+ebp]
§ imull %ecx,%eax # eax = eax * 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 # eax = 4 + edx + eax

94
University of Washington

Quick Review
Do-While loop Goto Version
¢ C Code
loop:
do
Body
Body
if (Test)
while (Test);
goto loop

¢ While-Do loop
Goto Version
Do-While Version
if (!Test)
if (!Test) goto done;
While version goto done; loop:
while (Test) do Body
Body Body if (Test)
while(Test); goto loop;
done: done:

goto middle;
loop:
Body
or middle:
if (Test)
goto loop;
95
University of Washington

Control Flow Summary


¢ C Control ¢ Standard Techniques
§ if-then-else § Loops converted to do-while form
§ do-while § Large switch statements use jump tables
§ while, for § Sparse switch statements may use
§ switch decision trees (see textbook)

¢ Assembler Control ¢ Conditions in CISC


§ Conditional jump § CISC machines generally have condition
§ Conditional move code registers
§ Indirect jump
§ Compiler
§ Must generate assembly code
to implement more complex control

96

You might also like