如何将 .if、.else、.elseif 用于 x86 汇编语言

How to use .if, .else, .elseif for x86 Assembly language

我在处理程序集的 .if、.else 等语句时遇到了一些问题。

我的代码必须就地反转数字数组,并且它必须适用于不同的数据类型。我有一个 if 语句来检查数据的类型。如果它是 BYTE 类型它将进入第一个 if 语句,如果它是 WORD 它将进入下一个,如果它是 DWORD 它将进入第三个。我的问题是编译器为不会执行的代码块抛出错误。在当前代码中,我将数组设置为字节,因此它会为最后 2 个 if 语句块抛出错误。你能给我一些关于如何解决这个问题的建议吗?

numbers BYTE 10h, 20h, 30h, 40h, 50h, 60h, 70h, 80h, 90h

L1:

.if (ebx == 1) 
    mov al, numbers[esi]
    xchg al, numbers[edi]
    mov numbers[esi], al 
.elseif (ebx == 2) 
    mov ax, numbers[esi]
    xchg ax, numbers[edi]
    mov numbers[esi], ax 
.else 
    mov eax, numbers[esi]
    xchg eax, numbers[edi]
    mov numbers[esi], eax
.endif
add esi, (type_of_numbers)
sub edi, (type_of_numbers)

Loop L1

根据需要添加大小覆盖(BYTE PTR 数字[esi]、WORD PTR ...、DWORD PTR ...)。 – 迈克尔

.if / .elseif 运行时 检查 ,而不是像 C 那样的 assemble-time #if / #else。这就是为什么所有块都必须 assemble 正确,即使它们不匹配 numbers.

的类型

这看起来非常效率低下;您肯定在 assemble 时知道 numbers 的类型,例如 TYPE numbers,并且想使用与该类型宽度匹配的访问?

MASM 有 assemble-time IFELSE(注意缺少 .)用于基于常量的条件装配。那会让你只 assemble 匹配 numbers 声明的块,因此不需要任何大小覆盖。

and see also https://msdn.microsoft.com/en-us/library/4bd8b239.aspx 回复:if MASM 中的指令。

所以我认为你会做类似

的事情
IF       TYPE numbers == 1
   ... byte swap
ELSEIF   TYPE numbers == 2 
   ... word swap
ELSE
   ... dword swap
ENDIF

我不是 100% 确定您可以在 IF / ELSEIF 指令中使用 TYPE symbol


(当然,如果你关心效率,你就不会使用 xchg [mem], reg,因为这是一个带有完整内存屏障的原子交换:不幸的是,它暗示了一个 lock 前缀。)