当我使用.text(具有AT&T和Intel语法)反汇编某些二进制文件的objdump部分时,有时会看到带有.s后缀的指令,例如:cmpb.s %bh,%chsbbl.s %edi,%ediadcb.s %bl,%dh
.s后缀是否具有有效/有用的含义(也许甚至不作为后缀),或者这是分解某些数据/填充的伪像,就像是一条指令序列一样?谢谢你。

最佳答案

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

  • 源操作数是立即数,目标操作数是累加器寄存器。
  • 源操作数是立即数,目标操作数是寄存器或内存位置
  • 源操作数是一个寄存器,而目标操作数是一个寄存器或内存位置。
  • 源操作数是寄存器或内存位置,目标操作数是寄存器。

  • 当然,对于不同的操作数大小,也有这些变量的变体: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位寄存器按照al,cl,dl,bl,ah,ch,dh,bh的顺序编码为数字0到7)

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

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

    关于assembly - x86指令中的 ".s"后缀是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16746922/

    10-11 18:44