首页 > 解决方案 > 使用宏在 MASM 中除数?

问题描述

我正在尝试编写一个 MASM 宏,它接受一个数字并将其除以二:

mCalculateDiscount MACRO originalPrice
    PUSH EDX
    PUSH ECX
    MOV  EDX, 0
    MOV  EAX, originalPrice
    MOV  ECX, 2
    DIV  ECX
    POP  ECX
    POP  EDX
ENDM

答案将保存在 EAX 中,这种方法是错误的,哪种方法是正确的,使用宏或过程?

标签: assemblymasm

解决方案


对于真正归结为一条指令的操作(不计算加载操作数的代码),我认为您通常会直接编写它,而不使用宏。

像这样的宏效率低下,因为它没有考虑周围的代码。如果您在 EDX 中没有任何重要数据怎么办?那么EDX的push/pop就是一种浪费。ECX 也是如此。或者,也许在您周围的代码中,ECX 用于其他用途,但 ESI 可用;如果直接编码,您可以只使用 ESI 作为除数。使用宏,您将失去这个机会。

如果您的代码变得如此复杂以至于如果没有像这样的宏就无法保持其井井有条,那么可能是时候将其移植到像 C 这样的高级语言了。您的内置 push/pop 的宏正在做一个弱版本寄存器分配,实际的编译器可以更有效地完成。

最后,正如 Erik Eidt 指出的那样,使用 DIV 除以二是非常低效的;您应该改为右移(可能快 10 倍左右),并且它还避免了需要一堆额外的寄存器。整个宏可以替换为

    MOV EAX, originalPrice
    SHR EAX, 1

推荐阅读