编码汇编代码行 "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.o
或 otool -tv file.o
删除 assemble 目标文件。 (命令及其开关可能有所不同;这些是当前的 Apple 工具。)
通常会找到形式为
的汇编代码行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.o
或 otool -tv file.o
删除 assemble 目标文件。 (命令及其开关可能有所不同;这些是当前的 Apple 工具。)