[ First ]  [ Previous ]  [ Next ]  [ Last ]  [ Manuals ]

 

Chapter 4.

 

Using Macros



This chapter describes how to define and use macros. You can use the same macro language regardless of your target processor.


NOTE

The macro language is similar to Hitachi assembler syntax with some extensions.


This chapter includes the following topics:


Defining Macros

This section, which describes how to define macros, includes the following topics:


Macro Definition Syntax

A macro definition is one or more assembly statements that define:

You can use the following methods to define a macro:

Defining a macro with the .macro directive Defining a macro with the #define directive

Defining a macro with the .macro directive

One way to define a macro is to use the .macro directive. Listing 4.1 shows the syntax of a macro definition using the .macro directive.

Macro definition syntax using the .macro directive:


name:				.macro				[ parameter ] [ ,parameter ] ...
				macro_body
				.endm


The .macro directive indicates the first line of a macro definition. Every macro definition must end with the .endm directive.

Table 4.1 describes the syntax elements shown in Listing 4.1.

Macro syntax descriptions for .macro directive:

 

Syntax Element
Description
name  
A label used to invoke the macro.  
parameter  
Operands that are passed to the macro and used in the macro body.  
macro_body  
One or more assembly language statements that are substituted for a macro call when you invoke the macro.  

You can specify a conditional assembly block within a macro. Based on the result of the tested condition, you can use the .mexit directive to stop macro execution before the assembler reaches the .endm directive.

Listing 4.2 shows a macro that uses the .mexit directive.

Conditional macro using the .mexit directive:


# define a macro
addto				.macro dest,val
				.if val==0
					  no-op 
				.mexit				# execution goes to the statement
								# immediately after the .endm directive
				.elseif val==1
						# use compact instruction
						inc dest
				.mexit				# execution goes to the statement
								# immediately after the .endm directive
				.endif
# if val is not equal to either 0 or 1,
# add dest and val
				add dest,val
# end macro definition
				.endm


Listing 4.3 shows assembly language code that calls the addto macro shown in Listing 4.2.

Assembly code that calls the addto macro:


# specify an executable code section
				.text
				xor   eax,eax
# call the addto macro
				addto eax,0
				addto eax,1
				addto eax,2
				addto eax,3


Listing 4.4 shows the expanded addto macro calls shown in Listing 4.3.

Expanded addto macro calls:


           xor  eax,eax
           nop
           inc  eax
           add  eax,2
           add  eax,3



Defining a macro with the #define directive

Another way to define a macro is to use the #define directive. Listing 4.5 shows the syntax of a macro definition using the #define directive.

Macro definition syntax using the #define directive:


#define name [ (parms) ] assembly_statement [ ; ] [ \ ]
assembly_statement [ ; ] [ \ ]
assembly_statement
parms ::= parameter [ ,parameter ]...



NOTE

If you specify parameters for a macro, you must enclose the parameters in parentheses.


Table 4.2 describes the syntax elements shown in Listing 4.5.

Macro syntax descriptions for #define directive:

 

Syntax Element
Description
name  
A label used to invoke the macro.  
parameter  
Operands that are passed to the macro.  
assembly_statement  
An assembly language statement that is substituted for a macro call when you invoke the macro. You can extend the assembly language statement beyond the length of one physical line by typing a backslash (\) at the end of a line and continuing the statement on the subsequent line.     You also can specify multiple assembly statements in the macro by typing a semicolon (;) followed by a backslash (\) and typing a new assembly statement on the next physical line.  


Using Macro Arguments

You can refer to parameters directly by name. Listing 4.6 shows the setup macro, which moves an integer into a register and branches to the label _final_setup.

The setup macro:


setup:       .macro name
             mov    eax, name
             call    _final_setup
             .endm


Listing 4.7 shows one way to invoke the setup macro.

Calling setup:


               #define VECT 0              
               setup  VECT


Listing 4.8 shows how the assembler expands the setup macro after the preceding call.

Expanded setup:


           move    eax, VECT
           call    _final_setup


When you refer to named macro parameters in the macro body, you can precede or follow the macro parameter with &&. This lets you embed the parameter in a string. For example, Listing 4.9 shows the smallnum macro, which creates a small float by appending the string E-20 to the macro argument.

The smallnum macro:


smallnum:    .macro    mantissa
             .float    mantissa&&E-20
             .endm


Listing 4.10 shows one way to invoke the smallnum macro.

Invoking smallnum:


              smallnum  10


Listing 4.11 shows how the assembler expands the smallnum macro after the preceding call.

Expanding smallnum:


              .float     10E-20



Using Local Labels in a Macro

When you use a local label (a label that begins with @) in a macro, the scope of the label is limited to the expansion of the macro. For more information, see "Local labels".


Creating Unique Labels and Equates

You can generate unique labels and equates within a macro with the following characters: \@. Each time you invoke the macro, the assembler generates a unique symbol of the form ??nnnn, such as ??0001 or ??0002.

You refer to unique labels and equates (those that use \@) in your code with the same methods used for regular labels and equates. The assembler replaces the \@ sequence with a unique numeric string and increments the value of the string each time you invoke the macro.

Listing 4.12 shows a macro that uses unique labels and equates.

Unique label macro:


my_macro: .macro
          foo\@ = my_count
my_count  .set my_count + 1
          add  ebx, foo\@
          jmp  label\@
          add  eax, ebx
label\@:
          nop
          .endm


Listing 4.13 shows a call to the my_macro macro twice (with my_count initialized to 0).

Invoking my_macro:


my_count  .set 0
          my_macro
          my_macro


Listing 4.14 shows the expanded my_macro code after the calls in Listing 4.13.

Expanded my_macro calls:


foo??0000   =     my_count
my_count    .set  my_count + 1
            add   ebx, foo??0000
            jmp   label??0000
            add   eax, ebx
label??0000
            nop
foo??0001   =     my_count
my_count    .set  my_count + 1
            add   ebx, foo??0001
            jmp   label??0001
            add   eax, ebx
label??0001
            nop






Referring to the Number of Arguments

To refer to the number of non-null arguments passed to a macro, use the special symbol narg. You can use it only during macro expansion.



Invoking Macros

To invoke a macro, use its name in your assembler listing.

 

When invoking a macro, you must separate parameters with commas. To pass a parameter that includes a comma, enclose the parameter in angle brackets.

 

For example, Listing 4.15 shows a macro named pattern, which repeats a pattern of bytes passed to it the number of times specified in the macro call.

The pattern macro:


pattern: .macro times,bytes

.rept times

.byte bytes

.endr

.endm


Listing 4.16 shows a statement that calls pattern, passing a parameter that includes a comma.

Calling a macro with an argument that contains commas:


.data

halfgrey: pattern 4,<0xAA,0x55>


The call in Listing 4.16 generates the same data as the code shown in Listing 4.17.

Alternate way to generate a repeating pattern of bytes:


halfgrey: .byte 0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55


 

 


[ First ]  [ Previous ]  [ Next ]  [ Last ]  [ Manuals ]

Visit the Metrowerks website at: http://www.metrowerks.com
For assistance contact Metrowerks Technical Support at: cw_support@metrowerks.com
Copyright © 2000, Metrowerks Corp. All rights reserved.

Last updated: July 20, 2000