【问题标题】:Get the upper half of the EAX register获取 EAX 寄存器的上半部分
【发布时间】:2013-03-05 17:27:00
【问题描述】:

在x86汇编语言中,有没有办法获取EAX寄存器的上半部分?我知道AX 寄存器已经包含了EAX 寄存器的下半部分,但是我还不知道有什么方法可以获得上半部分。

我知道mov bx, ax 会将eax 的下半部分移动到bx,但我想知道如何将eax 的上半部分也移动到bx

【问题讨论】:

  • 只需将其下移 16 位。
  • 要么做shr eax, 16,然后移动。 (破坏eax),或者做mov ebx, eaxshr ebx, 16(将ebx的上半部分归零)我不确定在bx上进行操作是否会自动将ebx的上半部分归零反正。所以如果是这样的话,你还不如选择后一种方法。
  • ror eax,16 mov bx,ax ror eax,16 如果你想保持 eax/ebx 的上半部分不变
  • @Mysticial 在bx 上执行操作不会自动将ebx 的上半部分归零。但是,在 x86-64 中,使用 ebx(但不是 bxblbh)作为 dest 将 rbx 的前 32 位归零。
  • @nrz 啊。很高兴知道。我知道 x64 上的归零行为。我只是不确定这种行为在早期是否已经存在。

标签: assembly x86


【解决方案1】:

如果你想保留EAX和EBX的上半部分:

rol eax, 16
mov bx, ax
rol eax, 16

如果有可用的暂存寄存器,则效率更高(并且不会为以后读取 EAX 的指令引入额外的延迟):

mov ecx, eax
shr ecx, 16
mov  bx, cx

如果您不需要其中任何一个,mov ebx, eax / shr ebx, 16 是显而易见的方法,并避免使用任何partial-register stalls or false dependencies

【讨论】:

  • 这种情况下,eax会恢复到原来的值吗?
  • 是的,会的。 rolror 循环旋转位。请参阅文档。
  • 或者只是shr eax,16 ??
  • @JesonPark 当然,但这会破坏 eax 原始值的 0 到 15 位。
  • 如果有可能,您可以再次将数据移动到 EAX!
【解决方案2】:

如果您不介意将 bx 的原始值(ebx 的低 16 位)转移到 ebx 的高 16 位,则只需 1 条指令:

shld ebx,eax,16

这不会修改eax

【讨论】:

  • 或者用BMI2,rorx ebx, eax, 16设置ebx = word_swap(eax)。与shld 不同,它不依赖于 EBX 的旧值,并且是在所有支持它的 CPU 上具有 1c 延迟的单个 uop。 (agner.org/optimize)
【解决方案3】:

我会这样做:

mov ebx,eax
shr ebx, 16

ebx 现在包含 eax 的前 16 位

【讨论】:

    【解决方案4】:

    对于 16 位模式,这是最小(不是最快)的代码:只有 4 个字节。

    push eax  ; 2 bytes: prefix + opcode 
    pop ax    ; 1 byte: opcode
    pop bx    ; 1 byte: opcode
    

    比占用5字节内存的单指令shld ebx,eax,16还要紧凑。

    【讨论】:

    • 这些指令大小适用于 16 位模式。在 32 位代码中,总共 5 个字节,shld ebx,eax,16 是 4 个字节。 (并且shld 在许多 CPU 上速度更快。)
    • 谢谢彼得。 shld ebx, eax, 16 占用 5 个字节(66 0F A4 D8 10)。 shld r32, r32, clshld r16, r16, immediate 是 4 个字节。为什么推送指令是 5 个字节?
    • 我说的是in 32-bit mode,默认操作数大小是32,这比现代计算机上的16-bit模式更常见。 (但仍然大部分被 64 位模式淘汰)。在 32 位模式下,pop ax 需要 66 前缀,但 push eax 不需要,因此总共得到 1 + 2 + 2 = 5。同样,shld r32, r32, imm8 在 32 中不需要任何前缀或 64 位模式。 (顺便说一句,你不想使用shld r,r,cl,因为它在 Skylake 上是 4 微欧,而在 shld r,r,imm8 上是 1。agner.org/optimize
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多