MOV的HEX机器代码立即到64位寄存器没有REX.W前缀吗?

发布于 2025-01-31 02:11:02 字数 439 浏览 2 评论 0原文

我有此代码,说

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

情绪少女 2025-02-07 02:11:03

有两个原因。

首先,指令nasm编码实际上是mov r13d,0x1234而不是mov r13,0x1234。这是因为以前的指示较短,但也做同样的事情。

现在为什么我们看到这个编码?这是一个解释:

41 bd 34 12 00 00
|| ||  

There are two reasons for this.

First, the instruction NASM encodes is actually mov r13d, 0x1234 instead of mov 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:

41 bd 34 12 00 00
|| ||

这样的小城市 2025-02-07 02:11:03

|| || ``````````-- 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,它看起来像这样:

49 bd 34 12 00 00 00 00 00 00

在这里,我们有一个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字节即时。

49 c7 c5 34 12 00 00

|| || ``````````-- 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 as nasm -O0 would, like mov r13, strict qword 0x1234 , it would look like this:

49 bd 34 12 00 00 00 00 00 00

Here we have a REX.BW prefix 49 to encode both the additional register bit and the 64 bit operand width. This is the mov r64, imm64 encoding, same opcode as mov 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 with mov r13, strict dword 0x1234. The C7 and C5 bytes are opcode and Mod/RM, followed by a 4-byte immediate.

49 c7 c5 34 12 00 00
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文