0% found this document useful (0 votes)
37 views

KAIST 04 Machine Level Programming Basics

The document discusses machine-level programming and assembly basics. It provides an overview of Intel processors and architectures, and covers the basics of assembly including registers, operands, instructions, and the x86-64 architecture. It also discusses compiling C code to assembly and machine code.

Uploaded by

김민재
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
37 views

KAIST 04 Machine Level Programming Basics

The document discusses machine-level programming and assembly basics. It provides an overview of Intel processors and architectures, and covers the basics of assembly including registers, operands, instructions, and the x86-64 architecture. It also discusses compiling C code to assembly and machine code.

Uploaded by

김민재
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 47

KAIST

Machine‐Level Programming I: Basics
CS230: System Programming
4th Lecture

Instructor:
Jaehyuk Huh (허재혁)

Lecture slides based on CS:App from CMU and CS230 KAIST (Prof. Kim Daeyoung)
1
KAIST

Today: Machine Programming I: Basics
• History of Intel processors and architectures
• C, assembly, machine code
• Assembly Basics: Registers, operands, move
• Intro to x86‐64
KAIST

Intel x86 Processors
• Totally dominate laptop/desktop/server market

• Evolutionary design
– Backwards compatible up until 8086, introduced in 1978
– Added more features as time goes on

• Complex instruction set computer (CISC)
– Many different instructions with many different formats
• But, only small subset encountered with Linux programs
– Hard to match performance of Reduced Instruction Set Computers 
(RISC)
– But, Intel has done just that!
• In terms of speed.  Less so for low power.
KAIST

Intel x86 Evolution: Milestones
Name Date Transistors MHz
• 8086 1978 29K 5‐10
– First 16‐bit processor.  Basis for IBM PC & DOS
– 1MB address space
• 386 1985 275K 16‐33
– First 32 bit processor , referred to as IA32
– Added “flat addressing”
– Capable of running Unix
– 32‐bit Linux/gcc uses no instructions introduced in later models
• Pentium 4F 2004 125M 2800‐3800
– First 64‐bit processor, referred to as x86‐64
• Core i7 2008 731M 2667‐3333
– Our lab machines
KAIST

Intel x86 Processors: Overview
Architectures Processors
X86‐16 8086

286
X86‐32/IA32 386
486
Pentium
MMX Pentium MMX

SSE Pentium III

SSE2 Pentium 4

SSE3 Pentium 4E
X86‐64 / EM64t Pentium 4F time

Core 2 Duo
SSE4 Core i7
IA: often redefined as latest Intel architecture
KAIST

Intel x86 Processors, contd.
• Machine Evolution
– 386 1985 0.3M
– Pentium 1993 3.1M
– Pentium/MMX 1997 4.5M
– PentiumPro 1995 6.5M
– Pentium III 1999 8.2M
– Pentium 4 2001 42M
– Core 2 Duo 2006 291M
– Core i7 2008 731M
• Added Features
– Instructions to support multimedia operations
• Parallel operations on 1, 2, and 4‐byte data, both integer & FP
– Instructions to enable more efficient conditional operations
• Linux/GCC Evolution
– Two major steps: 1) support 32‐bit 386.  2) support 64‐bit x86‐64
KAIST

More Information
• Intel processors (Wikipedia)
• Intel microarchitectures
KAIST

New Species: ia64, then IPF, then 
Itanium,… 
Name DateTransistors
• Itanium 2001 10M
– First shot at 64‐bit architecture: first called IA64
– Radically new instruction set designed for high performance
– Can run existing IA32 programs
• On‐board “x86 engine”
– Joint project with Hewlett‐Packard
• Itanium 2 2002 221M
– Big performance boost
• Itanium 2 Dual‐Core 2006 1.7B
• Itanium has not taken off in marketplace
– Lack of backward compatibility, no good compiler support, Pentium 4 got 
too good
KAIST

x86 Clones: Advanced Micro Devices 
(AMD)
• Historically
–AMD has followed just behind Intel
–A little bit slower, a lot cheaper
• Then
–Recruited top circuit designers from Digital Equipment Corp. and other 
downward trending companies
–Built Opteron: tough competitor to Pentium 4
–Developed x86‐64, their own extension to 64 bits
KAIST

Intel’s 64‐Bit
• Intel Attempted Radical Shift from IA32 to IA64
– Totally different architecture (Itanium)
– Executes IA32 code only as legacy
– Performance disappointing
• AMD Stepped in with Evolutionary Solution
– x86‐64 (now called “AMD64”)
• Intel Felt Obligated to Focus on IA64
– Hard to admit mistake or that AMD is better
• 2004: Intel Announces EM64T extension to IA32
– Extended Memory 64‐bit Technology
– Almost identical to x86‐64!
• All but low‐end x86 processors support x86‐64
– But, lots of code still runs in 32‐bit mode
KAIST

