• Keine Ergebnisse gefunden

INLINE MACROS

Im Dokument MACRO ASSEMBLER: (Seite 44-50)

EQU 16 ;SIZE OF LOCAL STACK (IN DOUBLE BYTES) ORG

1. INLINE MACROS

The simplest macro facilities involve the REPT (repeat), IRPC (indefinite repeat character), and mp (indefinite repeat) macro groups. All these forms -cause the assembler to repetively re-read portions of the source program under control of a counter or list of textual sUbstitutions. These groups are listed below in increasing order of complexity.

7.1. The REPT-ENDM Group.

The REPT-ENDM group is written as a sequence of assembly language statements starting with the REPT pseudo operation, and terminated by an ENDM pseudo operation.

The form is:

label: REPT expression statement-l statement-2 statement-n label: ENDM

where the labels are optional. The expression following the REPT is evaluated as a 16-bit unsigned count of the number of times that the assembler is to read and process statements 1 through n which are enclosed within the group.

Figure 12 shows an example of the use of the REPT group. In this case the REPT-ENDM group is used to generate a short table of the byte values 5, 4, 3, 2, and 1. Upon entry to the REPT, the value of NXTVAL is 5 which is taken as the repeat count (even though NXTVAL changes within the REPT). Note that the macro lines which do not generate machine code are not listed in the repetition, while the lines which do generate code are listed with a

"+"

sign after the machine code address.

Full macro tracing is optional, however, using assembly parameters, as discussed in a later section.

In general, if a label appears on the REPT statement, its value is the first machine code address which follows. This REPT label is not re-read on each repetition of the loop. The optional label on the ENDM is re-read on each iteration and thus constant labels (not generated through concatenation or with the LOCAL pseudo operation) will generate phase errors if the repetion count is greater than 1.

Properly nested macros, including REPT's, can occur within the body of the REPT-ENDM group. Further, nested conditional assembly statements are also allowed, with the added feature that conditionals which begin within the repeat group are automatically terminated upon reaching the end of the macro expansion. Thus, IF and ELSE pseudo operations are not required to have their corresponding ENDIF when they begin within the repeat group (although the ENDIF is allowed).

7.2. The IRPC-ENDM Group.

Similar to the REPT group, the mpC-ENDM group causes the assembler to re-read a bounded set of statements, taking the form

~ TITLE 'SAMPLE REPT STATEMENT'

THIS PROGRAM READS INPUT PORT 0 AND INDEXES INTO A TABLE NXTVAL-1;;AND DECREMENT FILL VALUE NXTVAL

label:

mpc

identifier ,character-list statement-1

statement-2 statement-n label: ENDM

where the optional labels obey the same conventions as in the REPT-ENDM group.

The "identifier" is any valid assembler name, not including embedded "$" separators, and "character-list" denotes a string of characters, terminated by a delimiter (space, tab, end-of-line, or comment).

The

mpc

controls the re-read process as follows: the statement sequence is read once for each character in the character-list. On each repetition, a character is taken from the character-list and associated with the controlling identifier, starting with the first and ending with the last character in the list. Thus, an IRPC header of the form

mpc

?X,ABCDE

re-reads the statement sequence which follows (to the balancing ENDM) a total of five times, once for each character in the list "ABCDE." On the first iteration, the character "A" is associated with the identifier "?X" and on the' fifth iteration the letter "E" is associated with the controlling identifier.

On each, iteration, the macro assembler SUbstitutes any occurrence of the controlling identifier by the associated character value. Using the above IRPC header, an occurrence of "?X" in the bounds of the IRPC-ENDM group is replaced by the character "A" on the first iteration, and by "E" on the last iteration.

The programmer can use the controlling identifier to construct new text strings within the body of the

mpc

by using the special "concatenation" operator, denoted by an ampersand (&). Again using the above IRPC header, the macro assember would replace "LAB&?X" by "LABA" on the first iteration, while "LABE" would be produced on the final iteration. The concatenation feature is most often used to generate unique label names on each iteration of the

mpc

re-read process.

Note, however, that the controlling identifier is not normally SUbstituted within string quotes, since the controlling identifier could quite possibly occur as a part of a quoted message. Thus, the macro assembler performs substitution of the controlling identifier when it is either preceded and/or followed by the ampersand operator.

Further, recall that all alpha.betics outside string quotes are translated to upper case, while no case translation occurs within string quotes. This requires that the controlling identifier be not only preceded or followed by the concatenation operator within strings, but must also be typed in upper case.

Figure 13 illustrates the use of the IRPC-ENDM group. Figure 13a shows the original assembly language program, before processing by the macro assembler. Note that the program is typed in both upper and lower case. Figure 13b shows the output from the macro assembler, with the lower case alphabetics translated to upper case.

Three

mpc

groups are shown in this example. The first IRPC uses the controlling identifier "reg" to generate a sequence of stack push operations which save the double precision registers BC, DE, and HL. Again note that the lines generated by this group are marked by a n+" sign following the machine code address.

OOOO+C5 0001+D5 0002+E5

0003+31 0004+41 0005+42 0006+24 0007+3F 0008+40

0009+E1 000A+D1 OOOB+Cl OOOC C9 OOOD

construct a data table

; save relevant registers enter: irpc reg,bdh

push reg ;;save reg endm

initialize a partial ascii table irpc c,lAb$?@

data&c: db '&C' endm

