x86 Assembly and Call Stack
CS 161 Spring 2024 - Lecture 2
Computer Science 161
Last Time
2
Computer Science 161
Today
3
Computer Science 161
Number Representation
4
Textbook Chapter 2.1
Computer Science 161
Units of Measurement
5
Computer Science 161
Hexadecimal
6
Binary | Hexadecimal |
0000 | 0 |
0001 | 1 |
0010 | 2 |
0011 | 3 |
0100 | 4 |
0101 | 5 |
0110 | 6 |
0111 | 7 |
Binary | Hexadecimal |
1000 | 8 |
1001 | 9 |
1010 | A |
1011 | B |
1100 | C |
1101 | D |
1110 | E |
1111 | F |
Computer Science 161
Hexadecimal
7
Binary | Hexadecimal |
0000 | 0 |
0001 | 1 |
0010 | 2 |
0011 | 3 |
0100 | 4 |
0101 | 5 |
0110 | 6 |
0111 | 7 |
Binary | Hexadecimal |
1000 | 8 |
1001 | 9 |
1010 | A |
1011 | B |
1100 | C |
1101 | D |
1110 | E |
1111 | F |
Computer Science 161
Running C Programs
8
Textbook Chapter 2.2
Computer Science 161
CALL (Compiler, Assembler, Linker, Loader)
9
int add_one(int a) {� int added = a + 1;� return added;�}
C code
add_one:� pushl %ebp� movl %esp, %ebp� subl $4, %esp� movl 8(%ebp), %eax� movl %eax, -4(%ebp)� incl -4(%ebp)� movl -4(%ebp), %eax� leave� ret
Assembly code
(RISC-V, x86)
0x55 0x89 0xe5 0x83 0xec 0x04 0x8b 0x45 0x08 0x89 0x45 0xfc 0x45 0x89 0xe8 0xc9 0xc3
Machine code
(raw bits)
Compiler
Assembler
Computer Science 161
CALL (Compiler, Assembler, Linker, Loader)
10
Computer Science 161
C Memory Layout
11
address 0x00000000
address 0xFFFFFFFF
Computer Science 161
C Memory Layout
12
|
address 0x00000000
address 0xFFFFFFFF
Higher addresses
Lower addresses
4 bytes
Computer Science 161
Endianness
13
Textbook Chapter 2.4
Computer Science 161
C memory layout
0xDE 0xAD 0xBE 0xEF 0x11 0x22 0x33 0x44 |
address 0x00000000
address 0xFFFFFFFF
Computer Science 161
C memory layout
0xDE 0xAD 0xBE 0xEF 0x11 0x22 0x33 0x44 |
address 0x00000001
address 0xFFFFFFFF
Computer Science 161
C memory layout
0xDE 0xAD 0xBE 0xEF 0x11 0x22 0x33 0x44 |
address 0x00000004
address 0xFFFFFFFF
Computer Science 161
Little-endian words
0xDE 0xAD 0xBE 0xEF 0x11 0x22 0x33 0x44 |
address 0x00000000
address 0xFFFFFFFF
Computer Science 161
Quick detour: How do we write dates?
Computer Science 161
Quick detour: How do we write dates?
Computer Science 161
Little-endian words
0xDE 0xAD 0xBE 0xEF 0x11 0x22 0x33 0x44 |
address 0x00000000
Computer Science 161
Quick detour: How do we write dates?
Computer Science 161
Little-endian words
0xDE 0xAD 0xBE 0xEF 0x11 0x22 0x33 0x44 |
address 0x00000000
Computer Science 161
Notation
0xDE 0xAD 0xBE 0xEF 0x44332211 |
word at 0x00000000
bytes at 0x00000004
Computer Science 161
Memory Layout
24
Textbook Chapter 2.3 & 2.5
Computer Science 161
x86 Memory Layout
25
Higher addresses
Lower addresses
Stack |
|
Heap |
Data |
Code |
Grows downwards
Grows upwards
Computer Science 161
Registers
26
Higher addresses
Lower addresses
Stack |
|
Heap |
Data |
Code |
Grows downwards
Grows upwards
Computer Science 161
Intro to x86 Architecture
27
Textbook Chapter 2.4 & 2.7
Computer Science 161
Why x86?
28
Computer Science 161
x86 Fact Sheet
29
Computer Science 161
x86 Registers
30
Computer Science 161
x86 Syntax
31
Computer Science 161
x86 Assembly
32
Opcode
Source
Destination
Computer Science 161
x86 Assembly
33
Opcode
Source
Destination
Computer Science 161
Stack Layout
Textbook Chapter 2.6
34
Computer Science 161
Stack Frames
35
Computer Science 161
Stack Frames
36
... |
... |
... |
... |
|
|
|
|
|
|
|
|
|
|
|
EBP
ESP
Current stack frame
Computer Science 161
Quick detour: storing pointers
... |
|
|
|
|
|
|
... |
Code for foo |
Code for main |
CODE
STACK
Registers
ebp
esp
eip
Current stack frame
Computer Science 161
Quick detour: storing pointers
... |
|
|
|
|
|
|
... |
Code for foo |
Code for main |
CODE
STACK
Registers
ebp
esp
eip
Current stack frame
0xbffff320
0xbffff314
0xbffff320
0xbffff314
Computer Science 161
Pushing and Popping
39
|
|
|
|
|
|
|
EBP
ESP
Current stack frame
|
|
|
|
|
0xcafef00d |
|
EBP
ESP
Current stack frame
Before push %eax
After push %eax
EAX = 0xcafef00d
EBX = ...
EAX = 0xcafef00d
EBX = ...
Computer Science 161
Pushing and Popping
40
|
|
|
|
|
0xcafef00d |
|
EBP
ESP
Current stack frame
|
|
|
|
|
0xcafef00d |
|
EBP
ESP
Current stack frame
Before pop %eax
After pop %eax
EAX = 0x00000000
EBX = ...
EAX = 0xcafef00d
EBX = ...
Computer Science 161
x86 Stack Layout
41
Computer Science 161
Stack Layout
struct foo {� long long f1; // 8 bytes� int f2; // 4 bytes� int f3; // 4 bytes�};��void func(void) {� int a; // 4 bytes� struct foo b;� int c; // 4 bytes�}
42
|
|
|
|
|
|
a |
b.f3 |
b.f2 |
b.f1 |
b.f1 |
c |
How would you fill out the boxes in this stack diagram?
Options:
a b.f1 b.f2 b.f3 c
Higher addresses
Lower addresses
4 bytes
Computer Science 161
Calling Convention
43
Textbook Chapter 2.6
Computer Science 161
Function Calls
44
int main() {� int a = 1;� foo();� return 0;�}
Caller
void foo() {� int b = 0;� return;�}
Callee
int main() {� int a = 1;� foo();� return 0;�}
Caller
The caller function (main) calls the callee function (foo).
The callee function executes and then returns control to the caller function.
Before function call
During function call
After function returns
Computer Science 161
x86 Calling Convention
45
Computer Science 161
Calling a Function in x86
46
|
|
|
|
|
caller code |
callee code |
|
|
|
|
|
caller code |
callee code |
|
|
|
|
|
caller code |
callee code |
EBP
Caller frame
ESP
Before function call
EIP
Stack
Code
EBP
ESP
During function call
Caller frame
Callee frame
EIP
Stack
Code
Caller frame
After function call
EBP
ESP
EIP
Stack
Code
Computer Science 161
x86 Calling Convention Design
47
Textbook Chapter 2.6
Computer Science 161
Review: stack, registers
... |
|
|
|
|
|
|
... |
Code for foo |
Code for main |
CODE
STACK
Registers
ebp
esp
eip
The stack grows this way
Computer Science 161
Review: words, code section
... |
|
|
|
|
|
|
... |
Code for foo |
Code for main |
CODE
STACK
Registers
ebp
esp
eip
Addresses increase this way
Computer Science 161
Stack frames
... |
|
|
|
|
|
|
... |
Code for foo |
Code for main |
CODE
Registers
ebp
esp
eip
STACK
Computer Science 161
ebp and esp
... |
|
|
|
|
|
|
... |
Code for foo |
Code for main |
CODE
STACK
Registers
ebp
esp
eip
Current stack frame
Computer Science 161
esp
... |
|
|
|
|
|
|
... |
Code for foo |
Code for main |
CODE
STACK
Registers
ebp
esp
eip
Current stack frame
Computer Science 161
eip
... |
|
|
|
|
|
|
... |
Code for foo |
Code for main |
CODE
STACK
Registers
ebp
esp
eip
Current stack frame
Computer Science 161
Designing the stack: requirements
Stack frame for main |
|
|
|
|
|
|
... |
Code for foo |
Code for main |
CODE
Registers
ebp
esp
eip
STACK
Computer Science 161
Designing the stack: requirements
Stack frame for main |
|
|
|
|
|
|
... |
Code for foo |
Code for main |
CODE
Registers
ebp
esp
eip
STACK
Computer Science 161
Designing the stack: requirements
Stack frame for main |
|
|
|
|
|
|
... |
Code for foo |
Code for main |
CODE
STACK
Registers
ebp
esp
eip
Computer Science 161
Remember to save your work as you go
Stack frame for main |
|
|
|
|
|
|
... |
Code for foo |
Code for main |
CODE
STACK
Registers
ebp
esp
eip
Computer Science 161
1. Arguments
Stack frame for main |
Argument #2 |
Argument #1 |
|
|
|
|
... |
Code for foo |
Code for main |
CODE
STACK
Registers
ebp
esp
eip
Computer Science 161
2. Remember eip
Stack frame for main |
Argument #2 |
Argument #1 |
Old eip (rip) |
|
|
|
... |
Code for foo |
Code for main |
CODE
STACK
Registers
ebp
esp
eip
Computer Science 161
2. Remember eip
Stack frame for main |
Argument #2 |
Argument #1 |
Old eip (rip) |
|
|
|
... |
Code for foo |
Code for main |
CODE
STACK
Registers
ebp
esp
eip
Computer Science 161
3. Remember ebp
Stack frame for main |
Argument #2 |
Argument #1 |
Old eip (rip) |
Old ebp (sfp) |
|
|
... |
Code for foo |
Code for main |
CODE
STACK
Registers
ebp
esp
eip
Computer Science 161
3. Remember ebp
Stack frame for main |
Argument #2 |
Argument #1 |
Old eip (rip) |
Old ebp (sfp) |
|
|
... |
Code for foo |
Code for main |
CODE
STACK
Registers
ebp
esp
eip
Computer Science 161
4. Adjust the stack frame
CODE
STACK
Registers
ebp
esp
eip
Stack frame for main |
Argument #2 |
Argument #1 |
Old eip (rip) |
Old ebp (sfp) |
|
|
... |
Code for foo |
Code for main |
Computer Science 161
4. Adjust the stack frame
CODE
STACK
Registers
ebp
esp
eip
Stack frame for main |
Argument #2 |
Argument #1 |
Old eip (rip) |
Old ebp (sfp) |
|
|
... |
Code for foo |
Code for main |
dashed line = ebp pointer before this step
Computer Science 161
4. Adjust the stack frame
CODE
STACK
Registers
ebp
esp
eip
Stack frame for main |
Argument #2 |
Argument #1 |
Old eip (rip) |
Old ebp (sfp) |
|
|
... |
Code for foo |
Code for main |
dashed line = esp pointer before this step
Computer Science 161
4. Adjust the stack frame
CODE
STACK
Registers
ebp
esp
eip
Stack frame for main |
Argument #2 |
Argument #1 |
Old eip (rip) |
Old ebp (sfp) |
|
|
... |
Code for foo |
Code for main |
dashed line = eip pointer before this step
Computer Science 161
5. Execute the function
CODE
STACK
Registers
ebp
esp
eip
Stack frame for main |
Argument #2 |
Argument #1 |
Old eip (rip) |
Old ebp (sfp) |
Local variable |
Local variable |
... |
Code for foo |
Code for main |
Computer Science 161
6. Restore everything
CODE
STACK
Registers
ebp
esp
eip
Stack frame for main |
Argument #2 |
Argument #1 |
Old eip (rip) |
Old ebp (sfp) |
Local variable |
Local variable |
... |
Code for foo |
Code for main |
Computer Science 161
6. Restore everything
CODE
STACK
Registers
ebp
esp
eip
Stack frame for main |
Argument #2 |
Argument #1 |
Old eip (rip) |
Old ebp (sfp) |
Local variable |
Local variable |
... |
Code for foo |
Code for main |
Computer Science 161
Review: steps of a function call
Computer Science 161
Steps of a function call (complete)
Computer Science 161
Steps of a function call (complete)
main
foo
main
Moving eip transfers control from main to foo.
Restoring eip transfers control back to main.
Computer Science 161
x86 Calling Convention Walkthrough
73
Textbook Chapter 2.6
Computer Science 161
x86 Function Call
caller:
...
push $2
push $1
call callee
add $8, %esp
...
callee:
push %ebp
mov %esp, %ebp
sub $4, %esp
mov $42, %eax
mov %ebp, %esp
pop %ebp
ret
void caller(void) {� callee(1, 2);�}
74
Here is a snippet of C code
Here is the code compiled into x86 assembly
int callee(int a, int b) {� int local;� return 42;�}
Computer Science 161
x86 Function Call
caller:
...
push $2
push $1
call callee
add $8, %esp
...
callee:
push %ebp
mov %esp, %ebp
sub $4, %esp
mov $42, %eax
mov %ebp, %esp
pop %ebp
ret
void caller(void) {� callee(1, 2);�}
75
The instruction that was just executed is in red
The EIP points to the address of the next instruction!
EIP
int callee(int a, int b) {� int local;� return 42;�}
Computer Science 161
x86 Function Call
caller:
...
push $2
push $1
call callee
add $8, %esp
...
callee:
push %ebp
mov %esp, %ebp
sub $4, %esp
mov $42, %eax
mov %ebp, %esp
pop %ebp
ret
void caller(void) {� callee(1, 2);�}
76
|
|
|
|
|
|
|
Here is a diagram of the stack. Remember, each row represents 4 bytes (32 bits).
EIP
int callee(int a, int b) {� int local;� return 42;�}
Computer Science 161
x86 Function Call
caller:
...
push $2
push $1
call callee
add $8, %esp
...
callee:
push %ebp
mov %esp, %ebp
sub $4, %esp
mov $42, %eax
mov %ebp, %esp
pop %ebp
ret
void caller(void) {� callee(1, 2);�}
77
caller stack frame |
|
|
|
|
|
EBP
ESP
EIP
int callee(int a, int b) {� int local;� return 42;�}
Computer Science 161
x86 Function Call
caller:
...
push $2
push $1
call callee
add $8, %esp
...
callee:
push %ebp
mov %esp, %ebp
sub $4, %esp
mov $42, %eax
mov %ebp, %esp
pop %ebp
ret
1. Push arguments on the stack
void caller(void) {� callee(1, 2);�}
78
EBP
caller stack frame |
2 |
|
|
|
|
ESP
EIP
int callee(int a, int b) {� int local;� return 42;�}
Computer Science 161
x86 Function Call
caller:
...
push $2
push $1
call callee
add $8, %esp
...
callee:
push %ebp
mov %esp, %ebp
sub $4, %esp
mov $42, %eax
mov %ebp, %esp
pop %ebp
ret
1. Push arguments on the stack
void caller(void) {� callee(1, 2);�}
79
caller stack frame |
2 |
1 |
|
|
|
EBP
ESP
EIP
int callee(int a, int b) {� int local;� return 42;�}
Computer Science 161
x86 Function Call
caller:
...
push $2
push $1
call callee
add $8, %esp
...
callee:
push %ebp
mov %esp, %ebp
sub $4, %esp
mov $42, %eax
mov %ebp, %esp
pop %ebp
ret
2. Push old EIP (RIP) on the stack�3. Move EIP
void caller(void) {� callee(1, 2);�}
80
caller stack frame |
2 |
1 |
RIP of callee |
|
|
EBP
ESP
EIP
int callee(int a, int b) {� int local;� return 42;�}
Computer Science 161
x86 Function Call
caller:
...
push $2
push $1
call callee
add $8, %esp
...
callee:
push %ebp
mov %esp, %ebp
sub $4, %esp
mov $42, %eax
mov %ebp, %esp
pop %ebp
ret
void caller(void) {� callee(1, 2);�}
81
caller stack frame |
2 |
1 |
RIP of callee |
|
|
Function prologue
EBP
ESP
EIP
int callee(int a, int b) {� int local;� return 42;�}
Computer Science 161
x86 Function Call
caller:
...
push $2
push $1
call callee
add $8, %esp
...
callee:
push %ebp
mov %esp, %ebp
sub $4, %esp
mov $42, %eax
mov %ebp, %esp
pop %ebp
ret
4. Push old EBP (SFP) on the stack
void caller(void) {� callee(1, 2);�}
82
caller stack frame |
2 |
1 |
RIP of callee |
SFP of callee |
|
EBP
ESP
EIP
int callee(int a, int b) {� int local;� return 42;�}
Computer Science 161
x86 Function Call
caller:
...
push $2
push $1
call callee
add $8, %esp
...
callee:
push %ebp
mov %esp, %ebp
sub $4, %esp
mov $42, %eax
mov %ebp, %esp
pop %ebp
ret
5. Move EBP
void caller(void) {� callee(1, 2);�}
83
caller stack frame |
2 |
1 |
RIP of callee |
SFP of callee |
|
EBP
ESP
EIP
int callee(int a, int b) {� int local;� return 42;�}
Computer Science 161
x86 Function Call
caller:
...
push $2
push $1
call callee
add $8, %esp
...
callee:
push %ebp
mov %esp, %ebp
sub $4, %esp
mov $42, %eax
mov %ebp, %esp
pop %ebp
ret
6. Move ESP
void caller(void) {� callee(1, 2);�}
84
caller stack frame |
2 |
1 |
RIP of callee |
SFP of callee |
|
EBP
ESP
EIP
int callee(int a, int b) {� int local;� return 42;�}
Computer Science 161
x86 Function Call
caller:
...
push $2
push $1
call callee
add $8, %esp
...
callee:
push %ebp
mov %esp, %ebp
sub $4, %esp
mov $42, %eax
mov %ebp, %esp
pop %ebp
ret
7. Execute the function
void caller(void) {� callee(1, 2);�}
85
caller stack frame |
2 |
1 |
RIP of callee |
SFP of callee |
local |
EBP
ESP
EIP
int callee(int a, int b) {� int local;� return 42;�}
Computer Science 161
x86 Function Call
caller:
...
push $2
push $1
call callee
add $8, %esp
...
callee:
push %ebp
mov %esp, %ebp
sub $4, %esp
mov $42, %eax
mov %ebp, %esp
pop %ebp
ret
void caller(void) {� callee(1, 2);�}
86
caller stack frame |
2 |
1 |
RIP of callee |
SFP of callee |
local |
Function epilogue
leave
ret
EBP
ESP
EIP
int callee(int a, int b) {� int local;� return 42;�}
Computer Science 161
x86 Function Call
caller:
...
push $2
push $1
call callee
add $8, %esp
...
callee:
push %ebp
mov %esp, %ebp
sub $4, %esp
mov $42, %eax
mov %ebp, %esp
pop %ebp
ret
8. Move ESP
void caller(void) {� callee(1, 2);�}
87
caller stack frame |
2 |
1 |
RIP of callee |
SFP of callee |
local |
ESP
EBP
EIP
int callee(int a, int b) {� int local;� return 42;�}
Computer Science 161
x86 Function Call
caller:
...
push $2
push $1
call callee
add $8, %esp
...
callee:
push %ebp
mov %esp, %ebp
sub $4, %esp
mov $42, %eax
mov %ebp, %esp
pop %ebp
ret
9. Pop (restore) old EBP (SFP)
void caller(void) {� callee(1, 2);�}
88
caller stack frame |
2 |
1 |
RIP of callee |
SFP of callee |
local |
EBP
ESP
EIP
int callee(int a, int b) {� int local;� return 42;�}
Computer Science 161
x86 Function Call
caller:
...
push $2
push $1
call callee
add $8, %esp
...
callee:
push %ebp
mov %esp, %ebp
sub $4, %esp
mov $42, %eax
mov %ebp, %esp
pop %ebp
ret
10. Pop (restore) old EIP (RIP)
void caller(void) {� callee(1, 2);�}
89
caller stack frame |
2 |
1 |
RIP of callee |
SFP of callee |
local |
EBP
ESP
EIP
int callee(int a, int b) {� int local;� return 42;�}
Computer Science 161
x86 Function Call
caller:
...
push $2
push $1
call callee
add $8, %esp
...
callee:
push %ebp
mov %esp, %ebp
sub $4, %esp
mov $42, %eax
mov %ebp, %esp
pop %ebp
ret
11. Remove arguments from stack
void caller(void) {� callee(1, 2);�}
90
caller stack frame |
2 |
1 |
RIP of callee |
SFP of callee |
local |
EBP
ESP
EIP
int callee(int a, int b) {� int local;� return 42;�}
Computer Science 161
Summary: x86 Assembly and Call Stack
91
Computer Science 161