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
© Copyright 2024