Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Assembly Language Step by Step 1992

.pdf
Скачиваний:
145
Добавлен:
17.08.2013
Размер:
7.98 Mб
Скачать

The Mechanics of Macro Parameters

A macro may have as many parameters as will fit on one line. This is a rather arbitrary restriction, leaving you no recourse but to use short parameters names if you need lots of parameters for a single macro.

Arguments are dropped into parameters in order, from left to right. If you pass only two arguments to a macro with three parameters, you're likely to get an error message from the assembler, depending on how you've referenced the unfilled parameter. The assembler builds opcodes based on the types of operands passed as arguments; if you don't pass an argument for a given parameter, any instructions that reference that parameter won't be constructable by the assembler, hence the errors.

If you pass more arguments to a macro than there are parameters to receive the arguments, the extraneous arguments will be ignored.

Local Labels within Macros

I haven't really gone into labels and branches yet, but there's an important problem with labels used inside macros. Labels in assembly-language programs must be unique, and yet a macro is essentially duplicated in the source code as many times as it is invoked. This means there will be error messages flagging duplicate labels...unless you declare a macro's labels as local.

Local labels are declared with the LOCAL directive. Here's an example; don't worry if you don't fully understand all of the instructions it uses:

UpCase MACRO Target,Length

;Target is a string: Length its length

LOCAL Tester,Bump

 

mov CX,Length

; CX is acting as length counter for loop

lea BX,Target

; String will be at DS:BX

Tester: cmp BYTE PTR [BX],'a'

; Is string character below 'a'l

jb Bump

; If so, leave character alone

cmp BYTE PTR [BX],'z'

; Is string character above 'z'?

ja Bump

; If so, leave character alone

and BYTE PTR [BX],llOlllllb

; Char is 1c alpha,

; so force bit 5 to 0

Bump: inc BX

 

; Bump BX to point to next char in string

loop Tester

 

: And go back and do it

again!

 

 

ENDM

The important thing to understand is that unless the labels Tester and Bump are declared local to the macro, there will be multiple instances of a label in the program and the assembler will generate a duplicate label error.

The only thing to remember about declaring local labels within macros is that the LOCAL directive must immediately follow the macro header. Don't put anything—not even a comment line—between the two.

Macro Libraries

Just as procedures can be gathered in libraries external to your program, so can macros be gathered into macro libraries. A macro library is really nothing but a text file that contains the source code for the macros in the library. Unlike a procedures module, macro libraries are not separately assembled. Macro libraries must be passed through the assembler each time the program is assembled. This is a problem with macros in general, not only with macros that are gathered into libraries. Programs that manage complexity by dividing code up into macros will assemble more slowly than programs that have been divided up into separately assembled modules.

Macro libraries are used by including them into your program's source-code file. The means to do this is the INCLUDE directive. The INCLUDE directive precedes the name of the macro library:

INCLUDE MYLIB.MAC

This statement may be anywhere in your source-code file, but you must keep in mind that all macros must be fully defined before they are invoked. For this reason, it's a good idea to use the INCLUDE directive near the top of your source-code file, before any possible invocation of one of the library macros could occur.

The following is a macro library containing macro versions of all the procedures we discussed in the previous section:

END Start

; The procedure named Start becomes the main program

You'll spot something odd in EAT5.ASM: instead of using ClrScr to clear the screen as I have been for the last several incarnations of EAT, I've replaced ClrScr with a new macro called Clear. Clear (defined in VIDLIB.MAC) uses some technology I haven't explained yet, but will return to in Chapter 10. The lesson is that there are numerous ways to skin a screen, and we've moved here from having the BIOS do it for us to doing it all on our own. Take it on faith for now, until I come back to it. More to the point for the current discussion is the use of the GotoXY and Write and Writeln macros. Additionally, if you look closely at the main program procedure in EAT5.ASM,

something odd may occur to you: It's starting to look like something other than an assembly-language program. This is true, and it's certainly possible to create so many macros that your programs will begin to look like some odd high-level language.

The danger there is that unless you name your macros carefully, and document them both in their macro-library files and on the lines where they are invoked, your programs will not be any more comprehensible for their presence. Dividing complexity into numerous compartments is only half the job— labeling the compartments is just as (or more) important!

You don't take off until all your flight checks are made.