Jam*_*ess 14
要了解.s后缀的含义,您需要了解x86指令的编码方式.如果我们以adc一个例子为例,操作数可以采用四种主要形式:
当然,对于不同的操作数大小,有不同的变体: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字节中的位置被交换,指令的第一个字节告诉我们哪个操作数存储在哪里.