Macros

Macros are elements of language that enable the replacement of one text with another. In assembler language, macros can be implemented differently in different assemblers understood as programming software. In this chapter, we'll present the MASM implementation. Although in other assemblers (NASM, NASM) the syntax can differ, the idea remains the same. There are a few types of macros in MASM:

  • Text macros,
  • Macro procedures,
  • Repeat blocks,
  • Macro functions,
  • Predefined macro functions,
  • String directives.

We'll go through all of them in the following sections.

Text macros

Text macros are a simple replacement of one text with another. They are defined with the directive TEXTEQU, which creates a new symbolic name and assigns the text to it. The text assigned should be closed in angle brackets, can be a previously defined macro, or can be a text representation of an expression. In the last case, the percent operator calculates the result of an expression and converts it into a text representation. This process is named expansion, and the percent operator is the expansion operator.

name TEXTEQU <text>
name TEXTEQU macroId | textmacro
name TEXTEQU %constExpr

Using text macros, it is possible to name some constants like PI, shorten other directives, and even create your own instruction names.

pi     TEXTEQU <3.1416>   ; Floating point constant
WPT    TEXTEQU <WORD PTR> ; Sequence of keywords
copy   TEXTEQU <mov>      ; New name for mov instruction

Previously defined text macro can be redefined later in the program.

message TEXTEQU <Hello World!> ; Define message with the text "Hello World!"
message TEXTEQU <Good Bye!>    ; Redefine message with new text "GoodBye!"

The explanation of percent operator is shown in the following code.

sum TEXTEQU <3+9>   ; sum is the text "3+9"
sum TEXTEQU %(3+9)  ; sum is the text "12"

Macro procedures

Macro procedure is a definition of a fragment of code that can be used later in the resulting program. In some assemblers, they are named multi-line macros. The use of the name of a macro procedure later in the source program causes the so-called expansion of the macro. It is worth noting that for every usage of the macro, the assembler will place in the resulting program all elements specified in the statements inside the macro. These include:

  • instructions,
  • directives,
  • pseudoinstructions.

The simplest definition of a macro procedure contains the name, MACRO keyword, a list of statements inside the macro and ENDM at the end

name  MACRO
      statements
      ENDM
Please note that no macro name is repeated before the ENDM directive.

Macro procedure can have parameters. They are treated as macros themselves, so the use of the parameter name inside the macro results in the replacement of it with the actual value.

name  MACRO parameterlist
      statements
      ENDM

An example of a simple macro which makes a copy of data from the source to the destination can be seen in the following code.

copy MACRO arg1, arg2
     mov RAX, arg1
     mov arg2, RAX
     ENDM

Note that the arguments of the macro must fit the instructions used inside it. They can be previously defined variables, the first argument can be a constant, or you can even pass the names of other registers.

; Three following lines with "copy" macro use:
 
    copy 65, x_coeff
    copy x_coeff, RBX
    copy RBX, RCX
 
; Will be expanded as
 
    mov RAX, 65
    mov x_coeff, RAX
    mov RAX, x_coeff
    mov RBX, RAX
    mov RAX, RBX
    mov RCX, RAX

If the actual parameter is empty, it may result in an error in the expanded line, because empty parameters are assumed as empty texts.

; Use of "copy" macro without two parameters
    copy RBX
 
; Will result in 
    mov RAX, RBX
    mov , RAX      ; this line is invalid and will cause an error

The solution to avoid such a situation is to assign the default parameter value or mark the parameter as required. In the first case, the default value will be assigned to the missing parameter.

; The "copy" macro with default values of parameters
copy MACRO arg1:=0, arg2:=RCX
     mov RAX, arg1
     mov arg2, RAX
     ENDM
 
; Use of "copy" macro without parameters
    copy 
 
; Will result in 
    mov RAX, 0
    mov RCX, RAX      

In the second case, the error will be signalled, but at the line with a macro use, not inside the macro, which makes it easier to localise the error.

; The "copy" macro with required parameters
copy MACRO arg1:REQ, arg2:REQ
     mov RAX, arg1
     mov arg2, RAX
     ENDM
 
; Use of "copy" macro without two parameters
    copy RBX       ; this line will cause an error

If a label needs to be defined inside the macro, it must be declared as local to avoid ambiguity. In general, any symbol can be declared as local. In such a case, it will only be visible inside the macro. The LOCAL directive can be used for this purpose. It must appear in the line next to the MACRO statement.

copy MACRO arg1, arg2
     LOCAL jump_over, jump_end
 
     cmp RAX, arg1  ; test if RAX = arg1
     je jump_over   ; if yes, do not copy arg1 to RAX
     mov RAX, arg1
 
jump_over:
     cmp RAX, arg2  ; test if RAX = arg2
     je jump_end    ; if ye,s do not copy RAX to arg2
     mov arg2, RAX
 
jump_end:
     ENDM

Repeat blocks

Repeat blocks are macros automatically repeated. The number of repetitions depends on the condition, or is determined by the constant value, or the list of argument values. The REPEAT block is expanded the number of times specified in the constant expression.

REPEAT constexpr
	Statements
ENDM

The WHILE block is expanded as long as the condition is true. The condition can be any expression that evaluates to zero (false) or nonzero (true).

WHILE expression
	Statements
ENDM

The FOR block is expanded for each argument in a list. The parameter is a placeholder that represents the name of each argument The argument list must contain comma-separated arguments and must be enclosed in angle brackets.

FOR parameter, <argumentlist>
	Statements
ENDM

The FORC is similar to FOR but takes a string of text rather than a list of arguments. The text must be enclosed in angle brackets. Statements inside the block are assembled once for each character from the string.

FORC parameter, <text>
	Statements
ENDM

Now, let's examine four repeat blocks that result in the same data definitions. All of them define five bytes with initialising values from 1 to 5.

 i = 1
REPEAT 5
 DB i
 i = i + 1
ENDM
 
 i = 1
WHILE i < 6
 DB i
 i = i + 1
ENDM
 
FOR i,<1,2,3,4,5>
 DB i
ENDM
 
FORC i,<12345>
 DB i
ENDM

Macro functions

A macro function is a macro which returns a value. As all macros are tex processing feature macro functions always return text. Returning the value is possible with the use of the EXITM directive. Argument of the EXITM must be text or the result of another macro function. Numeric values must be converted to text form with the expansion operator %.

Predefined macro functions

Masm offers a set of predefined macro functions, usually used to process texts. There are two versions of them. First is the macro function, which returns the resulting text. Second is the directive, which returns the same text and additionally creates a new symbol. The macro function @SubStr returns part of a source string. The SUBSTR directive assigns part of a source string to a new symbol. The macro function @InStr searches for one string within another and returns its position. The INSTR creates a new symbol containing the position of one string in another. The macro function @SizeStr determines the string size. The SIZESTR creates a new item and assigns to it the size of a string. The macro function @CatStr concatenates one or more strings to a single string and returns a concatenated string. The CATSTR directive concatenates one or more strings to a newly defined string. The following code demonstrates the equivalent use of both versions.

name SUBSTR string, start [, length ]
name INSTR [[start]], string, substring
name SIZESTR string
name CATSTR string [[, string ]]
 
name TEXTEQU @SubStr (string, start [, length ])
name TEXTEQU @InStr ([[start]], string, substring)
name TEXTEQU @SizeStr (string)
name TEXTEQU @CatStr (string [[, string ]])
en/multiasm/papc/chapter_6_13.txt · Last modified: 2025/11/17 08:54 by ktokarz
CC Attribution-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0