|
Writing MacrosAs you are working you will find that you have to type (and document) the same lines of code over and over. To simplify your task you may create macros. Macros are similar to the preprocessor in C or C++. When you assemble a source file, all macros are expanded. This can lead to large files when you are done compiling. Typically you will want to use procedures for blocks of code that are repeated often. However, for a block of code that is only used once in a program, but you need in every program you write, you may want to create a macro file like the following. The other time you may want to have macros is where you have written a procedure, but setting up the stack to pass the parameters is tedious. In this case, a macro with several parameters is probably your best route. I will give you an example of how to set up a macro with parameters to call a procedure that will print a string to the screen later on in the course. For now you can start to work on your own macros. Remember, the macros provided in the book are much to complex for this course, and may not be used in the projects. You may write your own versions of those in the books.
TITLE IO.MAC
;=======================================================================
; ExitProgram () -- Terminates current application
; PreCond -- None
; PostCond -- Nothing (no registers modified)
; Notes -- Assumes nothing about our current segment
;=======================================================================
ExitProgram MACRO
mov ax, 4c00h ;standard exit code
int 21h
ENDM
So if we combine this with our hello world program we would write it as
TITLE hi_world.asm
;=======================================================================
; Hello World application - prints "Hello World" to the screen
;=======================================================================
include io.mac
;Some Useful Constants
STDIN EQU 0
STDOUT EQU 1
STDERR EQU 2
LF EQU 0Ah
CR EQU 0Dh
_DATA SEGMENT USE16 BYTE PUBLIC 'DATA'
myString DB "Hello World", CR, LF, "$"
_DATA ENDS
_TEXT SEGMENT USE16 WORD PUBLIC 'CODE'
ASSUME cs:_TEXT, ds:_DATA
Start:
mov ax, _DATA ; set DS to point to our data segment
mov ds, ax
mov ah, 09h ; function: print string $ terminated
mov dx, OFFSET myString ; pointer to string
int 21h
ExitProgram
_TEXT ENDS
_STACK SEGMENT USE16 STACK 'STACK'
DW 100 dup(?)
_STACK ENDS
END Start
One last point to bring up here. If you are using labels (for jumping) in a macro, think about what is going to happen. The assembler blindly substitutes a copy of your macro code at each point you use it. If you have a label in your macro it is going to be copied with the same name each time. To avoid this problem look into the LOCAL directive (used within a macro or procedure) or the LOCALS keyword (applies to your entire file). Both of these typically use the @ symbol as the first character of their name. These can get really fancy (don't waste time on it), but you are welcome to use them. Last Modified: January 26, 1999 - Barry E. Mapen |