编码ADC EAX,ECX - 两种不同的编码方式?(体系结构x86)

8

我正在查看一份英特尔指令集手册,看起来有两种不同形式的 ADC 可以匹配/编码 ADC EAX, ECX ,如下所示:

ADC r/m32, r32  (11 /r , which encodes to 11C8)

或者

ADC r32, r/m32  (13 /r, which encodes to 13C1)

我的问题是(如果我的计算正确),11C813C1是否等效?汇编器在选择一种编码而不是另一种编码时会考虑哪些因素?这个问题是从实现一个汇编器的角度来看的,所以这个问题是普遍的,而不是关于这个假设指令的特定问题。
如果回答很长,请指引我正确的方向,因为我尝试通过谷歌搜索未能成功。

2
是的,它们是等价的。 - Egor Skriptunoff
2个回答

11

这是指令编码的冗余性。任何使用多个参数的架构都会有这个问题。

想象一下一个RISC架构,它有一个add rx, ry, rz指令,将ry和rz的和赋值给rx,那么你可以编码add rx, ry, rzadd rx, rz, ry,它们都是等效的。

在x86中,我们(通常)每个指令只有2个参数,但您可以选择它们之间的方向,因为您可以存储到内存或从内存读取。如果您不使用内存,则可以选择2个寄存器之间的方向,因此有2种编码方式。

您可以使用此方法来识别某些编译器/汇编器。对于某些汇编器,您可以选择使用哪种编码。在GAS中,您可以使用.s后缀来强制发出备用编码。

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

有时候在使用Google时,您需要使用一些小技巧,例如在以下网址中查看一些表格参考:http://pdos.csail.mit.edu/6.828/2005/readings/i386/ADC.htm。同时,您也可以尝试使用以下Google搜索语法:https://www.google.com/#q=allintext:+adc+eax+r32。 - user2485710
1
GAS引入了新的语法来进行编码覆盖,例如在r/m源前添加{load}前缀进行编码。具体请查看https://sourceware.org/binutils/docs/as/i386_002dMnemonics.html。或者添加`{disp32}`前缀以强制使用更长的寻址模式。 - Peter Cordes

2
ADC 的二进制编码是(假设为寄存器-寄存器操作):
000100dw  Mod Reg Ind 
d= destination, 1 if Reg is the destination register, 0 if not
w= word operation, =0 if byte operation, =1 32 bit operation
Reg= is the register to use as a destination Register
Mod / Ind fields are used to specify the other Register involved, Mod=11, Ind= the other register

当指令像ADC EAX, ECX这样与两个寄存器一起使用时,有两种可能的编码方式:

a) EAX= EAX + ECX, COP= 13h, the "normal" case
00010011 11|000|001 where d=1 meaning 000 (EAX) is the destination register and 001 (ECX) is the other register.

b) EAX= ECX + EAX, COP= 11h, 
00010001 11|001|000 d=0 meaning 001 (ECX) is not the destination register so 000(EAX) must be the destination register.

D位在涉及寄存器-寄存器或寄存器-内存操作数的几乎所有双操作数指令中都有所涉及。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接