你如何理解 x86-64 汇编的 'REX.W + B8+ rd io' 形式?

How do you understand 'REX.W + B8+ rd io' form for x86-64 assembly?

我最初试图生成字节以立即移动到 64 位 register.The 我想要的特定操作是

mov rdi, 0x1337

使用https://www.felixcloutier.com/x86/mov,我看到的唯一非符号扩展指令是

REX.W + B8+ rd io

这让我很困惑,所以我创建了一个小的汇编程序来查看汇编程序会生成什么

          global    _start

          section   .text
_start:   
          mov       rdi, 0x1337 
          syscall                           
          mov       rax, 60                 
          xor       rdi, rdi                
          syscall                           

我不得不关闭优化,以便移动到 64 位寄存器。所以我用 nasm -felf64 -O0 main.asm && ld main.o 编译并生成了一个 a.out。我查看 objdump -M intel -d ./a.out 和这一行

48 bf 37 13 00 00 00    movabs rdi,0x1337  

那条线看起来一点都不像

REX.W + B8+ rd io

给我?此外,在一些 之后,我看到该命令假定为 10 个字节。你如何从 REX.W + B8+ rd io 得到它?

B8+ rd 表示操作数(寄存器)编码在操作码的低 3 位中,而不是 ModR/M 字节中。

来自英特尔软件开发人员手册,

+rb, +rw, +rd, +ro — Indicated the lower 3 bits of the opcode byte is used to encode the register operand without a modR/M byte. The instruction lists the corresponding hexadecimal value of the opcode byte with low 3 bits as 000b. In non-64-bit mode, a register code, from 0 through 7, is added to the hexadecimal value of the opcode byte. In 64-bit mode, indicates the four bit field of REX.b and opcode[2:0] field encodes the register operand of the instruction. “+ro” is applicable only in 64-bit mode.

看起来 Intel 想对以这种方式编码的 64 位操作数使用 +ro,但实际上并没有这样做。不仅在 mov 引理中,而且在我能找到的任何地方。例如 64 位 pushpop 可能有 + ro,但它们也有 + rd。而“Indicated”可能是错别字,其余文字使用现在时。

(e/r)di 寄存器是数字 7,B8 + 7 = BF,解释了操作码。

io 代表一个 qword immediate(o 代表 octo,可能是 8 个字节?)。

REX 前缀(40 为基本前缀,+8 设置 W 位,可选 +1 设置 B 位以访问 R8..R15),操作码,noModR/M字节,加上8字节的立即数,加起来就是10字节。