64位或使用64位寄存器中的地址大小覆盖前缀 [英] Address-size override prefix in 64-bit or using 64-bit registers

查看:273
本文介绍了64位或使用64位寄存器中的地址大小覆盖前缀的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

in Assembly Addressing (64-bit), which way is better?

mov   cl, BYTE [ebx + .DATA]

mov   cl, BYTE [rbx + .DATA]

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

the opcode for first way is : 67 8a 4b .. and the opcode for second way is : 8a 4b ..

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

so if we use 32-bit register, we need to have a '0x67' prefix (Address-size override prefix) so i think we added an extra job !!!

,但我听说过(CACHE),最好使用'32-位而不是 64位

but i heard something about (CACHE) and it's better to use '32-bit' instead of '64-bit'

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

so which way is better at all ? and why ?

推荐答案

TL:DR:您基本上不需要地址大小的前缀。请使用64位寻址模式。

TL:DR: you basically never want address-size prefixes. Use 64-bit addressing modes.


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

I heard something about (CACHE) and it's better to use '32-bit' instead of '64-bit'

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

You're mixing up address-size with operand-size. 32-bit integers take half the space, so more of them fit in one cache line. Better spatial locality, less memory bandwidth.

选择64位模式的默认值是有原因的,在方便时,为了节省代码大小,您应该选择默认值当其他条件都相同时(使用32位寄存器的优点/ x86-64中的指令):

The defaults in 64-bit mode were chosen for a reason, and are what you should prefer when convenient, to save code-size when all else is equal (The advantages of using 32bit registers/instructions in x86-64):


  • 地址大小= 64位

  • operand-size = 32位

所以类似 mov ecx,[rdi] 是最有效的情况;其他尺寸需要REX或其他前缀。字节操作数大小使用不同的操作码代替前缀,但是写入8位寄存器可能会对完整寄存器的旧值产生错误的依赖性。首选 movzx 加载;

So something like mov ecx, [rdi] is the most efficient case; other sizes need REX or other prefixes. Byte operand-size uses different opcodes instead of prefixes but writing to 8-bit registers can have false dependencies on the old value of the full register. Prefer movzx loads; that's generally worth the extra byte of code-size for a 2-byte opcode.

如果您的电话号码是正确零扩展到64位,避免使用地址大小前缀,并使用

movzx ecx,  byte [rbx + .DATA]

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

Writing a 32-bit bit register implicitly zero-extends to 64-bit so you can use save cache footprint by using 32-bit data in memory.

如果索引 not 可能正确地零扩展或符号扩展为地址大小,您可能需要一条额外的说明才能实现( movsxd rcx,ebx mov ecx,ebx ),因此您可以使用64位寻址模式。

If an index might not be correctly zero- or sign-extended to address-size, you might need an extra instruction to make that happen (movsxd rcx, ebx or mov ecx, ebx) so you can use a 64-bit addressing mode.

[reg + sign_extended_disp32] 寻址模式很有趣,有趣的情况:它们仅适用于32位的所有符号地址。如果您知道整个阵列位于虚拟地址空间的低4GiB中,则可以避免使用 [ebx + .DATA] 以避免额外的指令扩展到64位,如果您知道RBX的上半部分可能存在垃圾。 (因此,在用户空间中使用静态地址,但在上半部分内核中可能不会,在64位虚拟地址空间的 high 32位中可能具有静态数据。)

[reg + sign_extended_disp32] addressing modes are interesting an interesting case: they only work at all of the symbol address fits in 32 bits. If you know that the whole array is in the low 4GiB of virtual address space, you could maybe get away with [ebx + .DATA] to avoid an extra instruction to extend to 64 bits, if you knew there might be garbage in the high half of RBX. (So static addresses in user-space, but maybe not in a high-half kernel where you might have static data in the high 32-bits of 64-bit virtual address space.)

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

If you know your pointers can be safely truncated to 32-bit (e.g. mmap(MAP_32BIT) or using the x32 ABI), you could even traverse a linked list or tree with an instruction like mov edi, [rdi] in a loop. Possibly useful for pointer-heavy data structures.

(您的问题是关于数组索引,而不是指针;在asm中,您通常希望将它们视为32位无符号整数,或64(如果数组可以很大)
或使用指针而不是 [reg + disp32] 遍历数组; disp32绝对地址仅在Linux中有效位置相关的可执行文件,或Windows LARGEADDRESSAWARE = no。)

(Your question was about array indices, not pointers; in asm you usually want to treat them as 32-bit unsigned integers, or 64 if arrays can be big. Or use pointers instead of [reg+disp32] to loop over an array; a disp32 absolute address only works in a Linux position-dependent executable, or Windows LARGEADDRESSAWARE=no.)

这篇关于64位或使用64位寄存器中的地址大小覆盖前缀的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