A job ad at a game programming company

Slides:



Advertisements
Similar presentations
Machine Programming – Procedures and IA32 Stack CENG334: Introduction to Operating Systems Instructor: Erol Sahin Acknowledgement: Most of the slides are.
Advertisements

University of Washington Last Time For loops  for loop → while loop → do-while loop → goto version  for loop → while loop → goto “jump to middle” version.
Machine-Level Programming I: Introduction Topics Assembly Programmer’s Execution Model Accessing Information Registers Memory Arithmetic operations CS.
Machine-Level Programming III: Procedures Apr. 17, 2006 Topics IA32 stack discipline Register saving conventions Creating pointers to local variables CS213.
Machine-Level Programming III: Procedures Sept. 17, 2007 IA32 stack discipline Register saving conventions Creating pointers to local variablesx86-64 Argument.
– 1 – , F’02 ICS05 Instructor: Peter A. Dinda TA: Bin Lin Recitation 4.
Machine-Level Programming I: Introduction Apr. 10, 2006 Topics Assembly Programmer’s Execution Model Accessing Information Registers Memory Arithmetic.
Machine-Level Programming III: Procedures Jan 30, 2003
Machine-Level Programming III: Procedures Sept. 15, 2006 IA32 stack discipline Register saving conventions Creating pointers to local variablesx86-64 Argument.
Stack Activation Records Topics IA32 stack discipline Register saving conventions Creating pointers to local variables February 6, 2003 CSCE 212H Computer.
Recitation 2: Assembly & gdb Andrew Faulring Section A 16 September 2002.
Y86 Processor State Program Registers
Processor Architecture: The Y86 Instruction Set Architecture
Linked Lists in MIPS Let’s see how singly linked lists are implemented in MIPS on MP2, we have a special type of doubly linked list Each node consists.
1 Carnegie Mellon Stacks : Introduction to Computer Systems Recitation 5: September 24, 2012 Joon-Sup Han Section F.
Ithaca College Machine-Level Programming IV: IA32 Procedures Comp 21000: Introduction to Computer Systems & Assembly Lang Spring 2013 * Modified slides.
64-Bit Architectures Topics 64-bit data New registers and instructions Calling conventions CS 105 “Tour of the Black Holes of Computing!”
Machine-Level Programming 1 Introduction Topics Assembly Programmer’s Execution Model Accessing Information Registers Memory Arithmetic operations.
Machine-Level Programming III: Switch Statements and IA32 Procedures Seoul National University.
University of Washington Today More on procedures, stack etc. Lab 2 due today!  We hope it was fun! What is a stack?  And how about a stack frame? 1.
Fabián E. Bustamante, Spring 2007 Machine-Level Programming III - Procedures Today IA32 stack discipline Register saving conventions Creating pointers.
Recitation 2 – 2/11/02 Outline Stacks & Procedures Homogenous Data –Arrays –Nested Arrays Mengzhi Wang Office Hours: Thursday.
Machine-Level Programming: X86-64 Topics Registers Stack Function Calls Local Storage X86-64.ppt CS 105 Tour of Black Holes of Computing.
Recitation 2: Outline Assembly programming Using gdb L2 practice stuff Minglong Shao Office hours: Thursdays 5-6PM Wean Hall.
Machine-Level Programming 1 Introduction Topics Assembly Programmer’s Execution Model Accessing Information Registers Memory Arithmetic operations.
Machine-level Programming III: Procedures Topics –IA32 stack discipline –Register saving conventions –Creating pointers to local variables.
University of Washington x86 Programming I The Hardware/Software Interface CSE351 Winter 2013.
Carnegie Mellon 1 Machine-Level Programming I: Basics Lecture, Feb. 21, 2013 These slides are from website which accompanies the.
Compiler Construction Code Generation Activation Records
1 Assembly Language: Function Calls Jennifer Rexford.
IA32 Stack –Region of memory managed with stack discipline –Grows toward lower addresses –Register %esp indicates lowest stack address address of top element.
X86 Assembly - Data.
Reading Condition Codes (Cont.)
Machine-Level Programming 2 Control Flow
Machine-Level Programming I:
Machine-Level Programming I:
C function call conventions and the stack
IA32 Processors Evolutionary Design
ISA's, Compilers, and Assembly
Recitation 2 – 2/11/02 Outline Stacks & Procedures
Aaron Miller David Cohen Spring 2011
Recitation 2 – 2/4/01 Outline Machine Model
Machine-Level Programming II: Arithmetic & Control
Machine-Level Programming 1 Introduction
Computer Architecture adapted by Jason Fritts then by David Ferry
asum.ys A Y86 Programming Example
Machine-Level Programming III: Switch Statements and IA32 Procedures
Y86 Processor State Program Registers
Instructors: Majd Sakr and Khaled Harras
Machine-Level Programming 4 Procedures
Instructor: David Ferry
Roadmap C: Java: Assembly language: OS: Machine code: Computer system:
Machine-Level Programming 2 Control Flow
Assembly Language Programming II: C Compiler Calling Sequences
Machine-Level Programming 2 Control Flow
Machine-Level Programming III: Procedures Sept 18, 2001
MIPS Procedure Calls CSE 378 – Section 3.
Machine-Level Programming 2 Control Flow
Machine-Level Programming I: Introduction Feb. 1, 2000
Machine-Level Programming I: Introduction
X86 Assembly - Data.
Machine Level Representation of Programs (IV)
Machine-Level Programming: Introduction
Machine-Level Representation of Programs (x86-64)
Machine-Level Programming I:
Machine-Level Programming I:
“Way easier than when we were students”
Machine-Level Programming I: Introduction Sept. 10, 2002
Presentation transcript:

