按照每个通用寄存器的用途编写x86汇编是否必要或更容易

时间:2016-09-22 03:26:22

标签: c++ assembly optimization x86 cpu-registers

一般来说,是否有必要或更容易按照每个注册的目的编码x86程序集?

x86体系结构中的寄存器每个都是首先设计用于特殊目的,但现代编译器似乎并不关心它们的使用(除非在某些特殊条件下,例如REP MOV或MUL)。

那么,根据每个寄存器的用途,编码会更容易还是更优化?(不管与某些寄存器相同的特殊指令(或编码))

例如(我可以改用REP MOVSB或LODSB STOSB,但只是为了演示):

第一个代码:

LEA ESI,[AddressOfSomething]
LEA EDI,[AddressOfSomethingElse]
MOV ECX,NUMBER_OF_LOOP
LoopHere:
MOV AL,[ESI]
ADD AL,8
MOV [EDI],AL
ADD ESI,1
ADD EDI,1
CMP AL,0
JNZ LoopHere
TheEnd:
;...

第二代码:

LEA ECX,[AddressOfSomething]
LEA EDX,[AddressOfSomethingElse]
MOV EBX,NUMBER_OF_LOOP
LoopHere:
MOV AL,[ECX]
ADD AL,8
MOV [EDX],AL
ADD ECX,1
ADD EDX,1
CMP AL,0
JNZ LoopHere
TheEnd:
;...

我使用的编译器 - Visual Studio 2015在执行此类任务时通常使用第二种方法,它不使用寄存器取决于它的用途,相反,编译器只选择基于其使用的寄存器' “易变”或“非易失”特征(在调用函数后)。因此,所有高级编程语言编程软件反汇编都使用第二种方法。

另一个有趣的事实是,在ARM语言中,GPR都具有相同的用途,并且被命名为R0-R7,这意味着当使用它时代码,代码将更类似于第二代码。

总而言之,我认为这两个代码使用相同的指令,因此无论我使用哪个寄存器,它都应该具有相同的速度。但我是对的吗?哪个代码更容易编码?

1 个答案:

答案 0 :(得分:5)

遵循每个寄存器的目的主要是:

  • 代码密度

    例如,使用A寄存器 1 通常会减少常用操作的代码大小,例如移动,算术,逻辑和IO 2
    使用C寄存器进行计数可让您利用jcxz系列指令,避免明确比较 movsd和类似的非常“密集”的指令,他们执行复杂的操作,否则将需要大量的代码。

    然而code density doesn't mean "faster"由于x86明显是CISC这一事实,复杂指令可能比等效的一系列更简单的指令 3 需要更多的时间来执行。

  • 可读性

    rep movsd这样的指令实际上是一种编码将数据从源移动到目的地的循环的“高级”方式。
    解析周期

    push eax
    pushf
    .loop:
      mov eax, DWORD [esi]
      mov DWORD [es:edi], eax
    
      add esi, 4*(1-D*2)
      add edi, 4*(1-D*2)
    
      dec ecx
      jnz .loop
    popf
    pop eax
    

    要困难得多。

  • 惯用语编程

    许多说明(SPcallret,...)假定使用push作为堆栈指针。
    可以避免使用SP作为堆栈指针,但它不会非常惯用(也不高效)。

  • 减少数据移动

    在实模式下,只有少数寄存器可用作基址(其中一个是B寄存器)。
    从头开始在B中保留地址会避免以后将其移入其中。虽然寄存器寄存器移动今天不需要执行单元,但它们使源更难以读取 4

大多数惯用寄存器用法今天已经放宽了 5 因为太多的特定用途寄存器会减少编译器可以做的优化(并且溢出到堆栈上的代价很高)。

CPU非常复杂,如果您想编写速度代码,那么您应该只考虑速度指标。惯用寄存器的使用不是其中之一,因为在微架构层面上there is not a single A, B or C register所以“注册”的一件事就是程序员看到它们只是一个人类概念(好吧,还有一个前端概念)。 / p>

1 在其表格 AL AX EAX RAX <登记/> 2 mov A, [mem]使用操作码 A0 A1 ,而mov B, [mem]使用 8A 1E 8B 1E add和类似的情况也是如此。 inoutdivmul强制使用A
3 但不要取回和解码。
4 是否有相当于“意大利面条代码”的数据移入寄存器?
5 例如考虑各种寻址模式或imul指令