我正在查看英特尔指令集手册,看起来有两种不同形式的ADC
符合/编码ADC EAX, ECX
,如下所示:
ADC r/m32, r32 (11 /r , which encodes to 11C8)
或
ADC r32, r/m32 (13 /r, which encodes to 13C1)
我的问题是(鉴于我的数学运算正确),11C8
和13C1
是否相同?汇编程序在选择一种编码而不是另一种编码时会考虑哪些因素?问题是从实现汇编程序的角度出发,所以问题一般来说不是关于这个特定的假设指令。
如果这是一个冗长的答案,请指出我正确的方向,因为我在谷歌上搜索失败。
答案 0 :(得分:11)
这是指令编码的redundancy。在指令中使用多个参数的任何体系结构都具有此功能。
考虑一个RISC架构,add rx, ry, rz
将ry和rz的总和分配到rx然后你可以编码add rx, ry, rz
或add rx, rz, ry
,它们都是等价的。
在x86中,我们(通常)每条指令只有2个参数,但您可以选择它们之间的方向,因为您可以存储或读取内存。如果不使用内存,则可以选择2个寄存器之间的方向,因此有2种编码方式
您可以使用它来识别一些编译器/汇编器。对于某些汇编程序,您可以选择要使用的编码。在GAS中,您可以使用.s
suffix强制它发出备用编码
10 de adcb %bl,%dh
12 f3 adcb.s %bl,%dh
答案 1 :(得分: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位涉及几乎两个涉及reg-reg或reg-mem操作数的操作数指令。