A job ad at a game programming company February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly Assembly Programming Why do they take assembly programming “very seriously”? February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly Assembly Programming Why do they take assembly programming “very seriously”? Compilers don’t always generate the best possible code Especially for computationally-intensive code Like graphics, signal processing, physical simulation, etc. An assembly programmer can use application/domain knowledge Knowledge that some variables won’t change during computation Knowledge of what precision is required Knowledge that operations can be reordered/pipelined There is often not a good mapping from C to some ISA features Good programmers are more creative than compilers (holistic) Generally only works for “small” pieces of code Humans are easily overwhelmed (our caches thrash) February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly RISC vs. CISC SPARC, PowerPC, and ARM are all very similar to MIPS, so you should have no problem learning them on your own, if needed. Today, we’ll look at x86, which has some significant differences of which you should be aware. February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly RISC vs. CISC SPARC, PowerPC, and ARM are all very similar to MIPS, so you should have no problem learning them on your own, if needed. Today, we’ll look at x86, which has some significant differences of which you should be aware. February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly Comparing x86 and MIPS Much more is similar than different. Both use registers and have byte-addressable memories Same basic types of instructions (arithmetic, branches, memory) Differences Fewer (8) registers, different names Two register formats (x86) vs. three (MIPS) Greater reliance on the stack, which is part of the architecture x86 arithmetic supports (register + memory) -> (register) format x86 has additional addressing modes x86 branches use condition codes different instruction names and variable-length encodings I’ll walk you through the tricky parts February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly x86 Registers Few, and special purpose 8 integer registers two generally used only for stack Not all instructions can use any register Little room for temporary values x86 uses “two-address code” op x, y # y = y op x Rarely can the compiler fit everything in registers Stack is used much more heavily %eax %edx %ecx %ebx %esi %edi %esp %ebp February 27, 2018 ISA's, Compilers, and Assembly