registers reg,hdb restore

irpc pop endm ret

reg ;;recall reg end

Figure 13a. Original (.ASM) File with IRPC Example.

CONSTRUCT A DATA TABLE

; SAVE RELEVANT REGISTERS ENTER: IRPC REG,BDH

PUSH REG ;;SAVE REG ENDJ.\1

PUSH B PUSH D PUSH H

INITIALIZE A PARTIAL ASCII TABLE IRPC C,lAB$?@

DATA&C: DB '&C' ENDM

DATAl: DB ' 1 ' DATAA: DB 'A' DATAB: DB 'B' DATA$ : DB '$ , DATA? : DB ' ? ' DATA@.: DB '@'

RESTORE REGISTERS JRPC REG,HDB

POP REG ; ; RECALL REG ENDM

POP

H

POP

D

POP B

RET

END

Figure 13b. Resulting (.PRN) file with JRPC Example.

40

The second IRPC shown in Figure 13 uses the controlling identifier "C" to generate a number of single byte constants with corresponding labels. It is important to observe that although the controlling variable was typed in lower case (see Figure 13a), it has been translated to upper case during assembly. Further, note that the string '&C' occurs within the group and, since the controlling variable is enclosed in string quotes, it must occur next to an ampersand operator and be typed in upper case for the sUbstitution to occur properly. On each iteration of the IRPC, a label is constructed through concatenation, and a "DB" is generated with the corresponding character from the character-list.

It should be pointed out that sUbstitution of the controlling identifier by its assoc'iated value could cause infinite SUbstitution if the controlling identifier is the same as the character from the character-list. For this reason, the macro assembler performs the SUbstitution and then moves along to read the next segment of the program, rather than re-reading the SUbstituted text for another possible occurrence of the controlling identifier. Thus, an IRPC of the form

IRPC C,lAC$?@

would produce

DATAC: DB 'C'

in place of the DB statement at the label DATAA in Figure 13b.

The last IRPC of Figure 13 is used to restore the previously saved double precision registers, and performs the exact opposite function from the IPRC at the beginning of the program.

One special case does occur, however, when the character-list is empty (i.e., when no characters occur following the "identifier," portion of the IRPC header). In this case, the group of statements is read once, and any occurrence of the controlling identifier is deleted when it is read (i.e., it is replaced by the "null string").

7.3. The IRP-ENDM Group.

The IRP (indefinite repeat) is similar in function to the IRPC, except that the controlling identifier can take on a multiple character value. The form of the IRP group is

label: IRP identifier,icl-1,cl-2, ..• ,cl-ni statement-1

statement-2 statement-m label: ENDM

where the optional labels obey the conventions of the REPT and IRPC groups. The identifier controls the iteration as follows. On the first iteration, the character-list given by "cl-1" is substituted for the identifier wherever the identifier occurs in the bounded statement group (statements 1 through m). On the second iteration, cl-2 becomes the value of the controlling identifier. Iteration continues in this manner

until the last character-list, denoted by cl-n, is encountered and processed. Substitution of values for the controlling identifier is subject to the same rules as in the IRPC (note rules for SUbstitution within strings and concatenation of text using the ampersand operator "&,,). One should also note that controlling identifiers are always ignored within comments.

Figure 14 gives several examples of IRP groups. The first occurrence of the IRP in Figure 14 is a typical use of this facility to generate a "jump vector" at the beginning of a program or subroutine. The IRP assigns label names (INITIAL, GET, PUT, and FINIS) to the controlling identifier "?LAB" and produces a jump instruction for each label by re-reading the IRP group, substituting the actual label for the formal name on each iteration.

The second occurrence of the IRP group in Figure 14 points out SUbstitution conventions within strings (for both IRPC and IRP groups). The controlling identifier

"IS" takes on the values "A-ROSE" and "?" on the two iterations of the IRP group, respectively. Note that the controlling identifier is replaced by the character-lists in the two cases "&IS" and "IS&" inside the string quotes since they are both adjacent to the ampersand operator. Note further that "is&" is not replaced because the controlling identifier is typed in lower case, and there is no automatic translation to upper case within strings. The occurrences of "IS" within the comments are not substituted.

The last IRP group shows the effects of an empty character-list. The value of the controlling identifier becomes the null string of symbols and, in the cases where

"?X" is replaced, produces the statement DB n

which produces no machine code, and is therefore not listed in the macro expansion.

The three statements

DB '?x' DB '?X' DB '&'

appear in the expansions because the "?x" is typed in lower case (and thus is not replaced), the '?X' does not appear next to an ampersand in the string (and is thus not replaced), while in the last case only one of the double ampersands is absorbed in the '&&?X&' string. In this last case, the two ampersands which surround "?X" are removed since they occur immediately next to the controlling identifier within the string.

Recall that substitution rules outside of string quotes and comments is much less complicated: the controlling identifier is replaced by the current character-list value whenever it occurs in any of the statements within the group. Further, the ampersand opera tor can be placed before or after the controlling identifier to cause the preceding or following text to be concatenated.

The actual forms for the character-lists (cl-l through cl-n) are more general than stated here. In particular, bracket nesting is allowed as well as escape sequences to allow delimiters to be ignored. The exact details of character-list forms are discussed in the macro parameter sections.

42

OOOO+C30COO

Im Dokument MACRO ASSEMBLER: (Seite 44-50)