• 汇编语言替换(&)、文本(<>)、字符(!)、展开(%)运算符简述

    下述四个汇编运算符使得宏更加灵活:

    & 替换运算符
    <> 文字文本运算符
    ! 文字字符运算符
    % 展开运算符

    替换运算符(&)

    替换运算符(&)解析对宏参数名的有歧义的引用。宏 mShowRegister 显示了一个 32 位寄存器的名称和十六进制的内容。示例调用如下:

    .code
    mShowRegister ECX

    下面是调用 mShowRegister 产生的示例输出:

    ECX=00000101

    在宏内可以定义包含寄存器名的字符串变量:

    mShowRegister MACRO regName
    .data
    tempStr BYTE "regName=",0

    但是预处理程序会认为 regName 是字符串文本的一部分,因此,不会将其替换为传递给宏的实参值。相反,如果添加了 & 运算符,它就会强制预处理程序在字符串文本中插入宏实参 ( 如 ECX)。下面展示的是如何定义 tempStr:

    mShowRegister MACRO regName
    .data
    tempStr BYTE "&regName=",0

    展开运算符(%)

    展开运算符(%)展开文本宏并将常量表达式转换为文本形式。有几种方法实现该功能。若使用的是 TEXTEQU,% 运算符就计算常量表达式,再把结果转换为整数。

    在下面的例子中,% 运算符计算表达式 (5+count),并返回整数 15 ( 以文本形式 ):

    count = 10
    sumVal TEXTEQU %(5 + count)            ;="15"

    如果宏请求的实参是整数常量,% 运算符就能使程序具有传递一个整数表达式的灵活性。计算这个表达式得到结果值,然后将这个值传递给宏。例如,调用 mGotoxyConst 时,计算表达式的结果分别为 50 和 7:

    mGotoxyConst %(5 * 10), %(3 + 4)

    预处理程序将产生如下语句:

    1  push edx
    1  mov dh,7
    1  mov dl,50
    1  call Gotoxy
    1  pop edx

    % 在一行的首位

    当展开运算符 (%) 是一行源代码的第一个字符时,它指示预处理程序展开该行上的所有文本宏和宏函数。比如,假设想在汇编时将数组大小显示在屏幕上。下面的尝试不会产生期望的结果:

    .data
    array DWORD 1,2,3,4,5,6,7,8
    .code
    ECHO The array contains (SIZEOF array) bytes
    ECHO The array contains %(SIZEOF array) bytes

    屏幕输出没什么用:

    The array contains (SIZEOF array) bytes
    The array contains %(SIZEOF array) bytes

    反之,如果用 TEXTEQU 编写包含 (SIZEOF array) 的文本宏,那么该宏就可以展开为之后的代码行:

    TempStr TEXTEQU %(SIZEOF array)
    %   ECHO The array contains TempStr bytes

    产生的输出如下所示:

    The array contains 32 bytes

    显示行号

    下面的宏 Mul32 将它前两个实参相乘,乘积由第三个实参返回。其形参可以是寄存器、内存操作数和立即数 ( 乘积除外 ):

    Mul32 MACRO op1, op2, product
        IFIDNI <op2>,<EAX>%
            LINENUM TEXTEQU %(@LINE)
            ECHO ----------------------------------------------
    %       ECHO * Error on line LINENUM: EAX cannot be the second
            ECHO * argument when invoking the MUL32 macro.
            ECHO ----------------------------------------------
        EXITM
        ENDIF
        push eax
        mov eax,op1
        mul op2
        mov product,eax
        pop eax
    ENDM

    Mul32 要检查的一个重要要求是:EAX 不能作为第二个实参。这个宏有趣的地方是,它显示的是其调用者的行号,这样更加易于追踪并解决问题。首先定义文本宏 LINENUM,它引用的 @LINE 是一个预先定义的汇编运算符,其功能为返回当前源代码行的编号:

    LINENUM TEXTEQU % ((@LINE)

    接着,在含有 ECHO 语句的代码行第一列上的展开运算符 (%) 使得 LINENUM 被展开:

    %   ECHO * Error on line LINENUM: EAX cannot be the second

    假设如下宏调用发生在程序的 40 行:

    MUL32 val1, eax,val3

    那么,汇编时将显示如下信息:

更多...

加载中...