x86 Stack is Architected! (Not just a convention) The esp register _is_ the stack pointer x86 includes explicit push and pop instructions push %eax # M[ESP - 4] = EAX; ESP = ESP - 4 pop %ecx # ESP = ESP + 4; ECX = M[ESP - 4] It can be seen that, like MIPS, the x86 stack grows down call instructions (x86 equivalent to jal) push the return address on stack call label # push next EIP; EIP = label (EIP = instruction pointer) Stack also used for passing arguments, pushed in reverse order Because esp is constantly changing, use ebp as stack “base pointer” Keeps track of the top of the current stack frame Same as the bottom of the previous stack frame Doesn’t move, so can be used throughout the function February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly A Simple Example int main() { int one = 123, two = 456; swap(&one, &two); ... } void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly A Simple Example 0x124 int main() { int one = 123, two = 456; swap(&one, &two); ... } 0x120 %ebp,esp 0x11c 0x118 0x114 … subl $8, %esp movl $123, -8(%ebp) movl $456, -4(%ebp) leal -4(%ebp), %eax pushl %eax leal -8(%ebp), %eax pushl %eax call swap ... 0x110 0x10c Key: sub = subtract l = long (32-bit operation) $8 = literal 8 %esp = stack pointer register ESP = ESP - 8 February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly A Simple Example 0x124 int main() { int one = 123, two = 456; swap(&one, &two); ... } 0x120 %ebp 0x11c 0x118 %esp 0x114 … subl $8, %esp movl $123, -8(%ebp) movl $456, -4(%ebp) leal -4(%ebp), %eax pushl %eax leal -8(%ebp), %eax pushl %eax call swap ... 0x110 0x10c Key: mov = data movement l = long (32-bit operation) $123 = literal 123 -8(%ebp) = base + offset addressing M[EBP - 8] = 123 February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly A Simple Example 0x124 int main() { int one = 123, two = 456; swap(&one, &two); ... } 0x120 %ebp 0x11c 0x118 123 %esp 0x114 … subl $8, %esp movl $123, -8(%ebp) movl $456, -4(%ebp) leal -4(%ebp), %eax pushl %eax leal -8(%ebp), %eax pushl %eax call swap ... 0x110 0x10c February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly A Simple Example 0x124 int main() { int one = 123, two = 456; swap(&one, &two); ... } 0x120 %ebp 0x11c 456 0x118 123 %esp 0x114 … subl $8, %esp movl $123, -8(%ebp) movl $456, -4(%ebp) leal -4(%ebp), %eax pushl %eax leal -8(%ebp), %eax pushl %eax call swap ... 0x110 0x10c Key: (push arguments in reverse order) lea = load effective address (don’t do a load, just compute addr.) EAX = EBP - 4 M[ESP - 4] = EAX ESP = ESP - 4 February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly A Simple Example 0x124 int main() { int one = 123, two = 456; swap(&one, &two); ... } 0x120 %ebp 0x11c 456 0x118 123 0x114 … subl $8, %esp movl $123, -8(%ebp) movl $456, -4(%ebp) leal -4(%ebp), %eax pushl %eax leal -8(%ebp), %eax pushl %eax call swap ... %esp 0x118 0x110 0x10c February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly A Simple Example 0x124 int main() { int one = 123, two = 456; swap(&one, &two); ... } 0x120 %ebp 0x11c 456 0x118 123 0x114 … subl $8, %esp movl $123, -8(%ebp) movl $456, -4(%ebp) leal -4(%ebp), %eax pushl %eax leal -8(%ebp), %eax pushl %eax call swap ... 0x118 0x110 0x114 %esp 0x10c 0x108 0x104 Key: M[ESP - 4] = next_EIP ESP = ESP - 4 EIP = swap February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly A Simple Example 0x124 int main() { int one = 123, two = 456; swap(&one, &two); ... } 0x120 %ebp 0x11c 456 0x118 123 0x114 … subl $8, %esp movl $123, -8(%ebp) movl $456, -4(%ebp) leal -4(%ebp), %eax pushl %eax leal -8(%ebp), %eax pushl %eax call swap ... 0x118 0x110 0x114 0x10c RTN ADR %esp 0x108 0x104 February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly The “swap” function swap: pushl %ebp movl %esp,%ebp pushl %ebx movl 12(%ebp),%ecx movl 8(%ebp),%edx movl (%ecx),%eax movl (%edx),%ebx movl %eax,(%edx) movl %ebx,(%ecx) movl -4(%ebp),%ebx movl %ebp,%esp popl %ebp ret Set Up void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } Body Finish February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly Function Prologue void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } 0x124 0x120 %ebp 0x11c 456 0x118 123 0x114 0x118 swap: pushl %ebp movl %esp,%ebp pushl %ebx 0x110 0x114 0x10c RTN ADR %esp 0x108 0x104 Save the old base pointer on the stack February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly Function Prologue void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } 0x124 0x120 %ebp 0x11c 456 0x118 123 0x114 0x118 swap: pushl %ebp movl %esp,%ebp pushl %ebx 0x110 0x114 0x10c RTN ADR 0x108 %esp 0x11c 0x104 Old stack pointer becomes new base pointer. February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly Function Prologue void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } 0x124 0x120 0x11c 456 0x118 123 0x114 0x118 swap: pushl %ebp movl %esp,%ebp pushl %ebx 0x110 0x114 0x10c RTN ADR 0x108 %ebp,esp 0x11c 0x104 0x100 Save register ebx, which is callee saved. February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly Function Prologue void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } 0x124 0x120 0x11c 456 0x118 123 0x114 0x118 swap: pushl %ebp movl %esp,%ebp pushl %ebx 0x110 0x114 0x10c RTN ADR 0x108 %ebp 0x11c 0x104 … %esp 0x100 Save register ebx, which is callee saved. February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly The swap itself void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } 456 0x118 Register Variable %ecx yp %edx xp %eax t1 %ebx t0 123 0x114 0x118 0x110 0x114 0x10c RTN ADR 0x108 %ebp 0x11c 0x104 … %esp movl 12(%ebp),%ecx # ecx = yp 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 0x100 %eax %edx %ecx 0x118 %ebx February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly The swap itself void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } 456 0x118 Register Variable %ecx yp %edx xp %eax t1 %ebx t0 123 0x114 0x118 0x110 0x114 0x10c RTN ADR 0x108 %ebp 0x11c 0x104 … %esp movl 12(%ebp),%ecx # ecx = yp 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 0x100 %eax %edx 0x114 %ecx 0x118 %ebx February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly The swap itself void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } 456 0x118 Register Variable %ecx yp %edx xp %eax t1 %ebx t0 123 0x114 0x118 0x110 0x114 0x10c RTN ADR 0x108 %ebp 0x11c 0x104 … %esp movl 12(%ebp),%ecx # ecx = yp 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 0x100 %eax 456 %edx 0x114 %ecx 0x118 %ebx February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly The swap itself void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } 456 0x118 Register Variable %ecx yp %edx xp %eax t1 %ebx t0 123 0x114 0x118 0x110 0x114 0x10c RTN ADR 0x108 %ebp 0x11c 0x104 … %esp movl 12(%ebp),%ecx # ecx = yp 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 0x100 %eax 456 %edx 0x114 %ecx 0x118 %ebx 123 February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly The swap itself void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } 456 0x118 Register Variable %ecx yp %edx xp %eax t1 %ebx t0 456 0x114 0x118 0x110 0x114 0x10c RTN ADR 0x108 %ebp 0x11c 0x104 … %esp movl 12(%ebp),%ecx # ecx = yp 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 0x100 %eax 456 %edx 0x114 %ecx 0x118 %ebx 123 February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly The swap itself void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } 123 0x118 Register Variable %ecx yp %edx xp %eax t1 %ebx t0 456 0x114 0x118 0x110 0x114 0x10c RTN ADR 0x108 %ebp 0x11c 0x104 … %esp movl 12(%ebp),%ecx # ecx = yp 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 0x100 %eax 456 %edx 0x114 %ecx 0x118 %ebx 123 February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly Function Epilogue void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } 0x124 0x120 0x11c 123 0x118 456 0x114 0x118 0x110 movl -4(%ebp),%ebx movl %ebp,%esp popl %ebp ret 0x114 0x10c RTN ADR 0x108 %ebp 0x11c 0x104 … %esp 0x100 Restore register ebx. February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly Function Epilogue void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } 0x124 0x120 0x11c 123 0x118 456 0x114 0x118 0x110 movl -4(%ebp),%ebx movl %ebp,%esp popl %ebp ret 0x114 0x10c RTN ADR 0x108 %ebp 0x11c 0x104 … %esp 0x100 Copy the base pointer to the stack pointer. February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly Function Epilogue void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } 0x124 0x120 0x11c 123 0x118 456 0x114 0x118 0x110 movl -4(%ebp),%ebx movl %ebp,%esp popl %ebp ret 0x114 0x10c RTN ADR 0x108 %ebp,esp 0x11c 0x104 … 0x100 Restore the old base pointer. February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly Function Epilogue void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } 0x124 0x120 %ebp 0x11c 123 0x118 456 0x114 0x118 0x110 movl -4(%ebp),%ebx movl %ebp,%esp popl %ebp ret 0x114 0x10c RTN ADR %esp 0x108 0x11c 0x104 … 0x100 Return, which pops the return address off the stack February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly Memory Operands Most instructions (not just mov) can include a memory operand addl -8(%ebp), %eax # EAX = EAX + M[EBP - 8] incl -8(%ebp) # M[EBP - 8] = M[EBP - 8] + 1 More complex addressing modes are supported general form: D(Rb,Ri,S) # Mem[Reg[Rb]+S*Reg[Ri]+ D] D: Constant “displacement” 1, 2, or 4 bytes Rb: Base register: Any of 8 integer registers Ri: Index register: Any, except for %esp Unlikely you’d use %ebp, either S: Scale: 1, 2, 4, or 8 Useful for accessing arrays of scalars (including those within structs) February 27, 2018 ISA's, Compilers, and Assembly

