x86指令中的".s"后缀是什么?

Pet*_*man 12 x86 assembly x86-64 att

当我拆开.text使用一些二进制文件的部分objdump(与两个AT&T和Intel语法),有时会看到指令用.s后缀,例如:cmpb.s %bh,%ch,sbbl.s %edi,%edi,或adcb.s %bl,%dh.

请问.s后缀有一个有效/有用的意思(也许甚至还不如一个后缀),或这是拆卸一些数据/填充,如果它是一个指令序列的假象?谢谢.

Jam*_*ess 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
Run Code Online (Sandbox Code Playgroud)

第一个字节决定了所用指令的形式,我稍后会再回过头来看.第二个字节是所谓的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
Run Code Online (Sandbox Code Playgroud)

如果其中一个操作数是存储器位置,则Mod和R/M字段一起确定存储器位置的有效地址,但是当该操作数只是寄存器时,Mod字段设置为11,并且R/M是值登记册.REG字段显然只代表另一个寄存器.

因此在de字节中,R/M字段保存dh寄存器,REG字段保存bl寄存器.在f3字节中,R/M字段保存bl寄存器,REG字段保存dh寄存器.(8位寄存器按照al,cl,dl,bl,ah,ch,dh,bh的顺序编码为数字0到7)

回到第一个字节,10告诉我们使用表格3编码,其中源操作数总是一个寄存器(即它来自REG字段),目标操作数是一个内存位置或寄存器(即它确定由Mod和R/M领域).将12告诉我们使用表单4编码,其中该操作数是周围的其他方法-源操作数,由MOD和R/M场和目标操作数确定来自REG字段.

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

  • 很好的答案,我只想补充说.s后缀是GAS惯例.没有其他汇编程序使用它(但我认为它们中的任何一个都不支持选择编码).这是[另一页](http://www.strchr.com/machine_code_redundancy)用更多示例描述问题. (4认同)

Mic*_*ael 8

所述.s指令后缀交换在指令编码(寄存器操作数参考).

  • 希望有一天SO帖子会揭示这些家伙滥用的娱乐性药物. (5认同)