Stack, Procedures and Macros

advertisement
Stack and Subroutines
Outline
o
o
o
o
o
Stack organization
PUSH and POP instructions
Calling procedures
Macros
Programming guidelines
The stack
o Space used as temporary storage during the
execution of the program
o Purpose:
o saving the return address when calling
procedures
o saving the contents of registers used in
procedures
o pass parameters to procedures
o allocate memory for local variables in
procedures
Contd…
The stack
o A single access point. LIFO data structure
o Data is always accessed from the “top” of the
stack
o Insert is done by “pushing” data to the top of the
stack
o Delete is done by “popping” data from the top of
the stack
Stack layout in memory
Original SP
Direction of
increasing
memory
addresses
In use
In use
In use
In use
In use
In use
Free
Free
Free
Free
Stack grows in
direction of
decreasing
memory
addresses
SS:SP
SS
Stack layout in memory
o SS – Stack segment points to the beginning of the
stack segment
o SP – points always to the top of the stack
o SP is decreased when data is pushed. E.g. if we
push a word SP is decreased by 2
o SP is increased when data is popped. E.g. is we
pope a word SP is popped by 2
o BP can point to any element in the stack
o Remember that BP is the register that you use in
your programs to access data from the stack
Push example
To
address
12FFF
Register array
AX
BX
CX
DX
6AB3
SP
0800
SS
0300
PUSH BX
6A
B3
03800
037FF
037FE
03000
Stack segment
Pop example
To
address
0FFFF
Register array
AX
BX
CX
DX
392F
SP
1006
SS
0000
POP BX
39
2F
01008
01007
01006
00000
Stack segment
PUSH and POP
o Instructions to access the stack
o PUSH and POP always store/load words not bytes
o In 386 and above you can also push/pop
doublewords
o PUSH X
o X can be immediate data, 16-bit register,
segment register or 2 bytes of memory
o POP X
o X can be 16-bit register, segment register except
CS and memory location
PUSHA and POPA
o In 286 and later it is possible to push/pop the entire
set of general purpose registers
o AX,BX,CX,DX,SP,BP,SI,DI
Stack Initialization
o Let’s assume that we decide to use 64 Kbytes for
the stack starting at address 10000h
o We set SS=1000h and SP=0000h
o 64K cover addresses from 10000h to 1FFFFh
o First PUSH decrements SP by 2 (0000h-2=FFFEh),
data is stored in 1FFFFh and 1FFFEh
Using the stack
o Storing
o Return address when a procedure is called
o Preserve the contents of registers
o Local variables required by procedures
o Dynamically allocated memory
o Pass
o Parameters passed to procedures
Why preserving
registers
o Registers are global variables in principle
o Registers can also be used as temporary storage in
a procedure
o If a procedure needs to use registers as temporary
storage and these registers contain “useful” global
variables, their contents must be preserved
o The first instructions in the procedure should take
care of this
Example:
preserving registers
PUSH AX
; Place AX on the stack
PUSH BX
; Place BX on the stack
PUSH CX
; Place CX on the stack
PUSH DX
; Place DX on the stack
PUSH SI
; Place SI on the stack
PUSH DI
; Place DI on the stack
; code that modifies AX,BX,CX,SI,DI
POP DI
; Restore original value of DI
POP SI
; Restore original value of SI
POP DX
; Restore original value of DX
POP CX
; Restore original value of CX
POP BX
; Restore original value of BX
POP AX
; Restore original value of AX
Calling procedures
and using the stack
o call proc_name
o Pushes the instruction pointer (IP)
o Pushes CS to the stack if the call is to a
procedure outside the code segment
o Unconditional jump to the label proc_name
o ret
o Pop saved IP and if necessary the saved CS and
restores their values in the registers
Procedure example
..start
mov ax, 10h
mov bx, 20h
mov cx, 30h
mov dx, 40h
call AddRegs
call DosExit
AddRegs
add ax, bx
add ax, cx
add ax, dx
ret
;this proc does AX + BX + CX + DX  AX
Direct access
to the stack
o PUSH/POP/CALL/RET modify the SP
o When you need to access variables in the stack you
need to manipulate the BP
o Example: access the third word from the top of
stack and return result in AX
PUSH BP
; Can you tell why ?
MOV BP, SP
ADD BP, 4
MOV AX, [BP]
o When you need to allocate/deallocate memory in
the stack you manipulate directly the SP
Procedures at a glance
o Procedures can access global variables declared at
the beginning of the program
o Procedures can access global variables stored in
registers
o Procedures may have parameters passed to them
o Registers with global variables is a form of
parameter passing
o Pushing parameters to the stack is another form
of parameter passing
o Procedures may need to preserve registers
o Procedures may return results to the caller in
registers or write results in memory
Guidelines for MP1
o There should be a one-to-one match between push
and pop
o The first pop is matched with the last push
o Some of the functions you need to implement return
values to memory and some return values in
registers
o PlayerStats [player1], [player2],[player3]
o NewPlay, bx=1,2, or 3 of 3 player created
o Do not push and pop registers that will store return
values
Macros
o Procedures have some extra overhead to execute
(call/ret statements, push/pop IP, CS and data from
the stack)
o A macro is a piece of code which is
“macroexpanded” whenever the name of the macro
is encountered
o Note the difference, a procedure is “called”, while a
macro is just “expanded/inlined” in your program
o Macros are faster than procedures (no call
instructions, stack management etc.)
o But they might
o Significantly increase code size
o Hard to debug
Macro format
%macro MACRO_NAME num_args
;
; your code, use %{1} to access the first
; argument, %{2} to access the second
; argument and so on
%end macro
Macro example
%macro DIV16 3 ; result=x/y
MOV AX, %{2} ; take the dividend
CWD
; sign-extend it to DX:AX
IDIV %{3}
; divide
MOV %{1},AX ; store quotient in result
%endmacro
Macro example
; Example: Using the macro in a program
; Variable Section
varX1
DW
20
varX2
DW
4
varR
RESW
; Code Section
DIV16 word [varR], word [varX1], word [varX2]
; Will actually generate the following code inline in your
; program for every instantiation of the DIV16 macro (You
; won’t actually see this unless you debug the program).
; MOV AX, word [varX1]
; CWD
; IDIV word [varX2]
; MOV word [varR], AX
Organizing your program
o Create a block diagram or pseudocode of your
program in paper
o Control flow
o Data flow
o Break the program into logical “components” that
can be easily translated to procedures in your code
o Use descriptive names for variables
o Noun_type for types
o Nouns for variables
o Verbs for procedures
Organizing your program
o Modular program organization helps debugging
o Makes it easier to ‘isolate’ the bug in a single
procedure
o All (Microsoft) programs contain bugs!
o This is overstated…
o It really means that you shouldn’t expect your
program to work the first time you run it…
o …but you shouldn’t feel bad about it either, relax
and trace the bug
Tracing bugs
o The debugging process:
o Set breakpoints in your programs and use them
as checkpoints for checking the contents of
registers/memory
o Comment out code, this might help you find out
whether the commented out code contains the
bug
o Use print statements (and you might not need the
debugger!)
o Display the values of critical data
o Display the status of the program
Tracing bugs
o Force registers and variables to test the output of
the procedure
o Helps you debug the procedure using as many
inputs as possible
o If everything else fails
o Test your logic
o Change your algorithms
Procedures
o Labeled sections of code that you can jump to or
return from any point in your program
o A procedure in your assembler is merely a nondotted label
o Use dotted labels if you want to set jump points
within a procedure (local labels)
NASM directives
o EXTERN, references to procedures defined in other
files (e.g. libraries)
o GLOBAL, makes your procedures available to other
files, e.g. if you are writing a library
o SEGMENT defines segments
o SEGMENT stack
o SEGMENT code
Example of
program structuring
; ECE291:MPXXX
; In this MP you will develop a program which take input
; from the keyboard
;====== Constants
============================================
=====
;ASCII values for common characters
CR
EQU 13
; EQU’s have no effect on
memory
Contd…
Example of
program structuring
LF
EQU 10
directives only
ESCKEY EQU 27
assembled
; They are preprocessor
; LF gets replace with 10 when
;====== Externals
============================================
=====
; -- LIB291 Routines
extern dspmsg, dspout, kbdin
extern rsave, rrest, binasc
Example of
program structuring
;==== LIBMPXXX Routines (Your code will replace calls to
these ;functions)
extern LibKbdHandler
extern LibMouseHandler
extern LibDisplayResult
extern MPXXXXIT
;====== Stack
============================================
========
Contd…
Example of
program structuring
stkseg segment STACK ; *** STACK SEGMENT ***
resb 64*8
; 64*8 = 512 Bytes of Stack
stacktop:
;====== Begin Code/Data
==========================================
codeseg
segment CODE
; *** CODE
SEGMENT ***
Example of
program structuring
;====== Variables
===========================================
===
inputValid
db 0
; 0: InputBuffer is not ready
; 1: InputBuffer is ready
;-1: Esc key pressed
operandsStr db 'Operands: ','$'
OutputBuffer 16 times db 0
; Contains formatted
output
db ‘$’
; (Should be terminated with '$')
Contd…
Example of
program structuring
MAXBUFLENGTH
EQU 24
InputBuffer
MAXBUFLENGTH times db 0
; Contains one line of user input
db ‘$’
graphData
%include “graphData.dat” ; data
GLOBAL outputBuffer, inputValid, operandsStr
GLOBAL graphData
Example of
program structuring
;====== Procedures
===========================================
KbdHandler
<Your code here>
MouseHandler
<Your code here>
DisplayResult
<Your code here>
Contd…
Example of
program structuring
;====== Program Initialization
===============================
..start:
mov ax, cs
; Use common code & data
segment
mov ds, ax
mov sp, stacktop
; Initialize top of stack
Example of
program structuring
;====== Main Procedure
========================================
MAIN:
MOV AX, 0B800h ;Use extra segment to access
video
MOV ES, AX
<here comes your main procedure>
CALL
MPXXXXIT
; Exit to DOS
Download