MOV的HEX机器代码立即到64位寄存器没有REX.W前缀吗?
我有此代码,说
global main
[BITS 64]
section .text
main:
mov r13, 0x1234
mov rax, 60
mov rdi, 0
syscall
当我手动翻译此指令MOV R13,0x1234
时,我是十六进制代码0x48_bd_34_12_00_00_00_00
。
该说明的OP代码是Rex.W + B8 + RD IO(我想)。
当我在Linux上翻译文件时,十六进制的传统为0x41_bd_34_12_00_00
。
41是0100_0001 b。但是rex.w说w = 1,因此应为0100_1001b。
所以我不明白为什么雷克斯前缀为41h而不是49h。
I have this code which says
global main
[BITS 64]
section .text
main:
mov r13, 0x1234
mov rax, 60
mov rdi, 0
syscall
When I translate manually this instruction mov r13, 0x1234
, I've as hexadecimal code 0x48_BD_34_12_00_00
.
The op code of the instruction is REX.W + B8+ rd io (I guess).
When I translate my file on Linux, the hexadecimal traduction is 0x41_BD_34_12_00_00
.
41 is 0100_0001 b. But the REX.W says that W = 1, so it should be 0100_1001b.
So I don't understand why the REX prefix is 41h and not 49h.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
有两个原因。
首先,指令nasm编码实际上是
mov r13d,0x1234
而不是mov r13,0x1234
。这是因为以前的指示较短,但也做同样的事情。现在为什么我们看到这个编码?这是一个解释:
There are two reasons for this.
First, the instruction NASM encodes is actually
mov r13d, 0x1234
instead ofmov r13, 0x1234
. This is because the former instruction is shorter but does the same thing.Now why do we see this encoding? Here's an explanation:
|| || ``````````-- immediate value
|| ``-------------- opcode b8 + reg (5)
``----------------- REX.B prefix
我们要编码的寄存器具有13。该寄存器号的低3位是在OpCode字节中编码的。高位编码在rex.b位。因此,需要一个rex.b前缀。
如果我们想编码
mov r13,0x1234
作为nasm -o0
将喜欢mov r13,严格qWord 0x1234
,它看起来像这样:在这里,我们有一个rex.bw前缀
49
来编码附加寄存器位和64位操作数宽度。这是MOV R64,IMM64
编码,与MOV R32,IMM32
相同的OPCODE,但带有REX.W.。不优化32位寄存器但确实选择最短编码的汇编程序(例如Yasm或Gas)将使用
MOV R/M64,sign_extdended_imm32
编码,您可以获得它从NASM带有MOV R13,严格的DWORD 0x1234
。 C7和C5字节是OPODE和MOD/RM,然后是4字节即时。|| || ``````````-- immediate value
|| ``-------------- opcode b8 + reg (5)
``----------------- REX.B prefix
The register we want to encode has number 13. The low 3 bit of this register number are encoded in the opcode byte. The high bit is encoded in the REX.B bit. Hence, a REX.B prefix is needed.
If we wanted to encode
mov r13, 0x1234
asnasm -O0
would, likemov r13, strict qword 0x1234
, it would look like this:Here we have a REX.BW prefix
49
to encode both the additional register bit and the 64 bit operand width. This is themov r64, imm64
encoding, same opcode asmov r32, imm32
but with a REX.W.Assemblers that don't optimize to a 32-bit register but do pick the shortest encoding for what you wrote (e.g. YASM or GAS) would use the
mov r/m64, sign_extended_imm32
encoding, which you can get from NASM withmov r13, strict dword 0x1234
. The C7 and C5 bytes are opcode and Mod/RM, followed by a 4-byte immediate.