ADD( const, memory)
是最混乱的,这个代码序列看起来如下:
- 从内存中获取指令字节
- 更新EIP以指向下一个字节
- 解码指令。
- 如果需要,获取用于有效地址计算的位移
- 如果需要,请更新EIP,使其指向位移值之外的位置
- 从内存中获取常数值并将其发送到ALU
- 更新EIP,使其指向常量值之外(在内存中的下一条指令处)
- 从内存中获取源操作数的值,并将其发送到ALU
- 指示ALU添加值
- 将结果存储回内存操作数
- 使用加法运算的结果更新标志寄存器
这来自《汇编语言的艺术》一书。为什么EIP更新了2到3次?
您永远无法观察到EIP指向正在解码的指令的中间。这只是作者的注释。真正的硬件显然不会在缓慢的迭代过程中解码,因为它是硬件而不是软件。
x86解码起来很复杂,在操作码采用16或32位立即数的情况下,操作数大小前缀甚至会根据操作数大小更改指令的剩余的长度。英特尔CPU在解码时实际上在这个问题上停滞不前。(这被称为LCP失速)。
然而,这种表示法听起来很奇怪,因为可变长度操作码意味着指令的长度+立即数。解码前缀+操作码告诉指令的总长度,但寻址模式除外,寻址模式可能有一个SIB字节和/或位移。