EQU适用于非immediates x86

时间:2017-07-06 19:04:17

标签: assembly x86 nasm

我对汇编很新,我一直想知道是否有任何操作可以和EQU一样但是有寄存器?例如:

Boink EQU EAX

如果没有此类操作,是否有办法将BoinkEAX等同而不必使用RESB, RESD等等?

道歉,如果这个问题对你来说有点愚蠢,并提前感谢你。

我正在使用NASM。

1 个答案:

答案 0 :(得分:3)

这个问题似乎有些愚蠢,主要是因为你的动机并不清楚。你为什么要这样做?您的目标是使代码更具可读性,实质上是为其他难以理解的寄存器名称提供符号(人类可读)的名称吗?

如果是,您可以使用preprocessor macros。在块的顶部定义宏以引入符号名称,然后确保在块的末尾取消定义它以防止混淆。例如:

Max:

    %define value1 edx
    %define value2 ecx
    %define result eax

    sub  value1, value2
    sbb  result, result
    not  result
    and  result, value1
    add  result, value2

    %undef value1
    %undef value2
    %undef result

    ret

的情况,这可以使代码更具可读性。以上可以说是其中一种情况。它还可以更容易地更改寄存器分配,这在您使用(读取:基准测试)代码来确定最佳分配策略时尤其方便。

在MASM中,您可以使用TEXTEQU directive - 执行非常类似的操作,例如

value1  TEXTEQU  <edx>
value2  TEXTEQU  <ecx>
result  TEXTEQU  <eax>

但你必须be very careful with this。在实际代码中(至少,实际代码已被编写为高效,如果它不是有效的,为什么要在汇编中编写?),您几乎总是会重用寄存器多种用途。这意味着您的符号名称很快就会过时。你是否继续在整个代码中使用过时的名称?您是否为每个寄存器别名多个符号名称,涵盖所有可能的用途?您是否不断为寄存器定义,取消定义和重新定义新的符号名称?这些都不是好的选择,无论你做什么,你只会让代码更加混乱。

因此,您通常会看到汇编程序员所做的是在每条指令的旁边使用注释来解释该指令的内容。类似的东西:

; Uses branchless instructions to find the maximum of two integers.
; Parameters: EDX == value1
;             ECX == value2
; Returns:  Maximum integer value in EAX
; Clobbers: EDX
Max:
    sub  edx, ecx    ; edx <= (edx - ecx)
    sbb  eax, eax    ; eax <= (CF == 1) ? -1        :  0
    not  eax         ; eax <= (CF == 1) ? 0         : -1
    and  eax, edx    ; eax <= (CF == 1) ? 0         : (edx - ecx)
    add  eax, ecx    ; eax <= (CF == 1) ? (0 + ecx) : ((edx - ecx) + ecx)
    ret