Procedures and Macros - PowerPoint PPT Presentation

1 / 30
About This Presentation
Title:

Procedures and Macros

Description:

takes the address of the procedure in memory as an operand ... or cx, cx ; check counter value. jz QUIT ; quit if zero. add ax, cx ; ow, add to sum ... – PowerPoint PPT presentation

Number of Views:108
Avg rating:3.0/5.0
Slides: 31
Provided by: anniegro
Category:

less

Transcript and Presenter's Notes

Title: Procedures and Macros


1
Procedures and Macros
  • CS227
  • Western Washington University

2
Procedures
  • Why?
  • To avoid writing the same sequence of
    instructions every time you need them
  • Code readability and clarity
  • Top-down design
  • How?
  • CALL instruction
  • RET instruction

3
The CALL Instruction
  • CALL print_char
  • takes the address of the procedure in memory as
    an operand
  • stores the current value contained in IP on the
    stack
  • this is the return address, because it is the
    address of the instruction to be executed after
    completing the procedure
  • this is accomplished by subtracting 2 from the SP
  • loads the instruction pointer with the starting
    address of the procedure

4
Calling Mechanisms
  • intra-segment NEAR call
  • the procedure being called is in the same segment
  • inter-segment FAR call
  • the procedure being called is in another segment
  • both NEAR and FAR calls can be direct or indirect
  • direct - adds the 16-bit signed displacement to
    the IP
  • indirect - the instruction pointer is replaced
    with the 16-bit value from a specified register
    or memory location

5
The RET Instruction
  • copies the word at the top of the stack,
    hopefully the value of the instruction pointer,
    from the stack back to the IP
  • this returns execution to the caller of the
    procedure
  • for a return from a far procedure, it also needs
    to pop the value of the CS register
  • it does this by incrementing the SP by 2 and copy
    the word starting there into CS
  • the assembler automatically codes a near RET for
    a near PROC and a far RET for a far PROC

6
The Stack
  • the stack is a segment of memory used for
  • storing return addresses
  • saving the contents of registers for the calling
    program
  • hold data or addresses that will be used by the
    procedure
  • recall the SS and the SP registers
  • SS holds the value of the upper 16 bits of the
    starting address of the stack segment
  • SP holds the value of the offset of the last word
    written to the stack

7
Using the Stack
  • To write a word to the stack - PUSH
  • the SP register is decremented by 2
    automatically, before writing the word to the
    stack
  • soyou need to initialize the SP register to the
    top of the memory you have set aside as the stack
    segment, rather than the bottom
  • Retrieve a word from the stack - POP
  • the word starting at SP is copied to the
    specified destination
  • the SP register is incremented by 2 automatically

8
An Example
  • Assume SS 7000H and SP 0050H
  • 001D CALL foo
  • 0020
  • SP gets decremented by 2
  • the word 0020H is written to the memory locations
    starting at (SS SP) 7004EH
  • RET is executed
  • word starting at SP is popped into the IP
    register automatically
  • SP incremented, so SP 0050H, which is the top
    of the stack

9
Instructions to set up a stack
  • STACK_SEG SEGMENT STACK
  • DW 40 DUP(0)
  • STACK_TOP LABEL WORD
  • STACK_SEG ENDS
  • CODE SEGMENT
  • Assume CSCODE, SSSTACK_SE
  • MOV AX, STACK_SEG Initialize stack
  • MOV SS, AX segment register
  • LEA SP, STACK_TOP Initialize
  • stack pointer
  • CODE ENDS
  • END

10
Checklist
  • Declare the stack segment
  • STACK_SEG SEGMENT STACK
  • STACK_SEG ENDS
  • Declare the size of the stack
  • DW 40 DUP(0) this stack is 40 words big
  • Attach a name to the highest location in the
    stack
  • STACK_TOP LABEL WORD
  • this declares STACK_TOP as a label to the next
    even address after the words set aside for the
    stack
  • Inform the assembler that you are using a stack
  • ASSUME SSSTACK_SEG
  • Initialize the SS register
  • MOV AX, STACK_SEG
  • MOV SS, AX
  • Initialize the SP register
  • LEA SP, STACK_TOP

