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