编码汇编代码行 "xorq, %rdx, %rdx" 需要多少字节?

How many bytes does it take to encode the assembly-code line "xorq, %rdx, %rdx"?

通常会找到形式为

的汇编代码行
xorq, %rdx, %rdx

此操作的一个用途是将寄存器 %rd 设置为零,利用 x^x = 0 这一事实。在 C 中,它与设置 x = 0 相同。

表达这个操作的另一种更直接的方式是

movq [=12=], %rdx

我的问题是,我们如何计算对这两种不同的实现进行编码所需的字节数?我相信第一个答案是 3 个字节,而第二个答案需要 7 个字节。

可以从 x86 参考手册中找出此类问题的答案,但通常编写小型测试汇编程序会更快更容易,assemble,然后disassemble它。

$ cat > test.s <<EOF
        .text
        .globl x
x:
        xorl %edx, %edx
        xorq %rdx, %rdx
        movl [=10=], %edx
        movq [=10=], %rdx
EOF
$ as test.s -o test.o
$ objdump -d test.o

test.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <x>:
   0:   31 d2                   xor    %edx,%edx
   2:   48 31 d2                xor    %rdx,%rdx
   5:   ba 00 00 00 00          mov    [=10=]x0,%edx
   a:   48 c7 c2 00 00 00 00    mov    [=10=]x0,%rdx

所有这四个指令都会清除 RDX,因为 x86-64 自动 zero-extends 任何 32 位操作的结果到寄存器的全宽度。你可以从反汇编转储中看到它们分别用两个、三个、五个和七个字节编码,所以你原来的猜测是正确的。

使用较长指令的一个原因是 XOR 设置条件代码(因此在 xor %edx, %edx 之后您将有 ZF=1、OF=SF=PF=CF=0 和 AF 未定义)但 MOV才不是。如果您正在尝试 fine-tune 安排一些 hand-written 程序集,这可能很重要。

过去,assemblers 会生成显示编码指令的列表文件,您可以看到每条指令占用多少字节。如果做不到这一点,您可以将此代码放在一些 file.s:

a:  xorq  %rdx, %rdx
b:  movq [=10=], %rdx
c:

然后 assemble 它与 as -o file.o file.s 并查看带有 nm file.o 的符号,显示如下:

0000000000000000 t a
0000000000000003 t b
000000000000000a t c

从中可以看出xorq %rdx, %rdx需要316−016 = 3个字节,而movq [=15= ], %rdx 需要 a16−316 = 7 个字节。

您也可以使用 objdump -disassemble file.ootool -tv file.o 删除 assemble 目标文件。 (命令及其开关可能有所不同;这些是当前的 Apple 工具。)