Our Coverage
• IA32
– The traditional x86

• x86‐64/EM64T
– The emerging standard

• Presentation
– Book presents IA32 in Sections 3.1—3.12
– Covers x86‐64 in 3.13
– We will cover both simultaneously
– Some labs will be based on x86‐64, others on IA32
KAIST

Today: Machine Programming I: Basics
• History of Intel processors and architectures
• C, assembly, machine code
• Assembly Basics: Registers, operands, move
• Intro to x86‐64
KAIST

Definitions
• Architecture: (also instruction set architecture: ISA) The parts 
of a processor design that one needs to understand to write 
assembly code. 
– Examples:  instruction set specification, registers.
• Microarchitecture: Implementation of the architecture.
– Examples: cache sizes and core frequency.

• Example ISAs (Intel): x86, IA, IPF
KAIST

Assembly Programmer’s View
CPU Memory
Addresses
Registers Object Code
PC
Data Program Data
Condition OS Data
Instructions
Codes

Stack
• Programmer‐Visible State
– PC: Program counter
• Address of next instruction
• Called “EIP” (IA32) or “RIP” (x86‐64)
– Register file
• Heavily used program data
– Memory
• Byte addressable array
– Condition codes
• Code, user data, (some) OS data
• Store status information about most 
recent arithmetic operation • Includes stack used to support 
procedures
• Used for conditional branching
KAIST

Turning C into Object Code
– Code in files p1.c p2.c
– Compile with command: gcc –O1 p1.c p2.c -o p
• Use basic optimizations (-O1)
• Put resulting binary in file p

text C program (p1.c p2.c)

Compiler (gcc -S)

text Asm program (p1.s p2.s)

Assembler (gcc or as)

binary Object program (p1.o p2.o) Static libraries 


(.a)
Linker (gcc or ld)

binary Executable program (p)
KAIST

Compiling Into Assembly
C Code Generated IA32 Assembly
int sum(int x, int y) sum:
{ pushl %ebp
int t = x+y; movl %esp,%ebp
return t; movl 12(%ebp),%eax
} addl 8(%ebp),%eax
popl %ebp
ret

Some compilers use instruction 
“leave”

Obtain with command
/usr/local/bin/gcc –O1 -S code.c
Produces file code.s
KAIST

Assembly Characteristics: Data Types
• “Integer” data of 1, 2, or 4 bytes
– Data values
– Addresses (untyped pointers)

• Floating point data of 4, 8, or 10 bytes

• No aggregate types such as arrays or structures
– Just contiguously allocated bytes in memory
KAIST

Assembly Characteristics: Operations
• Perform arithmetic function on register or memory data

• Transfer data between memory and register
– Load data from memory into register
– Store register data into memory

• Transfer control
– Unconditional jumps to/from procedures
– Conditional branches
KAIST

Object Code
Code for sum
• Assembler
0x401040 <sum>:
0x55
– Translates .s into .o
0x89 – Binary encoding of each instruction
0xe5 – Nearly‐complete image of executable code
0x8b
0x45
– Missing linkages between code in different 
0x0c files
0x03 • Linker
0x45
0x08 – Resolves references between files
• Total of 11 bytes
0x5d – Combines with static run‐time libraries
0xc3 • Each instruction  • E.g., code for malloc, printf
1, 2, or 3 bytes
– Some libraries are dynamically linked
• Starts at address 
0x401040 • Linking occurs when program begins 
execution
KAIST

Machine Instruction Example
• C Code
int t = x+y;
– Add two signed integers
• Assembly
– Add 2 4‐byte integers
addl 8(%ebp),%eax
• “Long” words in GCC parlance
Similar to expression:  • Same instruction whether signed 
x += y or unsigned
More precisely: – Operands:
int eax; x: Register %eax
int *ebp; y: Memory M[%ebp+8]
eax += ebp[2] t: Register %eax
– Return function value in %eax

0x80483ca: 03 45 08 • Object Code
– 3‐byte instruction
– Stored at address 0x80483ca
KAIST

Disassembling Object Code
Disassembled
080483c4 <sum>:
80483c4: 55 push %ebp
80483c5: 89 e5 mov %esp,%ebp
80483c7: 8b 45 0c mov 0xc(%ebp),%eax
80483ca: 03 45 08 add 0x8(%ebp),%eax
80483cd: 5d pop %ebp
80483ce: c3 ret

• Disassembler
objdump -d p
– Useful tool for examining object code
– Analyzes bit pattern of series of instructions
– Produces approximate rendition of assembly code
– Can be run on either a.out (complete executable) or .o file
KAIST

