在汇编寻址(64位)中,哪种方法更好?
mov cl, BYTE [ebx + .DATA]
或
mov cl, BYTE [rbx + .DATA]
?
第一种方法的操作码是:67 8a 4b ..
第二种方法的操作码是:8a 4b ..
所以,如果我们使用32位寄存器,我们需要有一个'0x67'前缀(地址大小覆盖前缀),所以我认为我们增加了一个额外的工作!!
但是我听到了有关(CACHE)的信息,最好使用'32位'而不是'64位'
那么哪种方法更好呢?以及为什么?
我听说过有关(CACHE)的信息,最好使用'32位'而不是'64位'
您正在将地址大小与操作数大小混合。 32位整数占用一半的空间,因此更多的它们可以容纳在一个缓存行中。更好的空间局部性,更少的内存带宽。
选择64位模式下的默认值是有原因的,当方便时,您应该选择它作为默认值,以便在所有其他条件相同时保存代码大小(The advantages of using 32bit registers/instructions in x86-64:]
所以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]
之类的指令遍历链接列表。