【问题标题】:MASM - Differences between procedures and macrosMASM - 过程和宏之间的差异
【发布时间】:2019-11-19 20:18:12
【问题描述】:

我想知道 MASM 中的 macrosprocedures 有什么区别?

如果我调用 macro 而不是 procedure 来执行完全相同的操作,那么程序将执行的操作或汇编程序将如何组装我的代码有什么不同吗?

如果不是,我可能想了解为什么macros 存在?

谢谢。

【问题讨论】:

  • 宏的存在使内联变得容易(例如,使用不同的寄存器选择)

标签: assembly masm masm32


【解决方案1】:

宏只是文本替换。因此,每当您“调用”宏时,该调用将在编译时被宏的全部内容替换。当您调用一个过程时,通常只有该过程的一个实例,因此您将分支到程序中的不同位置。

考虑以下示例:

.586
.model flat, stdcall
option casemap :none

.code

; Multiply the argument by 3/2
Mul3_2 MACRO reg
    lea reg,[reg + reg*2]
    shr reg,1
ENDM

; Multiply the argument by 3/2 and return in eax
Mul3_2Proc PROC arg:DWORD
    mov eax,[arg]
    lea eax,[eax + eax*2]
    shr eax,1
    ret
Mul3_2Proc ENDP

main PROC
    Mul3_2 eax
    Mul3_2 ebx

    invoke Mul3_2Proc,eax    ; Equivalent to push eax / call Mul3_2Proc
    invoke Mul3_2Proc,ebx   
main ENDP

END main

如果我们让 MASM 的预处理器扩展我们的宏,我们会得到:

.586
.model flat, stdcall
option casemap :none

.code

; Multiply the argument by 3/2 and return in eax
Mul3_2Proc PROC arg:DWORD
    mov eax,[arg]
    lea eax,[eax + eax*2]
    shr eax,1
    ret
Mul3_2Proc ENDP

main PROC
    lea eax,[eax + eax*2]
    shr eax,1
    lea ebx,[ebx + ebx*2]
    shr ebx,1

    invoke Mul3_2Proc,eax    ; Equivalent to push eax / call Mul3_2Proc
    invoke Mul3_2Proc,ebx
main ENDP

END main

如您所见,在我们使用Mul3_2 宏的两个地方,该宏的内容已被插入,reg 替换为我们作为参数传递给宏的任何内容。宏本身不再存在于我们的代码中,因为它已经达到了它的目的。

另一方面,我们调用Mul3_2Proc 过程的两次事件保持不变。在运行时,每个位置都会跳转 (call) 到 Mul3_2Proc,然后在完成后,return 会返回调用站点。

【讨论】:

    【解决方案2】:

    在我看来,宏返回一个值

    所以你可以写:

      mov ax, myMacro( ...arguments... )
    

    类似于 VB.NET 中的 FunctionSub(或 C# 中的 void)

    【讨论】:

    • 除非它是一个扩展为编译时常量、寄存器名称或内存地址的单行宏,否则您不能将它用作mov 到 AX 的源操作数.即作为 C 预处理器之类的文本替换。 没有类似于 VB.NET 中的函数或非 void C 函数。宏 = 宏体的内联(如果它由指令组成)。宏和函数可以返回值(在任何你想要的寄存器中)。
    • 你是对的,这不会编译,我已经有一段时间没有测试宏了。但它可以返回一个值。
    猜你喜欢
    • 2011-01-03
    • 2010-10-19
    • 2018-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-13
    • 2010-11-15
    相关资源
    最近更新 更多