Address Computation Examples %edx 0xf000 %ecx 0x100 Expression 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 February 27, 2018 ISA's, Compilers, and Assembly

Control Flow = Condition Codes Conditional control flow is a two step process: Setting a condition code (held in the EFLAGS register) done by most arithmetic operations Branching based on a condition code bit Standard sequence involves using the compare (cmp) instruction Compare acts like a subtract, but doesn’t write dest. register cmp 8(%ebx), %eax # set flags based on (EAX - M[EBX + 8]) jg branch_target # taken if (EAX > M[EBX + 8]) February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly Control Flow Example int sum(int n) { int i, sum = 0; for (i = 1 ; i <= n ; ++ i) { sum += i; } return sum; February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly Control Flow Example int sum(int n) { int i, sum = 0; for (i = 1 ; i <= n ; ++ i) { sum += i; } return sum; sum: pushl %ebp movl %esp, %ebp movl 8(%ebp), %ecx # n (was argument) movl $1, %edx # i = 1 xorl %eax, %eax # sum = 0 cmpl %ecx, %edx # (i ? n), sets cond. codes jg .L8 # branch if (i > n) .L6: addl %edx, %eax # sum += i incl %edx # i += 1 cmpl %ecx, %edx # (i ? n) jle .L6 # branch if (i <= n) .L8: February 27, 2018 ISA's, Compilers, and Assembly