Alternate Disassembly
Disassembled
Object
0x401040:
0x55 Dump of assembler code for function sum:
0x89 0x080483c4 <sum+0>: push %ebp
0xe5 0x080483c5 <sum+1>: mov %esp,%ebp
0x8b 0x080483c7 <sum+3>: mov 0xc(%ebp),%eax
0x45 0x080483ca <sum+6>: add 0x8(%ebp),%eax
0x0c 0x080483cd <sum+9>: pop %ebp
0x03 0x080483ce <sum+10>: ret
0x45
0x08
0x5d • Within gdb Debugger
0xc3 gdb p
disassemble sum
– Disassemble procedure
x/11xb sum
– Examine the 11 bytes starting at sum
KAIST

What Can be Disassembled?
% objdump -d WINWORD.EXE

WINWORD.EXE: file format pei-i386

No symbols in "WINWORD.EXE".
Disassembly of section .text:

30001000 <.text>:
30001000: 55 push %ebp
30001001: 8b ec mov %esp,%ebp
30001003: 6a ff push $0xffffffff
30001005: 68 90 10 00 30 push $0x30001090
3000100a: 68 91 dc 4c 30 push $0x304cdc91

• Anything that can be interpreted as executable code
• Disassembler examines bytes and reconstructs assembly source
KAIST

Today: Machine Programming I: Basics
• History of Intel processors and architectures
• C, assembly, machine code
• Assembly Basics: Registers, operands, move
• Intro to x86‐64
KAIST

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)
KAIST

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 ‘$’
• Encoded with 1, 2, or 4 bytes %esp
– 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”
KAIST

movl Operand Combinations
Source Dest Src,Dest C Analog

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


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

movl Reg movl %eax,%edx temp2 = temp1;


Reg
Mem movl %eax,(%edx) *p = temp;

Mem Reg movl (%eax),%edx temp = *p;

Cannot do memory‐memory transfer with a single instruction
KAIST

Simple Memory Addressing 
Modes
• Normal (R) Mem[Reg[R]]
– Register R specifies memory address

movl (%ecx),%eax

• Displacement D(R) Mem[Reg[R]+D]


– Register R specifies start of memory region
– Constant displacement D specifies offset

movl 8(%ebp),%edx
KAIST

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

popl %ebx
popl %ebp Finish
ret
KAIST

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

popl %ebx
popl %ebp Finish
ret
KAIST

Understanding Swap
void swap(int *xp, int *yp) •
{ • Stack
int t0 = *xp; • (in memory)
Offset
int t1 = *yp;
*xp = t1; 12 yp
*yp = t0; 8 xp
}
4 Rtn adr
0 Old %ebp %ebp
-4 Old %ebx %esp
Register Value
%edx xp
%ecx yp
movl 8(%ebp), %edx # edx = xp
%ebx t0
movl 12(%ebp), %ecx # ecx = yp
%eax t1 movl (%edx), %ebx # ebx = *xp (t0)
movl (%ecx), %eax # eax = *yp (t1)
movl %eax, (%edx) # *xp = t1
movl %ebx, (%ecx) # *yp = t0
KAIST
Address
Understanding Swap 123 0x124
456 0x120
0x11c
%eax 0x118
%edx Offset
0x114
%ecx yp 12 0x120 0x110
xp 8 0x124 0x10c
%ebx
4 Rtn adr 0x108
%esi
%ebp 0
0x104
%edi -4
0x100
%esp
movl 8(%ebp), %edx # edx = xp
%ebp 0x104 movl 12(%ebp), %ecx # ecx = yp
movl (%edx), %ebx # ebx = *xp (t0)
movl (%ecx), %eax # eax = *yp (t1)
movl %eax, (%edx) # *xp = t1
movl %ebx, (%ecx) # *yp = t0
KAIST
Address
Understanding Swap 123 0x124
456 0x120
0x11c
%eax 0x118
%edx 0x124 Offset
0x114
%ecx yp 12 0x120 0x110
xp 8 0x124 0x10c
%ebx
4 Rtn adr 0x108
%esi
%ebp 0
0x104
%edi -4
0x100
%esp
movl 8(%ebp), %edx # edx = xp
%ebp 0x104 movl 12(%ebp), %ecx # ecx = yp
movl (%edx), %ebx # ebx = *xp (t0)
movl (%ecx), %eax # eax = *yp (t1)
movl %eax, (%edx) # *xp = t1
movl %ebx, (%ecx) # *yp = t0
KAIST
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 8(%ebp), %edx # edx = xp
%ebp 0x104 movl 12(%ebp), %ecx # ecx = yp
movl (%edx), %ebx # ebx = *xp (t0)
movl (%ecx), %eax # eax = *yp (t1)
movl %eax, (%edx) # *xp = t1
movl %ebx, (%ecx) # *yp = t0
KAIST
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 123
4 Rtn adr 0x108
%esi
%ebp 0
0x104
%edi -4
0x100
%esp
movl 8(%ebp), %edx # edx = xp
%ebp 0x104 movl 12(%ebp), %ecx # ecx = yp
movl (%edx), %ebx # ebx = *xp (t0)
movl (%ecx), %eax # eax = *yp (t1)
movl %eax, (%edx) # *xp = t1
movl %ebx, (%ecx) # *yp = t0
KAIST
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 8(%ebp), %edx # edx = xp
%ebp 0x104 movl 12(%ebp), %ecx # ecx = yp
movl (%edx), %ebx # ebx = *xp (t0)
movl (%ecx), %eax # eax = *yp (t1)
movl %eax, (%edx) # *xp = t1
movl %ebx, (%ecx) # *yp = t0
KAIST
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 8(%ebp), %edx # edx = xp
%ebp 0x104 movl 12(%ebp), %ecx # ecx = yp
movl (%edx), %ebx # ebx = *xp (t0)
movl (%ecx), %eax # eax = *yp (t1)
movl %eax, (%edx) # *xp = t1
movl %ebx, (%ecx) # *yp = t0
KAIST
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 8(%ebp), %edx # edx = xp
%ebp 0x104 movl 12(%ebp), %ecx # ecx = yp
movl (%edx), %ebx # ebx = *xp (t0)
movl (%ecx), %eax # eax = *yp (t1)
movl %eax, (%edx) # *xp = t1
movl %ebx, (%ecx) # *yp = t0
KAIST