11
Writing a Procedure
  • WAIT_1MS PROC NEAR
  • MOV CX, 23F2H
  • HERE
  • LOOP HERE
  • RET
  • WAIT_1MS ENDP
  • WAIT_1MS is the name of the procedure specified
    by PROC
  • its a near procedure specified by NEAR
  • ENDP specifies the end of the procedure

12
PUSH POP
  • PUSH register/memory
  • decrements the SP by 2
  • copies the contents of the 16-bit register or
    memory location to memory at the new SP location
  • you can PUSH
  • any 16-bit general purpose register
  • any of the base or pointer registers
  • any of the segment registers
  • any word from memory
  • POP register/memory
  • copies a word from the TOP to the specified
    16-bit register or memory location
  • increments SP by 2
  • you can POP
  • to any register, except CS
  • to any memory location

13
A Stack Map
  • Shows diagrammatically the effects of a set of
    instructions on the stack and SP
  • MULTO PROC NEAR
  • PUSHF
  • PUSH AX
  • PUSH BX
  • PUSH CX
  • POP CX
  • POP BX
  • POP AX
  • POPF
  • RET
  • MULTO ENDP

14
Preserving Registers
  • Whose responsibility is it anyway?
  • The callee (procedure being called)
  • preferred
  • it knows exactly which registers it needs to use
  • less clutter in main program
  • independent of which registers are used by
    caller
  • The caller (calling program or procedure)

15
Passing Parameters
  • Passing in Registers
  • move the parameter to a register, and do not push
    that register onto the stack
  • Passing in General Memory
  • directly access the parameters by name
  • MOV AL, SOME_VAR
  • Passing using Pointers
  • copy the address of the parameter to a register,
    usually SI or DI before calling the procedure
  • LEA SI, SOME_VAR
  • Passing using the Stack
  • push the parameters on the stack before calling
    the procedure
  • use the BP register as a second pointer into the
    stack

16
Problems with Each Method
  • Passing in registers
  • the number of registers is limited
  • Passing in general memory
  • always using the same memory location
  • Passing using pointers
  • most versatile, because you can pass pointers to
    anywhere in memory
  • Passing using the stack
  • can be difficult to maintain the stackstack
    overflow
  • can use RET ltsome constantgt

17
Choosing a Method
  • For simple procedures with few parameters...
  • use registers
  • When dealing with arrays
  • use a register to store starting address
  • Globals are bad even in assembly
  • this is the case where you are directly accessing
    a memory location
  • For procedures that will be called from a high
    level language program, or recursive procs
  • use the stack

18
Reentrant Procedures
  • A reentrant procedure can be interrupted, used,
    and then re-entered without losing or overwriting
    anything useful
  • To be reentrant
  • a procedure must push the flags and registers
    onto the stack before doing anything else
  • a procedure should use only the registers or the
    stack to pass parameters

19
Why is reentrancy important?
  • Normal program execution can be interrupted with
    instructions to call a specified procedure
  • this is an interrupt service procedure
  • The interrupt service procedure could call the
    procedure that was executing when the interrupt
    occurred
  • if were using the stack correctly, there are no
    problems
  • if were directly using memory locations, were
    in trouble!

20
Recursive Procedures
  • A recursive procedure is a procedure that calls
    itself. It is useful for specific applications,
    such as trees
  • We can compute the sum of a the first n integers
    using a recursive procedure.
  • recursive sum example
  • cx will hold the counter,
  • ax will hold the sum
  • main proc
  • mov cx, 5
  • xor ax, ax
  • call sum
  • mov ax, 4c00h
  • int 21h
  • main endp

