shithub: rgbds

ref: 17192ea6f07c2697bd87bc28df015a66f6e97fc3
dir: /doc/asm/macro.htm/

View raw version
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
	<title>xAsm MACRO/ENDM</title>
        <link rel="stylesheet" type="text/css" href="../style.css">
</head>
<body>
<h1>MACRO, ENDM</h1>
<p>One of the best features of an assembler is the ability to write macros for it. Macros also provide a method of passing arguments to them and they can then react to the input using IF-constructs.</p>
<pre>MyMacro:  MACRO
          ld   a,80
          call MyFunc
          ENDM</pre>
<p>The above example is a very simple macro. You execute the macro by typing its name.</p>
<pre>          add  a,b
          ld   sp,hl
          MyMacro        ;This will be expanded
          sub  a,87</pre>
<p>When the assembler meets MyMacro it will insert the macrodefinition (the text enclosed in <b>MACRO/ENDM</b>).</p>
<p id="labelsuffix">Suppose your macro contains a loop.</p>
<pre>LoopyMacro:    MACRO
               xor  a,a
.loop          ld   [hl+],a
               dec  c
               jr   nz,.loop
               ENDM</pre>
<p>This is fine. That is, if you only use the macro once per <a href="labels.htm">scope</a>. To get around this problem there is a special label string equate called <b>\@</b> that you can append to your labels and it will then expand to a unique string.</p>
<p><b>\@</b> also works in <a href="rept.htm">REPT-blocks</a> should you have any loops there.</p>
<pre>LoopyMacro:    MACRO
               xor  a,a
.loop\@        ld   [hl+],a
               dec  c
               jr   nz,.loop\@
               ENDM</pre>
<h2>Arguments</h2>
<p>I’d like <i>LoopyMacro</i> a lot better if I didn’t have to pre-load the registers with values and <em>then</em> call it. What  I’d like is the ability to pass it arguments and it then loaded the registers itself.</p>
<p>And I can do that. In macros you can get the arguments by using the special macro string equates <b>\1</b> through <b>\9</b>, <b>\1</b> being the first argument specified on the calling of the macro.</p>
<pre>LoopyMacro:    MACRO
               ld   hl,\1
               ld   c,\2
               xor  a,a
.loop\@        ld   [hl+],a
               dec  c
               jr   nz,.loop\@
               ENDM</pre>
<p>Now I can call the macro specifying two arguments. The first being the address and the second being a bytecount. The macro will then reset all bytes in this range.</p>
<pre>               LoopyMacro     MyVars,54</pre>
<p>You can specify up to nine arguments when calling a macro. Arguments are passed as string equates. There’s no need to enclose them in quotes. Parameter passing has changed a bit since v1.03 in that an expression will not be evaluated first but passed directly. This means that it’s probably a very good idea to use brackets around \1–\9 if you perform further calculations on them. For instance if you pass 1+2 as the first argument and then do <code>    PRINTV  \1*2</code>
you will get the value 5 on screen and not 6 as you might have expected.</p>
<p>Note that a colon (:) following the macro-name is required. Macros can't be exported or imported. It's valid to call a macro from a macro (yes, even the same one).</p>

<h1>See also:</h1>
<ul>
<li><a href="shift.htm">SHIFT</a>
</ul>
<hr>
<p>Last updated 02 July 1997 by <a href="mailto:[email protected]">Carsten Sorensen</a></p>
</body>
</html>