1 machine-level programming ii: basics comp 21000: introduction to computer organization &...
TRANSCRIPT
1
Machine-Level Programming II: Basics
Comp 21000: Introduction to Computer Organization & Systems
Spring 2015
Instructor: John Barr
* Modified slides from the book “Computer Systems: a Programmer’s Perspective”, Randy Bryant & David O’Hallaron, 2011
2
Machine Programming I: Basics History of Intel processors and architectures C, assembly, machine code Assembly Basics: Registers, operands, move Intro to x86-64
3
CISC Properties
Instruction can reference different operand types Immediate, register, memory
Arithmetic operations can read/write memory Memory reference can involve complex computation
Rb + S*Ri + D Useful for arithmetic expressions, too
Instructions can have varying lengths IA32 instructions can range from 1 to 15 bytes
4
Features of IA32 instructions IA32 instructions can be from 1 to 15 bytes.
More commonly used instructions are shorter Instructions with fewer operands are shorter
Each instruction has an instruction format Each instruction has a unique byte representation i.e., instruction pushl %ebp has encoding 55
IA32 started as a 16 bit language So IA32 calls a 16-bit piece of data a “word” A 32-bit piece of data is a “double word” or a “long word” A 64-bit piece of data is a “quad word”
5
CPU
Assembly Programmer’s View (review)
Programmer-Visible State PC: Program counter
Address of next instruction Called “EIP” (IA32) or “RIP” (x86-64)
Register file Heavily used program data 8 named locations, 32 bit values (x86-64)
Condition codes Store status information about most recent
arithmetic operation Used for conditional branching
PC Registers
Memory
Object CodeProgram DataOS Data
Addresses
Data
Instructions
Stack
ConditionCodes
Memory Byte addressable array Code, user data, (some) OS data Includes stack used to support
procedures
6
Instruction format Assembly language instructions have a very rigid format For most instructions the format is
movl Source, DestInstruction name
Source of data for the instruction:Registers/memory
Destination of instruction results:Registers/memory
Instruction suffix
7
Instruction suffix
Every operation in GAS has a single-character suffix
Denotes the size of the operand
Example: basic instruction is mov
Can move byte (movb), word (movw) and double word (movl)
Note that floating point operations have entirely different instructions.
C declaration
Intel data type GAS suffix Size (bytes)
char Byte b 1
short Word w 2
int Double word l 4
unsigned Double word l 4
long int Double word l 4
unsigned long Double word l 4
char * Double word l 4
float Single precision s 4
double Double precision l 8
long double
Extended precision t 10/12
8
Registers 8 32-bit general purpose registers
Programmers/compilers can use these All registers begin with %e Rest of name is historical: from 8086
Registers originally had specific purposes No restrictions on use of registers in commands
However, some instructions use fixed registers as source/destination In procedures there are different conventions for saving/restoring the
first 3 registers (%eax, %eac, %edx) than the next 3 (%ebx, %edi, %esi). Final two registers have special purposes in procedures
– %ebp (frame pointer)– %esp (stack pointer)
Will discuss all these later
9
Registers 8 32-bit general purpose registers
The low-order bytes of the first 4 registers can be independently read or written by byte operation instructions.
Done for backward compatibility with 8008 and 8080 (1970’s!) When a byte of the register is changed, the rest of the register is
unaffected. The low-order 2 bytes (16 bits, i.e., a single word) can be independently
read/wrote by word operation instructions Comes from 8086 16-bit heritage When a word of the register is changed, the rest of the register is
unaffected. See next slide!
10
Integer Registers (IA32)%eax
%ecx
%edx
%ebx
%esi
%edi
%esp
%ebp
%ax
%cx
%dx
%bx
%si
%di
%sp
%bp
%ah
%ch
%dh
%bh
%al
%cl
%dl
%bl
16-bit virtual registers(%ax, %cx,dx, …)
(backwards compatibility)
gene
ral p
urpo
se
accumulate
counter
data
base
source index
destinationindex
stack pointer
basepointer
Origin(mostly obsolete)
8-bit register (%ah, %al,ch, …)
32-bit register (%eax, %ecx, …)
11
Moving Data: IA32 Moving Data
movl Source, Dest: Move 4-byte (“long”) word Lots of these in typical code
Operand Types Immediate: Constant integer data
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”
%eax
%ecx
%edx
%ebx
%esi
%edi
%esp
%ebp
12
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
13
Simple Addressing Modes (cont)
Immediate $Imm Imm The value Imm is the value that is used
movl $4096,%eax
Absolute Imm Mem[Imm] No dollar sign before the number The number is the memory address to use
movl 4096,%edx
The book has more details on addressing modes!!
14
movl Operand Combinations
Cannot do memory-memory transfer with a single instruction
movl
Imm
Reg
Mem
RegMem
RegMem
Reg
Source Dest C Analog
movl $0x4,%eax temp = 0x4;
movl $-147,(%eax) *p = -147;
movl %eax,%edx temp2 = temp1;
movl %eax,(%edx) *p = temp;
movl (%eax),%edx temp = *p;
Src,Dest
15
mov instructionsInstruction Effect Description
movl S,D
movw S,D
D S
D S
Move double word
Move word
movb S,D D S Move byte
movsbl S,D D SignExtend (S) Move sign-extended byte
movzbl S,D D ZeroExtend Move zero-extended byte
Notes: 1. byte movements must use one of the 8 single-byte registers2. word movements must use one of the 8 2-byte registers3. movsbl takes single byte source, performs sign-extension on high-order 24 bits, copies
the resulting double word to dest.4. movzbl takes single byte source, performs adds 24 0’s to high-order bits, copies the
resulting double word to dest
16
mov instruction example Assume that %dh = 8D and %eax = 98765432 at the
beginning of each of these instructions
instruction result1. movb %dh, %al %eax =2. movsbl %dh, %eax %eax =3. movzbl %dh, %eax %eax =
9876548D
FFFFFF8D
0000008D
17
mov instruction example instruction addressing mode1. movl $0x4050, %eax2. movl %ebp, %esp3. movl (%ecx), %eax4. movl $-17, (%esp)5. movl %eax, -12(%ebp)
ImmReg
Reg Reg
Mem RegImmMem
RegMem (Displacement)
18
Special memory areas: stack and heap Stack
Space in Memory allocated to each running program (called a process)
Used to store “temporary” variable values Used to store variables for functions
Heap Space in Memory allocated to each running
program (process) Used to store dynamically allocated
variables
Kernel virtual memory
Memory mapped region forshared libraries
Run-time heap(created at runtime by malloc)
User stack(created at runtime)
Unused
Read/write segment(.data, .bss)
Read-only segment(.init, .text, .rodata)
19
Using Simple Addressing Modes
void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0;} Body
SetUp
Finish
swap: pushl %ebp movl %esp,%ebp pushl %ebx
movl 8(%ebp), %edx movl 12(%ebp), %ecx movl (%edx), %ebx movl (%ecx), %eax movl %eax, (%edx) movl %ebx, (%ecx)
popl %ebx popl %ebp ret
Use %ebp to manipulate the stack; we’ll discuss why later
20
Using Simple Addressing Modes
void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0;}
swap:pushl %ebpmovl %esp,%ebppushl %ebx
movl 8(%ebp), %edxmovl 12(%ebp), %ecxmovl (%edx), %ebxmovl (%ecx), %eaxmovl %eax, (%edx)movl %ebx, (%ecx)
popl %ebxpopl %ebpret
Body
SetUp
Finish
21
Understanding Swap
void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0;}
Stack(in memory)
Register Value%edx xp%ecx yp%ebx t0%eax t1
yp
xp
Rtn adr
Old %ebp %ebp 0
4
8
12
Offset
•••
Old %ebx-4 %esp
movl 8(%ebp), %edx # edx = xpmovl 12(%ebp), %ecx # ecx = ypmovl (%edx), %ebx # ebx = *xp (t0)movl (%ecx), %eax # eax = *yp (t1)movl %eax, (%edx) # *xp = t1movl %ebx, (%ecx) # *yp = t0
Pushed on the stack by the calling function
NOTE: MEMORY GROWS UP; 0 IS AT BOTTOM!
22
Understanding Swap
0x120
0x124
Rtn adr
%ebp 0
4
8
12
Offset
-4
123
456
Address0x124
0x120
0x11c
0x118
0x114
0x110
0x10c
0x108
0x104
0x100
yp
xp
%eax
%edx
%ecx
%ebx
%esi
%edi
%esp
%ebp 0x104movl 8(%ebp), %edx # edx = xpmovl 12(%ebp), %ecx # ecx = ypmovl (%edx), %ebx # ebx = *xp (t0)movl (%ecx), %eax # eax = *yp (t1)movl %eax, (%edx) # *xp = t1movl %ebx, (%ecx) # *yp = t0
Assume that the main() uses this memory for variables
23
Understanding Swap
0x120
0x124
Rtn adr
%ebp 0
4
8
12
Offset
-4
123
456
Address0x124
0x120
0x11c
0x118
0x114
0x110
0x10c
0x108
0x104
0x100
yp
xp
%eax
%edx
%ecx
%ebx
%esi
%edi
%esp
%ebp
0x124
0x104
0x120
movl 8(%ebp), %edx # edx = xpmovl 12(%ebp), %ecx # ecx = ypmovl (%edx), %ebx # ebx = *xp (t0)movl (%ecx), %eax # eax = *yp (t1)movl %eax, (%edx) # *xp = t1movl %ebx, (%ecx) # *yp = t0
24
Understanding Swap
0x120
0x124
Rtn adr
%ebp 0
4
8
12
Offset
-4
123
456
Address0x124
0x120
0x11c
0x118
0x114
0x110
0x10c
0x108
0x104
0x100
yp
xp
%eax
%edx
%ecx
%ebx
%esi
%edi
%esp
%ebp
0x120
0x104
0x124
0x124
movl 8(%ebp), %edx # edx = xpmovl 12(%ebp), %ecx # ecx = ypmovl (%edx), %ebx # ebx = *xp (t0)movl (%ecx), %eax # eax = *yp (t1)movl %eax, (%edx) # *xp = t1movl %ebx, (%ecx) # *yp = t0
25
456
Understanding Swap
0x120
0x124
Rtn adr
%ebp 0
4
8
12
Offset
-4
123
456
Address0x124
0x120
0x11c
0x118
0x114
0x110
0x10c
0x108
0x104
0x100
yp
xp
%eax
%edx
%ecx
%ebx
%esi
%edi
%esp
%ebp
0x124
0x120
123
0x104movl 8(%ebp), %edx # edx = xpmovl 12(%ebp), %ecx # ecx = ypmovl (%edx), %ebx # ebx = *xp (t0)movl (%ecx), %eax # eax = *yp (t1)movl %eax, (%edx) # *xp = t1movl %ebx, (%ecx) # *yp = t0
26
Understanding Swap
0x120
0x124
Rtn adr
%ebp 0
4
8
12
Offset
-4
123
456
Address0x124
0x120
0x11c
0x118
0x114
0x110
0x10c
0x108
0x104
0x100
yp
xp
%eax
%edx
%ecx
%ebx
%esi
%edi
%esp
%ebp
456
0x124
0x120
0x104
123
123
movl 8(%ebp), %edx # edx = xpmovl 12(%ebp), %ecx # ecx = ypmovl (%edx), %ebx # ebx = *xp (t0)movl (%ecx), %eax # eax = *yp (t1)movl %eax, (%edx) # *xp = t1movl %ebx, (%ecx) # *yp = t0
27
456
456
Understanding Swap
0x120
0x124
Rtn adr
%ebp 0
4
8
12
Offset
-4
Address0x124
0x120
0x11c
0x118
0x114
0x110
0x10c
0x108
0x104
0x100
yp
xp
%eax
%edx
%ecx
%ebx
%esi
%edi
%esp
%ebp
456456
0x124
0x120
123
0x104
123
movl 8(%ebp), %edx # edx = xpmovl 12(%ebp), %ecx # ecx = ypmovl (%edx), %ebx # ebx = *xp (t0)movl (%ecx), %eax # eax = *yp (t1)movl %eax, (%edx) # *xp = t1movl %ebx, (%ecx) # *yp = t0
28
Understanding Swap
0x120
0x124
Rtn adr
%ebp 0
4
8
12
Offset
-4
456
123
Address0x124
0x120
0x11c
0x118
0x114
0x110
0x10c
0x108
0x104
0x100
yp
xp
%eax
%edx
%ecx
%ebx
%esi
%edi
%esp
%ebp
456
0x124
0x120
0x104
123123
movl 8(%ebp), %edx # edx = xpmovl 12(%ebp), %ecx # ecx = ypmovl (%edx), %ebx # ebx = *xp (t0)movl (%ecx), %eax # eax = *yp (t1)movl %eax, (%edx) # *xp = t1movl %ebx, (%ecx) # *yp = t0
29
Understanding Assemblyvoid mystery(int a, int b) { int t0 = __________; int t1 = __________; int t2 = __________; return _________;}
int main() { int x = mystery(10, 33); return 0;}
Complete this exercise on your handout sheet!
30
Understanding Assembly
void mystery (int a, int b) { int t0 = __________; int t1 = __________; int t2 = __________; return _________;}
Stack(in memory)
Register Value%edx%ecx%ebx%eax
33
10
Rtn adr
??
%esp
0
4
8
12
Offset
•••
??-4
0x00000000 <+0>: push %ebp 0x00000001 <+1>: mov %esp,%ebp 0x00000003 <+3>: sub $0x10,%esp
Pushed on the stack by the calling function
NOTE: Stack often increased to account for local variables
??
??
??
-8
-12
-16
ba
Fill out the addresses for the stack on your handout
31
Understanding Assembly
void mystery (int a, int b) { int t0 = __________; int t1 = __________; int t2 = __________; return _________;}
Stack(in memory)
Register Value%edx%ecx%ebx%eax
33
10
Rtn adr
old %ebp %esp 0
4
8
12
Offset
•••
??-4
0x00000000 <+0>: push %ebp 0x00000001 <+1>: mov %esp,%ebp 0x00000003 <+3>: sub $0x10,%esp
Pushed on the stack by the calling function
NOTE: Stack often increased arbitrary amount for local variables
??
??
??
-8
-12
-16
ba
32
Understanding Assembly
void mystery (int a, int b) { int t0 = __________; int t1 = __________; int t2 = __________; return _________;}
Stack(in memory)
Register Value%edx%ecx%ebx%eax
33
10
Rtn adr
old %ebp %esp 0
4
8
12
Offset
•••
??-4
0x00000000 <+0>: push %ebp 0x00000001 <+1>: mov %esp,%ebp 0x00000003 <+3>: sub $0x10,%esp
Pushed on the stack by the calling function
NOTE: Stack often increased arbitrary amount for local variables
??
??
??
-8
-12
-16
ba
%ebp
33
Understanding Assembly
void mystery (int a, int b) { int t0 = __________; int t1 = __________; int t2 = __________; return _________;}
Stack(in memory)
Register Value%edx%ecx%ebx%eax
33
10
Rtn adr
old %ebp %ebp 0
4
8
12
Offset
•••
??-4
0x00000000 <+0>: push %ebp 0x00000001 <+1>: mov %esp,%ebp 0x00000003 <+3>: sub $0x10,%esp
Pushed on the stack by the calling function
NOTE: Stack often increased arbitrary amount for local variables
??
??
??
-8
-12
-16 %esp
ba
34
Understanding Assembly
void mystery (int a, int b) { int t0 = __________; int t1 = __________; int t2 = __________; return _________;}
Stack(in memory)
Register Value%edx%ecx%ebx%eax 10
33
10
Rtn adr
Old %ebp %ebp 0
4
8
12
Offset
•••
??-4
%esp
0x00000006 <+6>: mov 0x8(%ebp),%eax 0x00000009 <+9>: add $0x5,%eax 0x0000000c <+12>: mov %eax,-0xc(%ebp)
Pushed on the stack by the calling function
??
??
-12
-16
ba
??-8
35
Understanding Assembly
void mystery (int a, int b) { int t0 = __________; int t1 = __________; int t2 = __________; return _________;}
Stack(in memory)
Register Value%edx%ecx%ebx%eax 15
33
10
Rtn adr
Old %ebp %ebp 0
4
8
12
Offset
•••
??-4
%esp
0x00000006 <+6>: mov 0x8(%ebp),%eax 0x00000009 <+9>: add $0x5,%eax 0x0000000c <+12>: mov %eax,-0xc(%ebp)
Pushed on the stack by the calling function
??
??
-12
-16
ba
??-8
36
Understanding Assembly
void mystery (int a, int b) { int t0 = a + 5; int t1 = __________; int t2 = __________; return _________;}
Stack(in memory)
Register Value%edx%ecx%ebx%eax 15
33
10
Rtn adr
Old %ebp %ebp 0
4
8
12
Offset
•••
??-4
%esp
0x00000006 <+6>: mov 0x8(%ebp),%eax 0x00000009 <+9>: add $0x5,%eax 0x0000000c <+12>: mov %eax,-0xc(%ebp)
Pushed on the stack by the calling function
15
??
-12
-16
b
t0
a
??-8
37
Understanding Assembly
void mystery (int a, int b) { int t0 = a + 5; int t1 = __________; int t2 = __________; return _________;}
Stack(in memory)
Register Value%edx%ecx%ebx%eax 33
33
10
Rtn adr
Old %ebp %ebp 0
4
8
12
Offset
•••
??-4
%esp
0x0000000f <+15>: mov 0xc(%ebp),%eax 0x00000012 <+18>: sub $0x3,%eax 0x00000015 <+21>: mov %eax,-0x8(%ebp)
Pushed on the stack by the calling function
15
??
-12
-16
b
t0
a
%eax is often used for temporary values
??-8
38
Understanding Assembly
void mystery (int a, int b) { int t0 = a + 5; int t1 = __________; int t2 = __________; return _________;}
Stack(in memory)
Register Value%edx%ecx%ebx%eax 30
33
10
Rtn adr
Old %ebp %ebp 0
4
8
12
Offset
•••
??-4
%esp
0x0000000f <+15>: mov 0xc(%ebp),%eax 0x00000012 <+18>: sub $0x3,%eax 0x00000015 <+21>: mov %eax,-0x8(%ebp)
Pushed on the stack by the calling function
15
??
-12
-16
b
t0
a
??-8
39
Understanding Assembly
void mystery (int a, int b) { int t0 = a + 5; int t1 = b - 3; int t2 = __________; return _________;}
Stack(in memory)
Register Value%edx%ecx%ebx%eax 30
33
10
Rtn adr
Old %ebp %ebp 0
4
8
12
Offset
•••
??-4
%esp
0x0000000f <+15>: mov 0xc(%ebp),%eax 0x00000012 <+18>: sub $0x3,%eax 0x00000015 <+21>: mov %eax,-0x8(%ebp)
Pushed on the stack by the calling function
15
??
-12
-16
b
t0
a
30-8 t1
40
Understanding Assembly
void mystery (int a, int b) { int t0 = a + 5; int t1 = b - 3; int t2 = __________; return _________;}
Stack(in memory)
Register Value%edx%ecx%ebx%eax 30
33
10
Rtn adr
Old %ebp %ebp 0
4
8
12
Offset
•••
??-4
%esp
0x00000018 <+24>: mov -0x8(%ebp),%eax 0x0000001b <+27>: mov -0xc(%ebp),%edx 0x0000001e <+30>: add %edx,%eax 0x00000020 <+32>: mov %eax,-0x4(%ebp)
Pushed on the stack by the calling function
15
??
-12
-16
b
t0
a
30-8 t1
Finish this exercise on your handout sheet
41
Understanding Assembly
void mystery (int a, int b) { int t0 = a + 5; int t1 = b - 3; int t2 = t0 + t1; return t2;}
Stack(in memory)
Register Value%edx 15%ecx%ebx%eax 45
33
10
Rtn adr
Old %ebp %ebp 0
4
8
12
Offset
•••
45-4
%esp
0x00000023 <+35>: mov -0x4(%ebp),%eax 0x00000026 <+38>: leave 0x00000027 <+39>: ret
Pushed on the stack by the calling function
15
??
-12
-16
b
t0
a
30-8 t1
t2
NOTE: by convention the return value is ALWAYS stored in %eax
42
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]]D(Rb,Ri,S) Mem[Reg[Rb]+S*Reg[Ri]+D]
43
Address Computation Examples
%edx
%ecx
0xf000
0x100
Expression Computation Address
0x8(%edx)
(%edx,%ecx)
(%edx,%ecx,4)
0x80(,%edx,2)
44
Address Computation Examples
%edx
%ecx
0xf000
0x100
Expression Computation Address
0x8(%edx)
(%edx,%ecx)
(%edx,%ecx,4)
0x80(,%edx,2)
0xf000 + 0x8 0xf008
0xf000 + 0x100 0xf100
0xf000 + 4*0x100 0xf400
2*0xf000 + 0x80 0x1e080
45
Address Computation Instruction leal Src,Dest
Src is address mode expression Set Dest to address denoted by expression
Format Looks like a memory access Does not actually access memory Rather, calculates the memory address, then stores in a register
Uses Computing addresses without a memory reference
E.g., translation of p = &x[i]; Computing arithmetic expressions of the form x + k*y
k = 1, 2, 4, or 8.
lea = load effective addresslea = load effective address
46
Example
Converted to ASM by compiler:
int mul12(int x){ return x*12;}
int mul12(int x){ return x*12;} leal (%eax,%eax,2), %eax ;t <- x+x*2
sall $2, %eax ;return t<<2; or t * 4
leal (%eax,%eax,2), %eax ;t <- x+x*2sall $2, %eax ;return t<<2
; or t * 4
47
Address Computation InstructionExpression Result
leal 6(%eax), %edx
leal (%eax, %ecx), %edx
leal (%eax , %ecx, 4), %edx
leal 7(%eax, %eax, 8), %edx
leal 0xA(,%eax, 4), %edx
leal 9(%eax,%ecx, 2), %edx
Assume %eax holds value x and %ecx holds value y
* Note the leading comma in the next to last entry
48
Address Computation InstructionExpression Result
leal 6(%eax), %edx
leal (%eax, %ecx), %edx
leal (%eax , %ecx, 4), %edx
leal 7(%eax, %eax, 8), %edx
leal 0xA(,%eax, 4), %edx
leal 9(%eax,%ecx, 2), %edx
Assume %eax holds value x and %ecx holds value y
* Note the leading comma in the next to last entry
%edx x + 6
%edx x + (y * 2) + 9
%edx (x * 4) + 10
%edx x + (x * 8) + 7 = (x * 9) + 7
%edx x + (y * 4)
%edx x + y
49
pushl and popl instructions
Instruction Effect Description
pushl S R[%esp] R[%esp]–4;
M[R[%esp]]S
Push on runtime stack
popl D DM[R[%esp]];
R[%esp]R[%esp]+4
Pop from runtime stack
Notes: 1. both instructions take a single operand2. Stack is a place in memory allocated to a process3. Stack grows from smaller addresses to larger addresses4. %esp holds the address of the current top of stack5. When pushl a value, first increment %esp by 4, then write the value at the new top of stack
address.
Effect of a pushl %ebp instruction:
subl $4, %espmovl %ebp, (%esp)
Effect of a popl %eax instruction:
movl (%esp), %eaxsubl $4, %esp
50
Increasingaddress
•••
Stack “top”
Stack “bottom”
0x108
•••
Stack “top”
Stack “bottom”
0x104
•••
Stack “top”
Stack “bottom”
0x1080x123
0x123
0
0x108
%eax
%edx
%esp
Initially
0x123
0
0x104
%eax
%edx
%esp
pushl %eax
0x123
0x123
0x108
%eax
%edx
%esp
popl %edx
0x1230x108
1. By convention we draw the stack with the top towards the bottom2. IA32 stack grows toward lower addresses
Stack GrowsDown
51
Machine Programming I: Basics History of Intel processors and architectures C, assembly, machine code Assembly Basics: Registers, operands, move Intro to x86-64
52
Data Representations: IA32 + x86-64 Sizes of C Objects (in Bytes) C Data Type Generic 32-bit Intel IA32 x86-64
unsigned 4 44
int 4 44
long int 4 48
char 1 11
short 2 22
float 4 44
double 8 88
long double 8 10/1216
char * 4 48– Or any other pointer
53
%rsp
x86-64 Integer Registers
Extend existing registers. Add 8 new ones. Make %ebp/%rbp general purpose
%eax
%ebx
%ecx
%edx
%esi
%edi
%esp
%ebp
%r8d
%r9d
%r10d
%r11d
%r12d
%r13d
%r14d
%r15d
%r8
%r9
%r10
%r11
%r12
%r13
%r14
%r15
%rax
%rbx
%rcx
%rdx
%rsi
%rdi
%rbp
54
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
55
32-bit code for swap
void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0;} Body
SetUp
Finish
swap:pushl %ebpmovl %esp,%ebppushl %ebx
movl 8(%ebp), %edxmovl 12(%ebp), %ecxmovl (%edx), %ebxmovl (%ecx), %eaxmovl %eax, (%edx)movl %ebx, (%ecx)
popl %ebxpopl %ebpret
56
64-bit code for swap
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
void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0;}
Body
SetUp
Finish
swap:
movl (%rdi), %edxmovl (%rsi), %eaxmovl %eax, (%rdi)movl %edx, (%rsi)
ret
57
64-bit code for long int swap
64-bit data Data held in registers %rax and %rdx movq operation
“q” stands for quad-word
void swap(long *xp, long *yp) { long t0 = *xp; long t1 = *yp; *xp = t1; *yp = t0;}
Body
SetUp
Finish
swap_l:
movq (%rdi), %rdxmovq (%rsi), %raxmovq %rax, (%rdi)movq %rdx, (%rsi)
ret
58
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