gpt4 book ai didi

c++ - 按照每个通用寄存器的用途对 x86 程序集进行编码是否有必要或更容易

转载 作者:太空狗 更新时间:2023-10-29 20:36:11 25 4
gpt4 key购买 nike

一般来说,按照每个寄存器的用途编写 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在做这样的任务时通常使用第二种方法,它不使用寄存器取决于它的目的,相反,编译器只根据它的目的选择使用什么寄存器“ volatile ”或“非 volatile ”特征(调用函数后)。正因为如此,所有高级程序设计语言编程的软件反汇编都采用第二种方法。

另一个有趣的事实是,在 ARM 语言中,GPR 都是同一个用途,被命名为 R0-R7,这意味着用它编码时,代码会更类似于 2nd code。

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

最佳答案

以下各寄存器的用途主要实现:

  • 代码密度

    例如使用 A register1 通常会减少移动、算术、逻辑和 IO2 等常见操作的代码大小。
    使用 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

    要困难得多。

  • 地道编程

    SP的使用因为堆栈指针由许多指令( callretpush 、 ...)承担。
    可以避免使用 SP作为堆栈指针,但它不会很惯用(也不高效)。

  • 更少的数据移动

    在实模式下,只有少数寄存器可以用作基址(其中之一是 B 寄存器)。
    将地址保存在 B 中从一开始就避免将它们移入其中。尽管寄存器-寄存器移动如今不需要执行单元,但它们使源代码更难阅读4

今天大多数惯用的寄存器用法都放宽了5,因为太多的特定用途寄存器减少了编译器可以做的优化(并且溢出到堆栈上是昂贵的)。

CPU 非常复杂,如果您想编写速度代码,那么您应该只考虑速度指标。惯用的寄存器用法不是其中之一,一方面是 there is not a single A , B or C register在微架构级别,程序员看到的“注册”只是一个人类概念(好吧,也是一个前端概念)。


1ALAXEAXRAX 形式br/>2 mov A, [mem]使用操作码 A0A1,而 mov B, [mem]使用 8A 1E8B 1Eadd也是如此和类似的。 in , out , div , mul强制使用 A .
3 但不是抓取和解码。
4 数据移入寄存器是否有等效的“意大利面条代码”?
5 例如考虑各种寻址模式或imul说明

关于c++ - 按照每个通用寄存器的用途对 x86 程序集进行编码是否有必要或更容易,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39629753/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com