Lecture[9] - Chapter 3 Stack Management and procedures
Lecture[9] - Chapter 3 Stack Management and procedures
Lecture 9
Chapter 3 : Stack
Management &
Procedures The Intel 8086
Outline
3
What is a Stack?
Stacks provide a new way to access data in main memory
They are used to store temporary values
A stack consists of
Memory area and a
Pointer which keeps the address of the top of stack
Stack is a Last-In-First-Out (LIFO) data structure
Analogous to a stack of plates in a cafeteria
Plate on Top of Stack is directly accessible
Two basic stack operations
Push: Inserts a new element on top of the stack
Pop: deletes top element from the stack
Stack can be viewed as a linear array of elements
Insertion and deletion is restricted to one end of the array
Stack must have a maximum capacity, so
When stack is full, no element should be pushed
When stack is empty, no element should be popped
4
8086 Runtime Stack
Runtime stack:
Array of successive memory locations managed by the processor
using two registers
1. Stack Segment register SS
2. Stack Pointer register SP
SP register points to the top of stack
Always points to last data item placed on the stack
5
Runtime Stack Allocation
Operating system allocates memory area for the stack
Runtime stack is initially empty
SP is initialized by the operating system and automatically modified by
the processor with PUSH, POP, RET and CALL instructions
The current address pointed by SS:SP is the top of the Stack
The stack grows downwards toward lower memory addresses
SP is decremented to allocate stack memory
16 BITS
High Address
Full Space
POP SP
PUSH SP-2
Free Space
Low Address
6
Stack Instructions
Two basic stack instructions:
PUSH source
POP destination
Source can be
General-purpose register
Segment register: CS, DS, SS, ES
Memory operand (memory-to-stack transfer is
allowed)
Destination can be
General-purpose register
Segment register, except that “POP CS” is NOT
allowed
Memory operand (stack-to-memory transfer is 7
Push Instruction
PUSH source
1. SP is first decremented by 2
SP = SP – 2 (stack grows by 2 bytes)
2. 16-bit source is then copied onto the stack at the new SP :
stack source ([SP] = source)
Operating system puts a limit on the stack capacity
Push can cause a Stack Overflow (stack cannot grow)
MOV AX,86
PUSH AX
MOV AX,70 SP 45 300
PUSH AX SP 86 298
SP 70 296
S 298
300
296
P 8
Examples on the Push Instruction
• Suppose we execute: The stack grows
– PUSH AX ; AX = 80FFh downwards
– PUSH BX ; BX = 2Eh The area below SP is
– PUSH CX ; CX = B61Dh free
BEFORE AFTER
2FFB4 SP 2FFB4
2FFAD 2FFAD
9
Pop Instruction
POP destination
1. 16-bit word at SP is first copied into destination
destination Stack (destination = [SP])
2. SP is then incremented by 2
SP = SP + 2 (stack shrinks by 2 bytes)
Popping from an empty stack causes a stack underflow
POP AX
POP BX
SP 45 300
A 7
SP 86 298
X 0
B 8 SP 70 296
X 6
S 298
300
296
P 10
Examples on the Pop Instruction
BEFORE AFTER
2FFB4 2FFB4
2FFAD 2FFAD
11
Stack & code Location
The stack and the program grow in the opposite direction to
decrease the risk of collision between the code and the Stack in
the case where they are placed in the same segment (SS = CS)
Separate Single
Segments Segments
FFFF
FFFF SP
IP
Stack growth
Code growth SP
CS IP
0000
0100
SP IP
Stack growth Code growth
SS SP ES SS DS CS IP
0000 0000
12
Uses of the Runtime Stack
Runtime Stack can be utilized for
Temporary storage of data and registers
Transfer of program control in procedures and
interrupts
Parameter passing during a procedure call
Allocating local variables used inside procedures
13
Example: Temporary Storage of Registers
Example on moving BX to AX
PUSH BX
POP AX
This example is equivalent to MOV AX,BX, is not very useful, it is
better to use MOV AX,BX.
The Stack is often used to temporarily save the contents of registers
Push and Pop are especially useful because we don’t have too
much registers to operate with, so
Stack is often used to free a set of registers
PUSH BX ; save BX
PUSH CX ; save CX
. . .
MOV BX,adr ; BX and CX can now be
modified
ADD CX,[Bx]
. . .
POP CX ; restore CX first, then
POP BX ; restore BX 14
Example: Nested Loop
When writing a nested loop, push the outer loop counter CX
before entering the inner loop, and restore CX after exiting the
inner loop and before repeating the outer loop
MOV CX,100 ; set outer loop count
L1: . . .; begin the outer
loop
PUSH CX ; save outer loop count
. . . ; outer loop
POP CX ; restore outer loop
count
LOOP L1 ; repeat the outer loop
15
Push/Pop All Registers & Flags
PUSHA
Pushes all the general-purpose registers
AX, CX, DX, BX, SP, BP, SI, and DI in this order
Initial SP value is pushed
SP = SP – 16
POPA
Pops into registers DI through AX in reverse order of PUSHA
SP is not read from stack. It is computed as: SP = SP + 16
PUSHF & POPF
Special Stack instructions for pushing and popping flags
Useful for saving and restoring the flags
16
Declaring a Stack
To use a Stack in assembler, you must declare a stack segment,
and reserve sufficient space.
It is necessary to initialize the SS and SP registers to point the
top of the stack.
Exemple Stack declaration of 200 bytes
18
Procedures
A procedure is a logically self-contained unit of code
Called sometimes a function, subprogram, or subroutine
Receives a list of parameters, also called arguments
Performs computation and returns results
Plays an important role in modular program development
Example of a procedure (called function) in C language
int sumof ( int x,int y,int z ) {
Result type int temp; Formal parameter list
temp = x + y + z;
return temp; Return function result
}
The above function sumof can be called as follows:
sum = sumof( num1,num2,num3 );Actual parameter list
19
Defining a Procedure in Assembly
Assembler provides two directives to define procedures
PROC to define name of procedure and mark its
beginning
ENDP to mark end of procedure
A typical procedure definition is
procedure_name PROC
. . .
; procedure body
. . .
procedure_name ENDP
20
Example of a Procedure Definition
The sumof procedure calculates the sum of three
integers, receives three integer parameters
Assumed to be in AX, BX, and CX
Computes and returns result in register AX
sumof PROC
add AX, BX ; AX = AX + second number
add AX, CX ; AX = AX + third number
ret ; return to caller
sumof ENDP
21
The Call Instruction
To invoke a procedure, the CALL instruction is used
The CALL instruction has the following format
CALL procedure_name
Example on calling the procedure sumof
Caller passes actual parameters in AX, BX, and CX Before
calling procedure sumof
23
Details of CALL and Return
;Address Assembly Language
main PROC
1020 Mov AX,num1 S FFC2
FFC4
1025 Mov BX,num2 P
102B Mov CX,num3 I 1036
1031
1085
1083
1081
1031 Call sumof P
1036 Mov sum,AX
. . . . . .
main ENDP
SP 45 FFC4
sumof PROC SP 1036 FFC2
1081 Add AX,BX
1083 Add AX,CX
1085 Ret
sumof ENDP
Sub1 PROC
. return address of call Sub1
.
call Sub2
ret return address of call Sub2
Sub1 ENDP
return address of call Sub3 SP
Sub2 PROC
.
.
call Sub3
ret
Sub2 ENDP
Sub3 PROC
.
.
ret
Sub3 ENDP
26
Parameter Passing
Parameter passing in assembly language is different
More complicated than that used in a high-level
language
In assembly language Two types of storage areas are used
Registers: general-purpose registers are used (register
method)
Memory: stack is used (stack method)
27
Passing Parameters : Register method
Place all required parameters in a general purpose
registers
Then call the procedure
A simple method, but is suitable only with a small number
of Parameters (there is little registers)
main PROC
mov AX, num1
Example mov BX, num2
The sum calculates the sum of two integers. call sum
The two numbers are placed in registers AX mov sum, AX
and BX, the result is placed in AX ………
main ENDP
sum PROC
add AX, BX
Ret
sum ENDP
28
Passing Parameters : Stack method
This technique uses a new register, BP (Base Pointer), which can read
values on the stack without popping (without changing SP)
main PROC
PUSH num1
FFFE PUSH num2
SP 45 CALL sum
BP+6 SP num1 FFFC Mov sum, AX
………
BP+4 SP num2 FFFA main ENDP
SP RA FFF8
BP SP Old BP FFF6
sum PROC
PUSH BP
MOV BP, SP ; top of the Stack
S FFFE
FFFC
FFFA
FFF6
FFF8 MOV AX, [BP+4] ; load the 2nd arg
ADD AX, [BP+6] ; add the 1st arg
P POP BP
A num2+num1
num2 RET 4
sum ENDP
X
• It’s more flexible than register method
• A well-written procedure modifies as little as possible the registers (save then restore BP in)
29
Preserving Registers
Need to preserve the registers across a procedure call
Stack can be used to preserve register values
Which registers should be saved?
Those registers that are modified by the called procedure, but
still used by the calling procedure
We can save all registers using PUSHA if we need most of
them
However, it is better to save only needed registers
Who should preserve the registers?
Calling procedure: saves and frees registers that it uses
Registers are saved before procedure call and restored after
return
Called procedure: preferred method for modular code
30
Example on Preserving Registers
;-----------------------------------------------------
; ArraySum: Computes the sum of an array of integers
; SI = pointer to an array of words
; CX = number of array elements
; AX = result
;-----------------------------------------------------
ArraySum PROC
push si ; save si, it is modified
push cx ; save cx, it is modified
mov ax,0 ; set the sum to zero
L1: add ax, [si] ; add each integer to sum
add si, 2 ; point to next integer
loop L1 ; repeat for array size
pop cx ; restore registers
pop si ; in reverse order
ret
ArraySum ENDP No need to save AX. Why?
31
Summary
Procedure – Named block of executable code
CALL: call a procedure, push return address on top of stack
RET: pop the return address and return from procedure
Preserve registers across procedure calls
Runtime stack – LIFO – Grows downwards
Holds return addresses, saved registers, etc.
PUSH – insert value on top of stack, decrement SP
POP – remove top value of stack, increment SP
32