rax=1 的最短英特尔 x86-64 操作码?

Shortest Intel x86-64 opcode for rax=1?

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

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

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

由于有一个用于压入的字节立即编码和一个用于寄存器的单字节弹出编码,这可以用三个字节完成:6a 01 58,或push / pop %rax

在任何已知的前提条件下,有一些技巧比推送 imm8/pop rax 3 字节解决方案更有效(在速度方面)。

速度mov eax, 1有很多优点,因为它没有任何输入依赖性,而且只有一条指令。乱序执行可以在它上面开始(以及任何依赖它的东西)而不用等待其他东西。 (参见 Agner Fog's guides and the 标签 wiki)。

显然其中许多利用了 writing a 32-bit register zeros the upper half, to avoid the unnecessary REX prefix of the OP's code. (Also note that xor rax,rax is not 在 Silvermont 上的事实。它只识别 32 位寄存器的异或归零,如 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 不起作用,这比 push/pop.

更有效