Variable Length Instructions 08048344 <sum>: 8048344: 55 push %ebp 8048345: 89 e5 mov %esp,%ebp 8048347: 8b 4d 08 mov 0x8(%ebp),%ecx 804834a: ba 01 00 00 00 mov $0x1,%edx 804834f: 31 c0 xor %eax,%eax 8048351: 39 ca cmp %ecx,%edx 8048353: 7f 0a jg 804835f 8048355: 8d 76 00 lea 0x0(%esi),%esi ... 804835f: c9 leave 8048360: c3 ret Instructions range in size from 1 to 17 bytes Commonly used instructions are short (think compression) In general, x86 has smaller code than MIPS Many different instruction formats, plus pre-fixes, post-fixes Harder to decode for the machine (more on this later) February 27, 2018 ISA's, Compilers, and Assembly

ISA's, Compilers, and Assembly Why did Intel win? x86 won because it was the first 16-bit chip by two years. IBM put it in PCs because there was no competing choice Rest is inertia and “financial feedback” x86 is most difficult ISA to implement for high performance, but Because Intel sells the most processors ... It has the most money ... Which it uses to hire more and better engineers ... Which is uses to maintain competitive performance ... And given equal performance, compatibility wins ... So Intel sells the most processors. February 27, 2018 ISA's, Compilers, and Assembly