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

📄 nasmdoc4.htm

📁 nasm手册 大家可以看看 对要写汇编程序的帮助很大
💻 HTM
📖 第 1 页 / 共 5 页
字号:
keytab: keyposF1        equ     $-keytab                 db     128+1 keyposF2        equ     $-keytab                 db      128+2 keyposReturn    equ     $-keytab                 db      13</pre><p>You can just as easily concatenate text on to the other end of a macroparameter, by writing <code><nobr>%1foo</nobr></code>.<p>If you need to append a <em>digit</em> to a macro parameter, for exampledefining labels <code><nobr>foo1</nobr></code> and<code><nobr>foo2</nobr></code> when passed the parameter<code><nobr>foo</nobr></code>, you can't code <code><nobr>%11</nobr></code>because that would be taken as the eleventh macro parameter. Instead, youmust code <code><nobr>%{1}1</nobr></code>, which will separate the first<code><nobr>1</nobr></code> (giving the number of the macro parameter) fromthe second (literal text to be concatenated to the parameter).<p>This concatenation can also be applied to other preprocessor in-lineobjects, such as macro-local labels (<a href="#section-4.3.2">section4.3.2</a>) and context-local labels (<a href="#section-4.7.2">section4.7.2</a>). In all cases, ambiguities in syntax can be resolved byenclosing everything after the <code><nobr>%</nobr></code> sign and beforethe literal text in braces: so <code><nobr>%{%foo}bar</nobr></code>concatenates the text <code><nobr>bar</nobr></code> to the end of the realname of the macro-local label <code><nobr>%%foo</nobr></code>. (This isunnecessary, since the form NASM uses for the real names of macro-locallabels means that the two usages <code><nobr>%{%foo}bar</nobr></code> and<code><nobr>%%foobar</nobr></code> would both expand to the same thinganyway; nevertheless, the capability is there.)<h4><a name="section-4.3.8">4.3.8 Condition Codes as Macro Parameters</a></h4><p>NASM can give special treatment to a macro parameter which contains acondition code. For a start, you can refer to the macro parameter<code><nobr>%1</nobr></code> by means of the alternative syntax<code><nobr>%+1</nobr></code>, which informs NASM that this macro parameteris supposed to contain a condition code, and will cause the preprocessor toreport an error message if the macro is called with a parameter which is<em>not</em> a valid condition code.<p>Far more usefully, though, you can refer to the macro parameter by meansof <code><nobr>%-1</nobr></code>, which NASM will expand as the<em>inverse</em> condition code. So the <code><nobr>retz</nobr></code>macro defined in <a href="#section-4.3.2">section 4.3.2</a> can be replacedby a general conditional-return macro like this:<p><pre>%macro  retc 1         j%-1    %%skip         ret   %%skip: %endmacro</pre><p>This macro can now be invoked using calls like<code><nobr>retc ne</nobr></code>, which will cause the conditional-jumpinstruction in the macro expansion to come out as<code><nobr>JE</nobr></code>, or <code><nobr>retc po</nobr></code> whichwill make the jump a <code><nobr>JPE</nobr></code>.<p>The <code><nobr>%+1</nobr></code> macro-parameter reference is quitehappy to interpret the arguments <code><nobr>CXZ</nobr></code> and<code><nobr>ECXZ</nobr></code> as valid condition codes; however,<code><nobr>%-1</nobr></code> will report an error if passed either ofthese, because no inverse condition code exists.<h4><a name="section-4.3.9">4.3.9 Disabling Listing Expansion</a></h4><p>When NASM is generating a listing file from your program, it willgenerally expand multi-line macros by means of writing the macro call andthen listing each line of the expansion. This allows you to see whichinstructions in the macro expansion are generating what code; however, forsome macros this clutters the listing up unnecessarily.<p>NASM therefore provides the <code><nobr>.nolist</nobr></code> qualifier,which you can include in a macro definition to inhibit the expansion of themacro in the listing file. The <code><nobr>.nolist</nobr></code> qualifiercomes directly after the number of parameters, like this:<p><pre>%macro foo 1.nolist</pre><p>Or like this:<p><pre>%macro bar 1-5+.nolist a,b,c,d,e,f,g,h</pre><h3><a name="section-4.4">4.4 Conditional Assembly</a></h3><p>Similarly to the C preprocessor, NASM allows sections of a source fileto be assembled only if certain conditions are met. The general syntax ofthis feature looks like this:<p><pre>%if&lt;condition&gt;     ; some code which only appears if &lt;condition&gt; is met %elif&lt;condition2&gt;     ; only appears if &lt;condition&gt; is not met but &lt;condition2&gt; is %else     ; this appears if neither &lt;condition&gt; nor &lt;condition2&gt; was met %endif</pre><p>The <code><nobr>%else</nobr></code> clause is optional, as is the<code><nobr>%elif</nobr></code> clause. You can have more than one<code><nobr>%elif</nobr></code> clause as well.<h4><a name="section-4.4.1">4.4.1 <code><nobr>%ifdef</nobr></code>: Testing Single-Line Macro Existence</a></h4><p>Beginning a conditional-assembly block with the line<code><nobr>%ifdef MACRO</nobr></code> will assemble the subsequent codeif, and only if, a single-line macro called <code><nobr>MACRO</nobr></code>is defined. If not, then the <code><nobr>%elif</nobr></code> and<code><nobr>%else</nobr></code> blocks (if any) will be processed instead.<p>For example, when debugging a program, you might want to write code suchas<p><pre>          ; perform some function %ifdef DEBUG           writefile 2,"Function performed successfully",13,10 %endif           ; go and do something else</pre><p>Then you could use the command-line option<code><nobr>-dDEBUG</nobr></code> to create a version of the program whichproduced debugging messages, and remove the option to generate the finalrelease version of the program.<p>You can test for a macro <em>not</em> being defined by using<code><nobr>%ifndef</nobr></code> instead of<code><nobr>%ifdef</nobr></code>. You can also test for macro definitionsin <code><nobr>%elif</nobr></code> blocks by using<code><nobr>%elifdef</nobr></code> and <code><nobr>%elifndef</nobr></code>.<h4><a name="section-4.4.2">4.4.2 <code><nobr>ifmacro</nobr></code>: Testing Multi-Line Macro Existence</a></h4><p>The <code><nobr>%ifmacro</nobr></code> directive operates in the sameway as the <code><nobr>%ifdef</nobr></code> directive, except that itchecks for the existence of a multi-line macro.<p>For example, you may be working with a large project and not havecontrol over the macros in a library. You may want to create a macro withone name if it doesn't already exist, and another name if one with thatname does exist.<p>The <code><nobr>%ifmacro</nobr></code> is considered true if defining amacro with the given name and number of arguments would cause a definitionsconflict. For example:<p><pre>%ifmacro MyMacro 1-3      %error "MyMacro 1-3" causes a conflict with an existing macro. %else      %macro MyMacro 1-3              ; insert code to define the macro      %endmacro %endif</pre><p>This will create the macro "MyMacro 1-3" if no macro already existswhich would conflict with it, and emits a warning if there would be adefinition conflict.<p>You can test for the macro not existing by using the<code><nobr>%ifnmacro</nobr></code> instead of<code><nobr>%ifmacro</nobr></code>. Additional tests can be performed in<code><nobr>%elif</nobr></code> blocks by using<code><nobr>%elifmacro</nobr></code> and<code><nobr>%elifnmacro</nobr></code>.<h4><a name="section-4.4.3">4.4.3 <code><nobr>%ifctx</nobr></code>: Testing the Context Stack</a></h4><p>The conditional-assembly construct<code><nobr>%ifctx ctxname</nobr></code> will cause the subsequent code tobe assembled if and only if the top context on the preprocessor's contextstack has the name <code><nobr>ctxname</nobr></code>. As with<code><nobr>%ifdef</nobr></code>, the inverse and<code><nobr>%elif</nobr></code> forms <code><nobr>%ifnctx</nobr></code>,<code><nobr>%elifctx</nobr></code> and <code><nobr>%elifnctx</nobr></code>are also supported.<p>For more details of the context stack, see<a href="#section-4.7">section 4.7</a>. For a sample use of<code><nobr>%ifctx</nobr></code>, see <a href="#section-4.7.5">section4.7.5</a>.<h4><a name="section-4.4.4">4.4.4 <code><nobr>%if</nobr></code>: Testing Arbitrary Numeric Expressions</a></h4><p>The conditional-assembly construct <code><nobr>%if expr</nobr></code>will cause the subsequent code to be assembled if and only if the value ofthe numeric expression <code><nobr>expr</nobr></code> is non-zero. Anexample of the use of this feature is in deciding when to break out of a<code><nobr>%rep</nobr></code> preprocessor loop: see<a href="#section-4.5">section 4.5</a> for a detailed example.<p>The expression given to <code><nobr>%if</nobr></code>, and itscounterpart <code><nobr>%elif</nobr></code>, is a critical expression (see<a href="nasmdoc3.html#section-3.8">section 3.8</a>).<p><code><nobr>%if</nobr></code> extends the normal NASM expression syntax,by providing a set of relational operators which are not normally availablein expressions. The operators <code><nobr>=</nobr></code>,<code><nobr>&lt;</nobr></code>, <code><nobr>&gt;</nobr></code>,<code><nobr>&lt;=</nobr></code>, <code><nobr>&gt;=</nobr></code> and<code><nobr>&lt;&gt;</nobr></code> test equality, less-than, greater-than,less-or-equal, greater-or-equal and not-equal respectively. The C-likeforms <code><nobr>==</nobr></code> and <code><nobr>!=</nobr></code> aresupported as alternative forms of <code><nobr>=</nobr></code> and<code><nobr>&lt;&gt;</nobr></code>. In addition, low-priority logicaloperators <code><nobr>&amp;&amp;</nobr></code>,<code><nobr>^^</nobr></code> and <code><nobr>||</nobr></code> are provided,supplying logical AND, logical XOR and logical OR. These work like the Clogical operators (although C has no logical XOR), in that they alwaysreturn either 0 or 1, and treat any non-zero input as 1 (so that<code><nobr>^^</nobr></code>, for example, returns 1 if exactly one of itsinputs is zero, and 0 otherwise). The relational operators also return 1for true and 0 for false.<h4><a name="section-4.4.5">4.4.5 <code><nobr>%ifidn</nobr></code> and <code><nobr>%ifidni</nobr></code>: Testing Exact Text Identity</a></h4><p>The construct <code><nobr>%ifidn text1,text2</nobr></code> will causethe subsequent code to be assembled if and only if<code><nobr>text1</nobr></code> and <code><nobr>text2</nobr></code>, afterexpanding single-line macros, are identical pieces of text. Differences inwhite space are not counted.<p><code><nobr>%ifidni</nobr></code> is similar to<code><nobr>%ifidn</nobr></code>, but is case-insensitive.<p>For example, the following macro pushes a register or number on thestack, and allows you to treat <code><nobr>IP</nobr></code> as a realregister:<p><pre>%macro  pushparam 1   %ifidni %1,ip         call    %%label   %%label:   %else         push    %1   %endif %endmacro</pre><p>Like most other <code><nobr>%if</nobr></code> constructs,<code><nobr>%ifidn</nobr></code> has a counterpart<code><nobr>%elifidn</nobr></code>, and negative forms<code><nobr>%ifnidn</nobr></code> and <code><nobr>%elifnidn</nobr></code>.Similarly, <code><nobr>%ifidni</nobr></code> has counterparts<code><nobr>%elifidni</nobr></code>, <code><nobr>%ifnidni</nobr></code> and<code><nobr>%elifnidni</nobr></code>.<h4><a name="section-4.4.6">4.4.6 <code><nobr>%ifid</nobr></code>, <code><nobr>%ifnum</nobr></code>, <code><nobr>%ifstr</nobr></code>: Testing Token Types</a></h4><p>Some macros will want to perform different tasks depending on whetherthey are passed a number, a string, or an identifier. For example, a stringoutput macro might want to be able to cope with being passed either astring constant or a pointer to an existing string.<p>The conditional assembly construct <code><nobr>%ifid</nobr></code>,taking one parameter (which may be blank), assembles the subsequent code ifand only if the first token in the parameter exists and is an identifier.<code><nobr>%ifnum</nobr></code> works similarly, but tests for the tokenbeing a numeric constant; <code><nobr>%ifstr</nobr></code> tests for itbeing a string.<p>For example, the <code><nobr>writefile</nobr></code> macro defined in<a href="#section-4.3.3">section 4.3.3</a> can be extended to takeadvantage of <code><nobr>%ifstr</nobr></code> in the following fashion:<p><pre>%macro writefile 2-3+   %ifstr %2         jmp     %%endstr     %if %0 = 3       %%str:    db      %2,%3     %else       %%str:    db      %2     %endif       %%endstr: mov     dx,%%str                 mov     cx,%%endstr-%%str   %else                 mov     dx,%2                 mov     cx,%3   %endif                 mov     bx,%1                 mov     ah,0x40                 int     0x21 %endmacro</pre><p>Then the <code><nobr>writefile</nobr></code> macro can cope with beingcalled in either of the following two ways:<p><pre>        writefile [file], strpointer, length         writefile [file], "hello", 13, 10</pre><p>In the first, <code><nobr>strpointer</nobr></code> is used as theaddress of an already-declared string, and <code><nobr>length</nobr></code>is used as its length; in the second, a string is given to the macro, whichtherefore declares it itself and works out the address and length foritself.<p>Note the use of <code><nobr>%if</nobr></code> inside the<code><nobr>%ifstr</nobr></code>: this is to detect whether the macro waspassed two arguments (so the string would be a single string constant, and<code><nobr>db %2</nobr></code> would be adequate) or more (in which case,all but the first two would be lumped together into<code><nobr>%3</nobr></code>, and <code><nobr>db %2,%3</nobr></code> wouldbe required).<p>  The usual <code><nobr>%elifXXX</nobr></code>,<code><nobr>%ifnXXX</nobr></code> and <code><nobr>%elifnXXX</nobr></code>versions exist for each of <code><nobr>%ifid</nobr></code>,<code><nobr>%ifnum</nobr></code> and <code><nobr>%ifstr</nobr></code>.<h4><a name="section-4.4.7">4.4.7 <code><nobr>%error</nobr></code>: Reporting User-Defined Errors</a></h4><p>The preprocessor directive <code><nobr>%error</nobr></code> will causeNASM to report an error if it occurs in assembled code. So if other usersare going to try to assemble your source files, you can ensure that theydefine the right macros by means of code like this:

⌨️ 快捷键说明

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