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
(high memory)
The the code is placed at the lowest available address followed then by data
Heap
The stack (subject of this chapter) is used for procedure calls and returns
Stack
The heap is used for dynamic memory allocation
Data Code
this is done by calling the OS at run time (possibly via a library function like malloc() or « new » in C++)
(low memory)
2
Runtime Stack
• Imagine a stack of plates . . .
• plates are only added to the top • plates are only removed from the top • LIFO structure top 5 4 3 2 10 9 8 7 6 1 bottom Irvine, Kip R. Assembly Language for x86 Processors 6/e, 2010.
3
4
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 much data are pushed onto the stack) at run time (if too 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
Runtime Stack
• Managed by the CPU, using two registers • SS (stack segment) • ESP (stack pointer) * Offset
00001000 00000FFC 00000FF8 00000FF4 00000FF0 00000006
ESP * 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)
Addr
STACK
100h FFh
30h
Check now the stack and ESP after each of these PUSH: MOV eax,10203040h PUSH ax; S = 2 bytes PUSH eax; S = 4 bytes
Must apply push/pop little endian when doing
FEh FDh
40h 10h ESP (Stack empty)
ESP
After push ax
FCh
20h
8
By default, an imm operand of PUSH is 32-bit. This can be overridden by the PTR operator: PUSH –1 ;FFFFFFFFh is ;pushed PUSH word ptr –1 ;FFFFh is pushed PUSH byte ptr –1 ; error PUSH qword ptr -1 ; error
FBh FAh
30h 40h
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 00000FFC 00000FF8 00000FF4 00000FF0 00000006
ESP AFTER
00001000 00000FFC 00000FF8 00000FF4 00000FF0 00000006 000000A5
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 00000FFC 00000FF8 00000FF4 00000FF0
00000006 000000A5 00000001 00000002 ESP 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.
Irvine, Kip R. Assembly Language for x86 Processors 6/e, 2010.
10
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 11
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
POP Example
Addr
Suppose that the stack is initially in the following state
i.e.: ESP contains FAh
100h FFh
Here is the stack and ESP after each of these POP POP eax; eax = 10203040h POP ax ; ax = 3040h POP ah ; error
FEh FDh FCh
12
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)
FBh FAh
STACK 30h 40h 10h 20h 30h 40h
ESP
After pop ax
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
00001000 00000FFC 00000FF8 00000FF4 00000FF0 00000006 000000A5 00000001 00000002
ESP AFTER
00001000 00000FFC 00000FF8 00000FF4 00000FF0 00000006 000000A5 00000001
ESP Irvine, Kip R. Assembly Language for x86 Processors 6/e, 2010.
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 mov esi,OFFSET dwordVal mov ecx,LENGTHOF dwordVal mov ebx,TYPE dwordVal call DumpMem pop ebx pop ecx pop esi ; push registers ; display some memory ; 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
15 EAX is used by ReadChar and other instructions
;read and print 3 chars
The stack provides a convenient way for saving and restoring registers that are needed temporarily
ECX is used by LOOP and other instructions Notice the particular order in which PUSH and POP are used
mov ecx,3 again: call ReadChar ; or al,20h ; up-to-low call WriteChar loop again ;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:
L1: mov ecx,100 push ecx L2: mov ecx,20 ; ; loop L2 pop ecx loop L1 ; set outer loop count ; begin the outer loop ; save outer loop count ; set inner loop count ; begin the inner loop ; repeat the inner loop ; 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 .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: quit: exit main ENDP END main ;prints ECX chars in reverse order pop ax ;pop char 16-bit call WriteChar loop again
20
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 msg MOV ax, PUSH msg+2 MOV eax, PUSH dword ptr msg+3 ;ESP = LEA EAX, MSG POP MOV POP word ptr ax, eax ;ESP = [esp] ;EAX = [eax] ;ESP = msg ;EAX = ;EAX = POP ax ;ESP = [esp] ;AX = ;EAX =
21
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