rax = 1的最短Intel x86-64操作码?

时间:2015-11-20 11:25:06

标签: assembly x86-64 micro-optimization code-size

rax设置为1的最短Intel x86-64操作码是什么?

我尝试了xor rax,raxinc al(在NASM语法中);它给出了5字节操作码48 31 c0 fe c0。是否有可能以4个字节实现相同的结果?

您可以修改或读取任何其他寄存器,但不能假设某些特定值将来自之前的说明中的任何一个。

2 个答案:

答案 0 :(得分:6)

由于push有一个字节立即编码,寄存器有一个单字节弹出,因此可以用三个字节完成:6a 01 58push $1 / pop %rax

答案 1 :(得分:2)

对于任何已知的前置条件,有一些技巧比push imm8 / pop rax 3字节解决方案更有效(就速度而言)。

对于速度mov eax, 1有许多优点,因为它没有任何输入依赖性,并且它只有一条指令。可以开始乱序执行(以及依赖它的任何事情),而无需等待其他事情。 (请参阅Agner Fog's guides代码wiki)。

显然,其中许多利用了writing a 32-bit register zeros the upper half这一事实,以避免OP代码的不必要的REX前缀。 (另请注意,Silvermont上的xor rax,rax不是special-cased as a zeroing idiom。它只识别32位寄存器的xor-zeroing,如eax或r10d,而不是rax或r10。)

如果您在任何注册表中都有一个小的已知常量,则可以使用

lea   eax, [rcx+1]    ; 3 bytes: opcode + ModRM + disp8

disp8可以将位移编码从-128到+127。

如果eax中有一个奇数,and eax, 1也是3个字节。

在32位代码中,inc eax仅占用一个字节,但那些inc / dec操作码被重新用作AMD64的REX前缀。所以xor eax,eax / inc eax在x86-64代码中是4个字节,但在32位代码中只有3个字节。但是,如果在mov eax,1上保存1个字节就足够了,并且LEA或AND不起作用,这比推/弹更有效。

相关问题