assembly - 为什么使用 `xor` 比使用 `mov` 占用的字节少?

标签 assembly x86-64 machine-code code-size

为了将 x 设置为零 (x = 0),我的 csapp 书指出了两种方法。

首先:

xorq %rcx, %rcx

第二个:

movq $0, %rcx

它还告诉我们第一个只需要 3 个字节,但是第二个需要 7 个字节。

这两种方式如何运作?为什么第一个占用的字节数比第二个少?

最佳答案

因为mov需要更多空间来编码其 32 位立即源操作数。
xor只需要 ModRM 字节对其操作数进行编码。

两者都不需要 REX 前缀,所以您应该比较 2 字节 xor %ecx,%ecx针对 5 字节 mov $0, %ecx Why do x86-64 instructions on 32-bit registers zero the upper part of the full 64-bit register?
GAS 不会为您进行此优化,并且 movq给你 mov $sign_extended_imm32, %r/m64编码而不是特殊情况 5 字节 mov $imm32, %r32省略 ModRM 字节的编码。
(除非您使用 as -O2,在这种情况下它将是 optimize the operand-size like NASM。请注意 gcc -O2 -c foo.s 不会将优化选项传递给 as。)

(如 CS:APP example uses idivq with two operands? 中所述,CS:APP 似乎充满了 asm 错误。这不是无效语法错误,只是错过了优化。)


不幸的是没有mov的编码使用符号扩展的 8 位立即数,否则我们可以有 3 字节 mov reg, imm8 . (https://www.felixcloutier.com/x86/mov)。 (令我惊讶的是,x86-64 的迭代没有将它释放的操作码字节之一重新用于像这样的漂亮 mov 编码,可能与 BMI1 或其他东西混为一谈。)

有关 x86 指令编码的更多详细信息,请阅读英特尔的第 2 卷手册并查看反汇编,以及 https://wiki.osdev.org/X86-64_Instruction_Encoding是一个很好的概述,比英特尔的手册更简洁。

另见 What is the best way to set a register to zero in x86 assembly: xor, mov or and?有关异或归零为何最佳的更多详细信息:在某些 CPU 上,特别是 P6 系列和 Sandybridge 系列,它具有优于 mov 的微体系结构优势除了简单的代码大小。

关于assembly - 为什么使用 `xor` 比使用 `mov` 占用的字节少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58090417/

相关文章:

assembly - nasm 指令和宏的缩进

assembly - rip 可以与具有 RIP 相对寻址的另一个寄存器一起使用吗?

x86 - 用于 x86 (MASM) 汇编的免费 IDE + 汇编器 + 软件模拟器?

assembly - 是否可以暂时抑制单个 ret 指令的 Intel CET,或者以其他方式使用 retpolines?

assembly - 帮助 68k 汇编 - 跳转表?

assembly - 整数溢出问题

c++ - compare_exchange C++ 函数如何确定竞争条件?

c++ - 在 C 和 C++ 中调用函数时 EAX 寄存器的初始化差异

c - 汇编 如何将 IMUL 操作码(只有一个操作数)翻译成 C 代码

c - 如何将机器代码发送到特定处理器?