assembly 当我们只知道操作码的十六进制时,如何编码指令

pxq42qpu  于 2023-08-06  发布在  其他
关注(0)|答案(2)|浏览(94)

this源代码中,他们给出了cmp r/m16/32 imm 8的十六进制值为0x 837。我在某个地方找到了,ebp的十六进制是0 b 0101。有了这些信息,我该如何对指令cmp dword [ebp-4] 2进行编码?我一直在寻找这个从几个小时,并没有得到任何线索,除了this(第61页)类似的指令cmpb $0xf,(%rdi)编码为80 3f 0 f。但我无法理解这一点,因为我提到的前一个来源说,0x 803是为sbb。另外,rdi是0 b 0111,而不是0 b1111(实际上是r15)。我有点糊涂了...如果可能的话,我想要x86-32和x86-64的编码指令。

cld4siwp

cld4siwp1#

除非您已经知道x86指令编码是如何工作的,否则您所链接的文档不是很有用。我们换一个。在this resource(从英特尔官方PDF手册中抓取1)之后,我们得到以下候选编码:

81 /7 iw    CMP r/m16,imm16     Compare imm16 with r/m16.
81 /7 id    CMP r/m32,imm32     Compare imm32 with r/m32.
83 /7 ib    CMP r/m16,imm8      Compare imm8 with r/m16.
83 /7 ib    CMP r/m32,imm8      Compare imm8 with r/m32.

字符串
这里需要注意的一点是,word和dword操作的编码相同。这不是一个错误:操作数大小由当前代码段的默认操作数宽度(即,无论我们是在16位、32位还是64位模式下运行)以及存在66REX.W操作数大小覆盖前缀。规则很简单:

  • 在16位模式中,默认操作数大小为16位
  • 在32位和64位模式中,默认操作数大小为32位
  • 66前缀在16和32位操作数大小之间切换
  • 在64位模式中,REX.W前缀切换到64位操作数大小

因此,当在32或64位模式下编程时,不需要前缀,因为默认操作数大小已经是我们想要的大小。
现在的问题是使用83还是81。在这种情况下,两者都可以使用,因为我们的立即数适合8位签名。我们将继续使用83操作码,因为编码更短。
编码83 /7 ib告诉我们,操作码是83,后面是reg = 7的modr/m字节(其他字段编码r/m32操作数),后面是8位立即数。
r/m32操作数[ebp-4]可以在链接的参考中给出的modr/m字节表中查找。我们有一个带索引寻址模式的内存操作数;指数ebp和位移-4。位移适合8位有符号,因此我们使用表中的[ebp+disp8]条目,并最终在7d处为modr/m字节。接下来是位移字节0xfc,表示2的补码中的−4。
把所有这些放在一起,我们得到83 7d fc 02作为cmp dword ptr [ebp-4], 2的编码:

83  opcode
7d  modr/m byte: reg = 7, r/m = [ebp+disp8]
fc  displacement: -4
02  immediate: 2


值得注意的是,对于32位和64位模式,编码是相同的。对于16位模式,需要额外的6667前缀来选择32位操作数和地址大小,即66 67 83 7d fc 02

脚注1:在英特尔软件开发人员手册(SDM)中,指令的操作数大小属性在第1卷第1章中描述。3.6,66h前缀用于选择模式的非默认值,在第2卷ch中描述。2.1.1组3.

其他编码细节主要在第2卷手册中。像https://www.felixcloutier.com/x86/https://c9x.me/x86/这样的网站是从英特尔的vol.2 PDF中抓取的,但只包括每条指令的条目,而不是告诉你适用于每条指令的基础知识的介绍,或者如何阅读条目的细节。How to read the Intel Opcode notation

disho6za

disho6za2#

请参阅官方 * 英特尔® 64和IA-32体系结构软件开发人员手册第2卷:指令集参考,A-Z*,在Intel's website上以多种格式提供。翻到关于CMP的那一页,找到有CMP r/m32, imm8的那一行。这给出了操作码列为83 /7 ib。翻到 * 表2-2。32位寻址形式,带ModR/M字节 *。选择[ebp]+disp8行和/digit 7列。单元格告诉您ModR/M字节是7d。您需要附加-4的位移,即8位有符号的fc和立即操作数。因此,完整的指令是83 7d fc 02。在64位模式下,如果使用rbp,编码是相同的。如果您想保留ebp,则需要使用地址大小覆盖前缀67

相关问题