Complete Memory Addressing Modes
• Most 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 (why these numbers?)

• Special Cases
(Rb,Ri) Mem[Reg[Rb]+Reg[Ri]]
D(Rb,Ri) Mem[Reg[Rb]+Reg[Ri]+D]
(Rb,Ri,S) Mem[Reg[Rb]+S*Reg[Ri]]
KAIST

Today: Machine Programming I: Basics
• History of Intel processors and architectures
• C, assembly, machine code
• Assembly Basics: Registers, operands, move
• Intro to x86‐64
KAIST

Data Representations: IA32 + x86‐64
• Sizes of C Objects (in Bytes)
– C Data Type Generic 32‐bit Intel IA32 x86‐64
• unsigned 4 4 4
• int 4 4 4
• long int 4 4 8
• char 1 1 1
• short 2 2 2
• float 4 4 4
• double 8 8 8
• long double 8 10/12 16
• char * 4 4 8
– Or any other pointer
KAIST

x86‐64 Integer Registers
%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.  Add 8 new ones.
– Make %ebp/%rbp general purpose
KAIST

Instructions
• Long word l (4 Bytes) ↔ Quad word q (8 Bytes)

• New instructions:
– movl ➙ movq
– addl ➙ addq
– sall ➙ salq
– etc.

• 32‐bit instructions that generate 32‐bit results
– Set higher order bits of destination register to 0
– Example: addl
KAIST

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

popl %ebx
popl %ebp Finish
ret
KAIST

64‐bit code for swap
swap:
Set
void swap(int *xp, int *yp) Up
{
int t0 = *xp; movl (%rdi), %edx
int t1 = *yp; movl (%rsi), %eax
Body
*xp = t1; movl %eax, (%rdi)
*yp = t0; movl %edx, (%rsi)
}
ret Finish

• Operands passed in registers (why useful?)
– First (xp) in %rdi, second (yp) in %rsi
– 64‐bit pointers
• No stack operations required
• 32‐bit data
– Data held in registers %eax and %edx
– movl operation
KAIST

64‐bit code for long int swap
swap_l:
Set
void swap(long *xp, long *yp) Up
{
long t0 = *xp; movq (%rdi), %rdx
long t1 = *yp; movq (%rsi), %rax
Body
*xp = t1; movq %rax, (%rdi)
*yp = t0; movq %rdx, (%rsi)
}
ret Finish

• 64‐bit data
– Data held in registers %rax and %rdx
– movq operation
• “q” stands for quad‐word
KAIST

Machine Programming I: Summary
• History of Intel processors and architectures
– Evolutionary design leads to many quirks and artifacts
• C, assembly, machine code
– Compiler must transform statements, expressions, procedures into 
low‐level instruction sequences
• Assembly Basics: Registers, operands, move
– The x86 move instructions cover wide range of data movement forms
• Intro to x86‐64
– A major departure from the style of code seen in IA32

You might also like