- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对 x86-64 二进制编码还很陌生。我正在尝试修复一些旧的“汇编程序”代码。
无论如何,我正在尝试做这样的事情(英特尔语法):
mov [rbp+rcx], al
汇编器当前正在生成这个:
88 04 0D
但这似乎不是一个有效的指令。如果我将 SIB 字节中的基数从 rbp
更改为其他寄存器,它就可以正常工作。使其工作的另一种方法是添加一个零字节位移 (88 44 0D 00
)。这似乎发生在其他类似的操作码上。
为什么我不能在 mod=00
中使用 rbp
?
最佳答案
另见 https://wiki.osdev.org/X86-64_Instruction_Encoding#32.2F64-bit_addressing_2或英特尔第 2 卷手册,了解这些特殊情况的编码表和脚注。这个答案指出了特殊情况,并讨论了为什么这些设计选择有意义,即他们需要解决什么设计问题。
表示 rbp
的编码是无基址寄存器的转义码(SIB 中的 disp32 或 ModRM 中的 RIP-relative rel32)。大多数汇编程序将 [rbp]
汇编成 [rbp + disp8=0]
。
因为你不需要缩放,所以使用 [rcx + rbp]
来避免需要 disp8=0,因为 rbp
可以 成为索引。
(SS 和 DS 在长模式下总是等价的,所以 base=RBP 意味着 SS 而 base=RCX 意味着使用 DS 段并不重要。)
(来 self 在 Why are rbp and rsp called general purpose registers? 上写的一个答案)。这个问题看起来是复制或移植这一部分的完美地方。
rbp
/r13
不能是没有位移的基址寄存器:该编码意味着:(在 ModRM 中) rel32
(RIP 相对),或(在 SIB 中)disp32
没有基址寄存器。 (r13
在 ModRM/SIB 中使用相同的 3 位,因此此选择通过不让指令长度解码器查看 the REX.B bit 来获取第 4 个基址寄存器位来简化解码)。 [r13]
汇编为 [r13 + disp8=0]
。 [r13+rdx]
汇编为 [rdx+r13]
(当这是一个选项时,通过交换基数/索引来避免问题)。
rsp
/r12
作为基址寄存器总是需要一个 SIB 字节。 (base=RSP 的 ModR/M 编码是用于发送 SIB 字节信号的转义码,同样,如果 r12
的处理方式不同,更多的解码器将不得不关心 REX 前缀)。
rsp
不能是变址寄存器。这使得对 [rsp]
进行编码成为可能,这比 [rsp + rsp]
更有用。 (英特尔本可以为 32 位寻址模式(386 中的新功能)设计 ModRM/SIB 编码,因此 SIB-with-no-index 只有在 base=ESP 时才有可能。这将使 [eax + esp*4]
possible and only exclude [esp + esp*1/2/4/8]
。但这没有用,所以他们简化了硬件,使 index=ESP 成为无索引的代码,无论如何基的。这允许两种冗余方式来编码任何基或基 + disp 寻址模式:有或没有 SIB。)
r12
可以是索引寄存器。与其他情况不同,这不会影响指令长度解码。此外,它不可能像其他情况那样使用更长的编码来解决。 AMD 希望 AMD64 的寄存器集尽可能正交,因此他们花费一些额外的晶体管来检查 REX.X 作为索引/非索引解码的一部分是有道理的。例如,[rsp + r12*4]
需要 index=r12,因此 r12
不是完全通用的会使 AMD64 成为更糟糕的编译器目标。
0: 41 8b 03 mov eax,DWORD PTR [r11]
3: 41 8b 04 24 mov eax,DWORD PTR [r12] # needs a SIB like RSP
7: 41 8b 45 00 mov eax,DWORD PTR [r13+0x0] # needs a disp8 like RBP
b: 41 8b 06 mov eax,DWORD PTR [r14]
e: 41 8b 07 mov eax,DWORD PTR [r15]
11: 43 8b 04 e3 mov eax,DWORD PTR [r11+r12*8] # *can* be an index
这些也都适用于 32 位寻址模式;编码是相同的,除了没有 EIP-relative 编码,只有两种冗余方式来编码没有 base 的 disp32。
This seems to happen with other similar opcodes.
r/m 操作数的 ModRM 编码总是相同的。有些操作码需要寄存器操作数,有些需要内存,但实际的 ModRM + 可选 SIB + 可选位移是固定的,因此无论指令如何,相同的硬件都可以对其进行解码。
有一些罕见的操作码,如 mov al/ax/eax/rax, [qword absolute_address]
,它们的操作数根本不使用 ModRM 编码,但任何使用相同的操作码格式。
关于assembly - rbp 不允许作为 SIB 基础?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52522544/
我对 x86-64 二进制编码还很陌生。我正在尝试修复一些旧的“汇编程序”代码。 无论如何,我正在尝试做这样的事情(英特尔语法): mov [rbp+rcx], al 汇编器当前正在生成这个:
我目前正在尝试编写一个反汇编程序。我找到了以下操作码列表及其含义,因此我决定在运行时解析它: http://web.archive.org/web/20150810224114/http://mpro
我正在为 32 位 x86 指令集开发一个反汇编程序。我的代码目前可以正确解码大多数 1 和 2 字节操作码,但我遇到了问题。当我将代码的输出与 Objdump 进行比较时,我发现 Objdump 看
我想使用作为 WebSphere 7 一部分的 WSADMIN 命令来查询系统上队列的状态。 谁能帮我吗? 谢谢 最佳答案 对于任何感兴趣的人,这是 jeff 答案的 jython 版本。 qpoin
我在 x86 机器上有这个绝对间接跳转指令: ff 24 25 30 10 60 00 生成自: jmp *bar 但是我在解码它的第二个和第三个字节时遇到了麻烦。 第二个应该是 Mod R/M 字段
我已经创建了一些代码来访问 Websphere MQ 的队列深度,但我无法确定是否有用于访问 SIB 队列的 API,或者我是否可以设置 websphere 以允许我访问它。 有人能给我一些提示/想法
我是一名优秀的程序员,十分优秀!