21
sum proc or cx, cx check counter value jz
QUIT quit if zero add ax, cx ow, add
to sum dec cx decrement counter call
sum recursive call QUIT ret sum
endp Factorial is a much more challenging
recursive routine to write. if n 1 then
factorial 1 else factorial n (factorial of
(n - 1))
22
factorial proc push bp mov bp, sp mov
ax, bp4 get n cmp ax, 1 n lt 1? ja
RECUR no continue mov ax, 1 yes return
1 jmp EXIT RECUR dec ax push ax
factorial(n-1) call factorial mov bx,
bp4 get n mul bx ax ax bx EXIT
pop bp ret 2 ax result factorial
endp How would you use this factorial procedure?
23
Writing Calling Far Procedures
  • Writing
  • PROCEDURES SEGMENT
  • MULTIPLY_32 PROC FAR
  • ASSUME CSPROCEDURES
  • NOP
  • RET
  • MULTIPLY_32 ENDP
  • PROCEDURES ENDS
  • Calling
  • the assembler takes care of translating a far
    procedure call

24
Using Multiple Assembly Units
  • You can create a program that is made up of
    multiple assembly units
  • can write each module and assemble, test, and
    debug as a unit
  • then you link all the obj files from the modules
    into an executable file
  • You need to use some new keywords
  • PUBLIC
  • EXTRN

25
PUBLIC EXTRN
  • SMART_DIVIDE.ASM
  • PUBLIC SMART_DIVIDE
  • PROCEDURES SEGMENT PUBLIC
  • SMART_DIVIDE PROC FAR
  • ASSUME CSPROCEDURES, DSDATA
  • SMART_DIVIDE ENDP
  • PROCEDURES ENDS
  • END
  • MAIN_PROG.ASM
  • PROCEDURES SEGMENT PUBLIC
  • lets the assembler know that
  • EXTRN SMART_DIVIDE FAR
  • smart_divide is of type far proc
  • PROCEDURES ENDS
  • and is located in the code
  • segment named procedures

26
More on PUBLIC
  • Make a segment PUBLIC whenever you want it to be
    linked with other segments of the same name in
    other modules
  • this has the effect of concatenating the segments
    in successive memory locations
  • Make a procedure PUBLIC when you want it to be
    called by other assembly modules
  • PUBLIC sampleProc
  • sampleProc proc
  • sampleProc endp
  • Make a variable PUBLIC whenever you want it to be
    accessible from other assembly modules
  • PUBLIC DIVISOR

27
More on EXTRN
  • Use EXTRN to tell the assembler that the data
    item is not in the present module
  • EXTRN SMART_DIVIDEFAR
  • EXTRN DIVISORWORD
  • Other possibilities include
  • PROC, ABS, NEAR, BYTE
  • Enclose the EXTRN statement within
  • SEGMENT_NAME SEGMENT PUBLIC
  • SEGMENT_NAME ENDS
  • this tells the assembler and linker where the
    data item is located
  • This is not necessary when using the .code
    directive

28
Macros
A macro is a symbolic name given to a sequence of
one or more assembly instructions. This is
similar to a define in C or an inlined function
in C. Once a macro is defined, it can be
invoked anywhere throughout your code. Why
use macros when you can write procedures? Macros
can be executed more quickly. No CALL
instruction is generated, so no status
information needs to be saved. Why not use
macros all the time then? Since the instructions
associated with a macro are directly inserted
into the code, the program size will expand
accordingly.
29
Macro Syntax
A macro is defined using the MACRO directive and
the ENDM directive. mPutchar macro begin
macro mov ah, 2 int 21h endm end
macro Notice the use of for comments.
This simply prevents the comment being inserted
as part of the expanded instructions. To
invoke a macro, simply write the name of the
macro .code mov dl, a mPutchar
30
Parameters
Macros have an advantage over procedures in that
parameters can be specified for macros. mPutchar
macro char push ax push dx mov ah, 2
mov dl, char use parameter int 21h pop
dx pop ax endm .code mPutchar a
Write a Comment
User Comments (0)
About PowerShow.com