【问题标题】:How many bytes does it take to encode the assembly-code line "xorq, %rdx, %rdx"?对汇编代码行“xorq, %rdx, %rdx”进行编码需要多少字节?
【发布时间】:2020-08-24 14:00:42
【问题描述】:

常见的汇编代码行格式为

xorq, %rdx, %rdx

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

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

movq $0, %rdx

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

【问题讨论】:

标签: assembly x86-64 machine-code


【解决方案1】:

在过去,汇编程序会生成显示编码指令的列表文件,您可以看到每条指令占用了多少字节。如果做不到这一点,你可以把这段代码放在file.s

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

然后将其与as -o file.o file.s 组合在一起,并查看带有nm file.o 的符号,显示如下:

0000000000000000 吨 0000000000000003 t b 000000000000000 吨 c

从中可以看到xorq %rdx, %rdx需要316-016 = 3个字节,而movq $0, %rdx需要16- 316 = 7 个字节。

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

【讨论】:

  • 如今的汇编程序仍然可以生成列表 :) 例如 as -alnasm -l
  • @Jester:我说“clang:警告:编译期间未使用的参数:'-al' [-Wunused-command-line-argument]”。 (是苹果 clang 版本 11.0.0 (clang-1100.0.33.17)。)
  • 这听起来更像是 C 编译器(驱动程序)警告,而不是汇编器警告。我没有 mac 但在 linux 上,如果你想使用 gcc,你需要做类似-Wa,-al 之类的操作,以使其将选项传递给汇编器。
  • @Jester: as(在 Apple 工具中)使用适当的组装选项调用 Clang。似乎没有请求列表的选项。
  • 哦,好的。无赖。
【解决方案2】:

可以从 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 位操作的结果零扩展至寄存器的整个宽度。从反汇编转储中可以看出,它们分别以 2、3、5 和 7 个字节进行编码,因此您最初的猜测是正确的。

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

【讨论】:

  • 似乎 32 位操作是零扩展而不是符号扩展。 demo.
  • MikeCAT 评论 32 位寄存器写入 zero-扩展,它们不进行符号扩展。此外,xor 指令都将设置进位标志 = 0、零标志 = 1 等。mov 不会更改标志。
猜你喜欢
  • 1970-01-01
  • 2012-10-19
  • 2012-12-14
  • 2010-10-21
  • 1970-01-01
  • 2011-01-10
  • 1970-01-01
  • 2014-07-10
  • 1970-01-01
相关资源
最近更新 更多