使用宏在 MASM 中划分数字?

Dividing numbers in MASM using macros?

我正在尝试编写一个 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 里面,这种方法是错误的,哪种方法是正确的,使用宏还是过程?

对于真正归结为单个指令的操作(不算加载操作数的代码),我认为您通常会直接编写它,而无需诉诸宏。

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

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

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

    MOV EAX, originalPrice
    SHR EAX, 1