⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nasmdoc4.htm

📁 nasm手册 大家可以看看 对要写汇编程序的帮助很大
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<p><pre>%ifdef SOME_MACRO     ; do some setup %elifdef SOME_OTHER_MACRO     ; do some different setup %else     %error Neither SOME_MACRO nor SOME_OTHER_MACRO was defined. %endif</pre><p>Then any user who fails to understand the way your code is supposed tobe assembled will be quickly warned of their mistake, rather than having towait until the program crashes on being run and then not knowing what wentwrong.<h3><a name="section-4.5">4.5 Preprocessor Loops: <code><nobr>%rep</nobr></code></a></h3><p>NASM's <code><nobr>TIMES</nobr></code> prefix, though useful, cannot beused to invoke a multi-line macro multiple times, because it is processedby NASM after macros have already been expanded. Therefore NASM providesanother form of loop, this time at the preprocessor level:<code><nobr>%rep</nobr></code>.<p>The directives <code><nobr>%rep</nobr></code> and<code><nobr>%endrep</nobr></code> (<code><nobr>%rep</nobr></code> takes anumeric argument, which can be an expression;<code><nobr>%endrep</nobr></code> takes no arguments) can be used toenclose a chunk of code, which is then replicated as many times asspecified by the preprocessor:<p><pre>%assign i 0 %rep    64         inc     word [table+2*i] %assign i i+1 %endrep</pre><p>This will generate a sequence of 64 <code><nobr>INC</nobr></code>instructions, incrementing every word of memory from<code><nobr>[table]</nobr></code> to <code><nobr>[table+126]</nobr></code>.<p>For more complex termination conditions, or to break out of a repeatloop part way along, you can use the <code><nobr>%exitrep</nobr></code>directive to terminate the loop, like this:<p><pre>fibonacci: %assign i 0 %assign j 1 %rep 100 %if j &gt; 65535     %exitrep %endif         dw j %assign k j+i %assign i j %assign j k %endrep fib_number equ ($-fibonacci)/2</pre><p>This produces a list of all the Fibonacci numbers that will fit in 16bits. Note that a maximum repeat count must still be given to<code><nobr>%rep</nobr></code>. This is to prevent the possibility of NASMgetting into an infinite loop in the preprocessor, which (on multitaskingor multi-user systems) would typically cause all the system memory to begradually used up and other applications to start crashing.<h3><a name="section-4.6">4.6 Including Other Files</a></h3><p>Using, once again, a very similar syntax to the C preprocessor, NASM'spreprocessor lets you include other source files into your code. This isdone by the use of the <code><nobr>%include</nobr></code> directive:<p><pre>%include "macros.mac"</pre><p>will include the contents of the file<code><nobr>macros.mac</nobr></code> into the source file containing the<code><nobr>%include</nobr></code> directive.<p>Include files are searched for in the current directory (the directoryyou're in when you run NASM, as opposed to the location of the NASMexecutable or the location of the source file), plus any directoriesspecified on the NASM command line using the <code><nobr>-i</nobr></code>option.<p>The standard C idiom for preventing a file being included more than onceis just as applicable in NASM: if the file<code><nobr>macros.mac</nobr></code> has the form<p><pre>%ifndef MACROS_MAC     %define MACROS_MAC     ; now define some macros %endif</pre><p>then including the file more than once will not cause errors, becausethe second time the file is included nothing will happen because the macro<code><nobr>MACROS_MAC</nobr></code> will already be defined.<p>You can force a file to be included even if there is no<code><nobr>%include</nobr></code> directive that explicitly includes it,by using the <code><nobr>-p</nobr></code> option on the NASM command line(see <a href="nasmdoc2.html#section-2.1.11">section 2.1.11</a>).<h3><a name="section-4.7">4.7 The Context Stack</a></h3><p>Having labels that are local to a macro definition is sometimes notquite powerful enough: sometimes you want to be able to share labelsbetween several macro calls. An example might be a<code><nobr>REPEAT</nobr></code> ... <code><nobr>UNTIL</nobr></code> loop,in which the expansion of the <code><nobr>REPEAT</nobr></code> macro wouldneed to be able to refer to a label which the<code><nobr>UNTIL</nobr></code> macro had defined. However, for such amacro you would also want to be able to nest these loops.<p>NASM provides this level of power by means of a <em>context stack</em>.The preprocessor maintains a stack of <em>contexts</em>, each of which ischaracterised by a name. You add a new context to the stack using the<code><nobr>%push</nobr></code> directive, and remove one using<code><nobr>%pop</nobr></code>. You can define labels that are local to aparticular context on the stack.<h4><a name="section-4.7.1">4.7.1 <code><nobr>%push</nobr></code> and <code><nobr>%pop</nobr></code>: Creating and Removing Contexts</a></h4><p>The <code><nobr>%push</nobr></code> directive is used to create a newcontext and place it on the top of the context stack.<code><nobr>%push</nobr></code> requires one argument, which is the name ofthe context. For example:<p><pre>%push    foobar</pre><p>This pushes a new context called <code><nobr>foobar</nobr></code> on thestack. You can have several contexts on the stack with the same name: theycan still be distinguished.<p>The directive <code><nobr>%pop</nobr></code>, requiring no arguments,removes the top context from the context stack and destroys it, along withany labels associated with it.<h4><a name="section-4.7.2">4.7.2 Context-Local Labels</a></h4><p>Just as the usage <code><nobr>%%foo</nobr></code> defines a label whichis local to the particular macro call in which it is used, the usage<code><nobr>%$foo</nobr></code> is used to define a label which is local tothe context on the top of the context stack. So the<code><nobr>REPEAT</nobr></code> and <code><nobr>UNTIL</nobr></code>example given above could be implemented by means of:<p><pre>%macro repeat 0     %push   repeat     %$begin: %endmacro %macro until 1         j%-1    %$begin     %pop %endmacro</pre><p>and invoked by means of, for example,<p><pre>        mov     cx,string         repeat         add     cx,3         scasb         until   e</pre><p>which would scan every fourth byte of a string in search of the byte in<code><nobr>AL</nobr></code>.<p>If you need to define, or access, labels local to the context<em>below</em> the top one on the stack, you can use<code><nobr>%$$foo</nobr></code>, or <code><nobr>%$$$foo</nobr></code> forthe context below that, and so on.<h4><a name="section-4.7.3">4.7.3 Context-Local Single-Line Macros</a></h4><p>NASM also allows you to define single-line macros which are local to aparticular context, in just the same way:<p><pre>%define %$localmac 3</pre><p>will define the single-line macro <code><nobr>%$localmac</nobr></code>to be local to the top context on the stack. Of course, after a subsequent<code><nobr>%push</nobr></code>, it can then still be accessed by the name<code><nobr>%$$localmac</nobr></code>.<h4><a name="section-4.7.4">4.7.4 <code><nobr>%repl</nobr></code>: Renaming a Context</a></h4><p>If you need to change the name of the top context on the stack (inorder, for example, to have it respond differently to<code><nobr>%ifctx</nobr></code>), you can execute a<code><nobr>%pop</nobr></code> followed by a<code><nobr>%push</nobr></code>; but this will have the side effect ofdestroying all context-local labels and macros associated with the contextthat was just popped.<p>NASM provides the directive <code><nobr>%repl</nobr></code>, which<em>replaces</em> a context with a different name, without touching theassociated macros and labels. So you could replace the destructive code<p><pre>%pop %push   newname</pre><p>with the non-destructive version<code><nobr>%repl newname</nobr></code>.<h4><a name="section-4.7.5">4.7.5 Example Use of the Context Stack: Block IFs</a></h4><p>This example makes use of almost all the context-stack features,including the conditional-assembly construct<code><nobr>%ifctx</nobr></code>, to implement a block IF statement as aset of macros.<p><pre>%macro if 1     %push if     j%-1  %$ifnot %endmacro %macro else 0   %ifctx if         %repl   else         jmp     %$ifend         %$ifnot:   %else         %error  "expected `if' before `else'"   %endif %endmacro %macro endif 0   %ifctx if         %$ifnot:         %pop   %elifctx      else         %$ifend:         %pop   %else         %error  "expected `if' or `else' before `endif'"   %endif %endmacro</pre><p>This code is more robust than the <code><nobr>REPEAT</nobr></code> and<code><nobr>UNTIL</nobr></code> macros given in<a href="#section-4.7.2">section 4.7.2</a>, because it uses conditionalassembly to check that the macros are issued in the right order (forexample, not calling <code><nobr>endif</nobr></code> before<code><nobr>if</nobr></code>) and issues a <code><nobr>%error</nobr></code>if they're not.<p>In addition, the <code><nobr>endif</nobr></code> macro has to be able tocope with the two distinct cases of either directly following an<code><nobr>if</nobr></code>, or following an<code><nobr>else</nobr></code>. It achieves this, again, by usingconditional assembly to do different things depending on whether thecontext on top of the stack is <code><nobr>if</nobr></code> or<code><nobr>else</nobr></code>.<p>The <code><nobr>else</nobr></code> macro has to preserve the context onthe stack, in order to have the <code><nobr>%$ifnot</nobr></code> referredto by the <code><nobr>if</nobr></code> macro be the same as the one definedby the <code><nobr>endif</nobr></code> macro, but has to change thecontext's name so that <code><nobr>endif</nobr></code> will know there wasan intervening <code><nobr>else</nobr></code>. It does this by the use of<code><nobr>%repl</nobr></code>.<p>A sample usage of these macros might look like:<p><pre>        cmp     ax,bx         if ae                cmp     bx,cx                if ae                        mov     ax,cx                else                        mov     ax,bx                endif         else                cmp     ax,cx                if ae                        mov     ax,cx                endif         endif</pre><p>The block-<code><nobr>IF</nobr></code> macros handle nesting quitehappily, by means of pushing another context, describing the inner<code><nobr>if</nobr></code>, on top of the one describing the outer<code><nobr>if</nobr></code>; thus <code><nobr>else</nobr></code> and<code><nobr>endif</nobr></code> always refer to the last unmatched<code><nobr>if</nobr></code> or <code><nobr>else</nobr></code>.<h3><a name="section-4.8">4.8 Standard Macros</a></h3><p>NASM defines a set of standard macros, which are already defined when itstarts to process any source file. If you really need a program to beassembled with no pre-defined macros, you can use the<code><nobr>%clear</nobr></code> directive to empty the preprocessor ofeverything.<p>Most user-level assembler directives (see<a href="nasmdoc5.html">chapter 5</a>) are implemented as macros whichinvoke primitive directives; these are described in<a href="nasmdoc5.html">chapter 5</a>. The rest of the standard macro setis described here.<h4><a name="section-4.8.1">4.8.1 <code><nobr>__NASM_MAJOR__</nobr></code>, <code><nobr>__NASM_MINOR__</nobr></code>, <code><nobr>__NASM_SUBMINOR__</nobr></code> and <code><nobr>___NASM_PATCHLEVEL__</nobr></code>: NASM Version</a></h4><p>The single-line macros <code><nobr>__NASM_MAJOR__</nobr></code>,<code><nobr>__NASM_MINOR__</nobr></code>,<code><nobr>__NASM_SUBMINOR__</nobr></code> and<code><nobr>___NASM_PATCHLEVEL__</nobr></code> expand to the major, minor,subminor and patch level parts of the version number of NASM being used.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -