Transcript Chapter 5
Assembly Language for x86 Processors
6th Edition
Kip R. Irvine
Chapter 5: The Stack
Slides prepared by the author
Revision date: 2/15/2010
(c) Pearson Education, 2010. All rights reserved. You may modify and copy this slide show for your personal use, or for
use in the classroom, as long as this copyright statement, the author's name, and the title are not changed.
A Process in Virtual Memory
This is how a process is placed
into its virtual addressable space
The stack (subject of this chapter)
is used for procedure calls and
returns
The heap is used for dynamic
memory allocation
this is done by calling the OS at
run time (possibly via a library
function like malloc() or « new »
in C++)
2
Increasing addresses
The code is placed at the lowest
available address followed then by
the data
(high memory)
Heap
Stack
Data
Code
(low memory)
Runtime Stack
• Imagine a stack of plates . . .
• plates are only added to the top
• plates are only removed from the top
• LIFO structure
10
9
8
7
6
5
4
3
2
1
Irvine, Kip R. Assembly Language for x86 Processors 6/e, 2010.
top
bottom
3
The Stack
A stack of a certain size is allocated to every process
The stack is used for procedure calls and returns
It is also used by compilers for storing variables and arrays
But the stack size is fixed when the program is loaded in main
memory
The stack size cannot be changed at run time
There is always the risk of a stack overflow at run time (if too
much data are pushed onto the stack)
If this is the case, the process is terminated and the OS returns
a stack fault message
The default stack size is normally large enough for almost all
applications but the programmer can choose its size
4
Runtime Stack
• Managed by the CPU, using two registers
• SS (stack segment)
• ESP (stack pointer) *
Offset
00001000
00000006
ESP
00000FFC
00000FF8
00000FF4
00000FF0
* SP in Real-address mode
Irvine, Kip R. Assembly Language for x86 Processors 6/e, 2010.
5
Stack Operations:PUSH and POP Instructions
• PUSH syntax:
• PUSH r/m16
•
• PUSH r/m32
• PUSH imm32
• POP syntax:
• POP r/m16
•
• POP r/m32
Irvine, Kip R. Assembly Language for x86 Processors 6/e, 2010.
6
The PUSH Instruction
To push data onto the stack, we use:
PUSH source
The source operand can be either reg, mem, imm, (or
indirect) but it must be 16-bit or 32-bit in size.
Let S be the size (in bytes) of source (S = 2 or 4). The
following sequence of events will occur upon execution
of PUSH source:
ESP is first decremented by S
Data are always pushed underneath (from below),
since the stack is upside-down.
Then the content of source will be copied at the location
pointed by ESP
7
PUSH Example
Suppose that the stack size is 100h
and starts at address 0.
ESP thus contains 100h when the
stack is empty (the byte at address
100h is the top of the stack)
ESP
(Stack empty)
30h
FEh
40h
Must apply little endian when doing
push/pop
FDh
10h
By default, an imm operand of PUSH is
32-bit. This can be overridden by the
PTR operator:
FCh
20h
PUSH –1 ;FFFFFFFFh is
;pushed
PUSH word ptr –1
;FFFFh is pushed
PUSH byte ptr –1 ; error
PUSH qword ptr -1 ; error
FBh
30h
FAh
40h
MOV eax,10203040h
PUSH ax; S = 2 bytes
PUSH eax; S = 4 bytes
8
100h
FFh
Check now the stack and ESP after
each of these PUSH:
Addr STACK
ESP
After push ax
ESP
After push eax
PUSH Operation (1 of 2)
• A 32-bit push operation decrements the stack pointer
by 4 and copies a value into the location pointed to
by the stack pointer.
BEFORE
00001000
00000006
00000FFC
00000FFC
000000A5
00000FF8
00000FF8
00000FF4
00000FF4
00000FF0
00000FF0
00001000
•
AFTER
00000006
ESP
ESP
The stack is empty when ESP points at the physical top of the stack:
The physical top of the stack is the memory byte which immediately
follows the byte in the stack which is located at the largest available
address.
9
Irvine, Kip R. Assembly Language for x86 Processors 6/e, 2010.
PUSH Operation (2 of 2)
• Same stack after pushing two more integers:
Offset
00001000
00000006
00000FFC
000000A5
00000FF8
00000001
00000FF4
00000002
ESP
00000FF0
The stack grows downward. The area below ESP is always
available (unless the stack has overflowed).
The stack is full when ESP points at the physical bottom of the
stack: The physical bottom of the stack is the memory byte in
the stack which is located at the smallest available address.
10
Irvine, Kip R. Assembly Language for x86 Processors 6/e, 2010.
The POP Instruction
POP undoes the action of PUSH
To pop data from the stack, we use:
POP destination
The operand can be either reg, mem (or indirect) but it
must be 16-bit or 32-bit in size.
The operand cannot be imm
Let S be the size (in bytes) of destination (S = 2 or 4). The
following sequence of events will occur upon execution
of POP destination:
The word (if S=2) or dword (if S=4) located at the address
contained in ESP is first copied into the destination
operand
ESP is then incremented by S
11
POP Example
Addr STACK
Suppose that the stack is initially
100h
in the following state
i.e.: ESP contains FAh
Here is the stack and ESP after
each of these POP
POP eax; eax = 10203040h
POP ax ; ax = 3040h
POP ah ; error
Note that the data remains in the
stack: only ESP is changed
(incremented) at each POP
Nevertheless, the stack is said to
be empty when ESP points to the
top of the stack (here 100h)
12
ESP
After pop ax
FFh
30h
FEh
40h
FDh
10h
FCh
20h
FBh
30h
FAh
40h
ESP
After pop eax
ESP
(initially)
POP Operation
• Copies value at stack[ESP] into a register or variable.
• Adds n to ESP, where n is either 2 or 4.
• value of n depends on the attribute of the operand receiving the
data
BEFORE
AFTER
00001000
00000006
00001000
00000006
00000FFC
000000A5
00000FFC
000000A5
00000FF8
00000001
00000FF8
00000001
00000FF4
00000002
00000FF0
Irvine, Kip R. Assembly Language for x86 Processors 6/e, 2010.
ESP
ESP
00000FF4
00000FF0
13
Using PUSH and POP
Save and restore registers when they contain important values.
PUSH and POP instructions occur in the opposite order.
push esi
push ecx
push ebx
; push registers
mov
mov
mov
call
esi,OFFSET dwordVal
ecx,LENGTHOF dwordVal
ebx,TYPE dwordVal
DumpMem
; display some memory
pop
pop
pop
ebx
ecx
esi
; restore registers
Irvine, Kip R. Assembly Language for x86 Processors 6/e, 2010.
14
Ex: Saving and Restoring Registers
Some registers are
automatically used by certain
instructions. Example:
… … … ; initial EAX, ECX
;save registers
push eax
push ecx
EAX is used by ReadChar and ;read and print 3 chars
other instructions
ECX is used by LOOP and
mov ecx,3
other instructions
again:
call ReadChar ;
or al,20h ; up-to-low
The stack provides a convenient
call WriteChar
way for saving and restoring
loop again
registers that are needed
temporarily
Notice the particular order in
which PUSH and POP are
used
15
;restore registers
pop ecx
pop eax
… … … ; initial EAX, ECX
Example: Nested Loop
(Also, see Page 36 of Lecture 5)
When creating a nested loop, push the outer loop counter before
entering the inner loop:
mov ecx,100
L1:
push ecx
mov ecx,20
L2:
; set outer loop count
; begin the outer loop
; save outer loop count
; set inner loop count
; begin the inner loop
;
;
loop L2
; repeat the inner loop
pop ecx
loop L1
; restore outer loop count
; repeat the outer loop
Need not create a temporary variable as in Page 36 of Lecture 5
Irvine, Kip R. Assembly Language for x86 Processors 6/e, 2010.
16
Example: Reversing a String
• Use a loop with indexed addressing
• Push each character on the stack
• Start at the beginning of the string, pop the stack in reverse
order, insert each character back into the string
• Source code
• Q: Why must each character be put in EAX before it is pushed?
Because only word (16-bit) or doubleword (32-bit) values
can be pushed on the stack.
Irvine, Kip R. Assembly Language for x86 Processors 6/e, 2010.
17
Your turn . . .
• Using the String Reverse program as a starting
point,
• #1: Modify the program so the user can input a string
containing between 1 and 50 characters.
• #2: Modify the program so it inputs a list of 32-bit integers
from the user, and then displays the integers in reverse
order.
Irvine, Kip R. Assembly Language for x86 Processors 6/e, 2010.
18
Related Instructions
• PUSHFD and POPFD
• push and pop the EFLAGS register
• PUSHAD pushes the 32-bit general-purpose registers on
the stack
• Order of PUSH: EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI
• POPAD pops the same registers off the stack in reverse
order
• PUSHA and POPA do the same for 16-bit registers
Irvine, Kip R. Assembly Language for x86 Processors 6/e, 2010.
19
Inverting the Input Line INCLUDE Irvine32.inc
The stack is a last-in first-out
data structure
Items come off the stack in
the reverse order that they
came in
This program uses this
property to read a sequence
of characters and display
them in reverse order on the
next line
20
.code
main PROC
mov ecx,0; sets count to 0
mov eax,0
read_again:
call ReadChar
cmp al,0Dh; If ‘CR’ then ‘display’
je display
push ax ;push char 16-bit
inc ecx ;inc count
jmp read_again
display:
jecxz quit
again: ;prints ECX chars in reverse order
pop ax ;pop char 16-bit
call WriteChar
loop again
quit:
exit
main ENDP
END main
Exercise 1
We have the following data segment
msg WORD ‘a’,’b’,’c’,’d’
Suppose that, initially, ESP contains 100h. Give the hexadecimal
value contained in the mentioned registers after executing each
instruction in this particular sequence:
PUSH
MOV
PUSH
MOV
PUSH
LEA
POP
MOV
POP
POP
21
msg
ax,
msg+2
eax,
dword ptr
EAX,
word ptr
ax,
eax
ax
;ESP
[esp] ;AX
;ESP
[esp] ;EAX
msg+3 ;ESP
MSG
[eax] ;ESP
msg
;EAX
;EAX
;EAX
=
=
=
=
=
=
=
=
=
Your Turn . . .
• Write a program that does the following:
• Assigns integer values to EAX, EBX, ECX, EDX, ESI,
and EDI
• Uses PUSHAD to push the general-purpose registers
on the stack
• Using a loop, your program should pop each integer
from the stack and display it on the screen
Irvine, Kip R. Assembly Language for x86 Processors 6/e, 2010.
22
55 64 67 61 6E 67 65 6E
Irvine, Kip R. Assembly Language for x86 Processors 6/e, 2010.
23