12

当我.text使用(使用 AT&T 和 Intel 语法)反汇编某些二进制文件的部分时objdump,有时会看到带有.s后缀的指令,例如:cmpb.s %bh,%ch、、sbbl.s %edi,%ediadcb.s %bl,%dh

后缀是否.s具有有效/有用的含义(甚至可能不是后缀),或者这是反汇编某些数据/填充的人工制品,就好像它是一系列指令一样?谢谢你。

4

2 回答 2

14

要了解.s后缀的含义,您需要了解 x86 指令的编码方式。如果我们以adc示例为例,操作数可以采用四种主要形式:

  1. 源操作数是立即数,目标操作数是累加器寄存器。
  2. 源操作数是立即数,目标操作数是寄存器或内存位置
  3. 源操作数是寄存器,目标操作数是寄存器或内存位置。
  4. 源操作数是寄存器或内存位置,目标操作数是寄存器。

当然,对于不同的操作数大小,它们也有一些变体:8 位、16 位、32 位等。

当您的操作数之一是寄存器而另一个是内存位置时,很明显汇编器应该使用形式 3 和 4 中的哪一种,但是当两个操作数都是寄存器时,任何一种形式都适用。前缀告诉汇编器使用.s哪种形式(或者在反汇编的情况下,显示您使用了哪种形式)。

看具体的例子adcb %bl,%dh,可以编码的两种方式如下:

10 de   adcb   %bl,%dh
12 f3   adcb.s %bl,%dh

第一个字节决定了所使用的指令的形式,我稍后再谈。第二个字节是众所周知的 ModR/M 字节,它指定了寻址模式和使用的寄存器操作数。ModR/M 字节可以分为三个字段:Mod(最高有效 2 位)、REG(接下来的 3 位)和 R/M(最后 3 位)。

de: Mod=11, REG = 011, R/M = 110
f3: Mod=11, REG = 110, R/M = 011

如果其中一个操作数是内存位置,则 Mod 和 R/M 字段共同确定内存位置的有效地址,但当该操作数只是一个寄存器时,Mod 字段设置为 11,R/M 为值的寄存器。REG 字段显然只是代表另一个寄存器。

所以在de字节中,R/M 字段保存dh寄存器,REG 字段保存bl寄存器。而在f3字节中,R/M 字段保存bl寄存器,REG 字段保存dh寄存器。(8 位寄存器编码为 0 到 7 的数字,顺序为 al、cl、dl、bl、ah、ch、dh、bh)

回到第一个字节,10告诉我们使用form 3编码,其中源操作数始终是寄存器(即来自REG字段),目标操作数是内存位置或寄存器(即确定通过 Mod 和 R/M 字段)。告诉我们使用12形式 4 编码,其中操作数是相反的——源操作数由 Mod 和 R/M 字段确定,目标操作数来自 REG 字段。

因此寄存器存储在 ModR/M 字节中的位置被交换,指令的第一个字节告诉我们哪个操作数存储在哪里。

于 2013-05-25T10:32:24.690 回答
8

.s指令后缀交换指令编码中的寄存器操作数(参考

于 2013-05-25T06:33:30.257 回答