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

问题描述

通常会找到以下形式的汇编代码行

xorq,%rdx,%rdx

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

表达此操作的另一种更直接的方法是

movq $0,%rdx

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

解决方法

在过去,汇编程序会生成列出编码指令的清单文件,您可以看到每个指令占用了多少字节。失败的话,您可以将这段代码放在一些file.s中:

a:  xorq  %rdx,%rdx
b:  movq $0,%rdx
c:

然后用as -o file.o file.s进行组装,并用nm file.o查看符号,该符号显示为:

0000000000000000 t a
0000000000000003 t b
000000000000000a t c

其中您可以看到xorq %rdx,%rdx要求3 16 −0 16 = 3个字节,而movq $0,%rdx需要一个 16 -3 16 = 7个字节。

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

,

可以从x86参考手册中找到此类问题的答案,但是编写一个小型测试组装程序,组装然后反汇编它通常会更快,更容易。

$ cat > test.s <<EOF
        .text
        .globl x
x:
        xorl %edx,%edx
        xorq %rdx,%rdx
        movl $0,%edx
        movq $0,%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    $0x0,%edx
   a:   48 c7 c2 00 00 00 00    mov    $0x0,%rdx

所有这四个指令清除RDX,因为x86-64自动将任何32位运算的结果零扩展到寄存器的全宽度。您可以从反汇编转储中看到,它们分别由两个,三个,五个和七个字节编码,因此您的原始推测是正确的。

使用更长指令的原因是XOR设置了条件代码(因此在xor %edx,%edx之后,您将拥有ZF = 1,OF = SF = PF = CF = 0和AF未定义),但是MOV没有。如果您要微调某些手写程序集的计划,这可能很重要。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...