64位或使用64位寄存器的地址大小覆盖前缀

问题描述 投票:0回答:1

在汇编寻址(64位)中,哪种方法更好?

mov   cl, BYTE [ebx + .DATA]

mov   cl, BYTE [rbx + .DATA]

第一种方法的操作码是:67 8a 4b ..第二种方法的操作码是:8a 4b ..

所以,如果我们使用32位寄存器,我们需要有一个'0x67'前缀(地址大小覆盖前缀),所以我认为我们增加了一个额外的工作!!

但是我听到了有关(CACHE)的信息,最好使用'32位'而不是'64位'

那么哪种方法更好呢?以及为什么?

assembly x86-64
1个回答
0
投票

我听说过有关(CACHE)的信息,最好使用'32位'而不是'64位'

您正在将地址大小与操作数大小混合。 32位整数占用一半的空间,因此更多的它们可以容纳在一个缓存行中。更好的空间局部性,更少的内存带宽。

选择64位模式下的默认值是有原因的,当方便时,您应该选择它作为默认值,以便在所有其他条件相同时保存代码大小(The advantages of using 32bit registers/instructions in x86-64:]

  • 地址大小= 64位
  • 操作数大小= 32位

所以mov ecx, [rdi]之类的东西是最有效的情况;其他尺寸需要REX或其他前缀。字节操作数大小使用不同的操作码而不是前缀,但是写入8位寄存器可能会对完整寄存器的旧值有错误的依赖性。首选movzx负载;对于2字节的操作码来说,通常值得花额外的代码大小字节。


如果您的数字正确零扩展为64位,请避免使用地址大小的前缀并使用

movzx ecx,  byte [rbx + .DATA]

写入32位位寄存器隐式零扩展到64位,因此您可以通过使用内存中的32位数据来使用节省缓存的空间。

[如果您知道您的指针可以安全地截断为32位(例如mmap(MAP_32BIT)或使用x32 ABI),则可以循环使用mov edi, [rdi]之类的指令遍历链接列表。

© www.soinside.com 2019 - 2024. All rights reserved.