1

is的运算, ADCisDEST ← DEST + SRC + CF的运算。令我困惑的是这些说明对 FLAGS 的影响。在 的情况下,关联性是明确的,因此我假设这相当于(就最终的寄存器状态而言)SBBDEST ← (DEST – (SRC + CF))SBBSBB

    jnc label
    lea src, [src+1]
    sub dest, src
    lea src, [src-1]
    jmp label2
label:
    sub dest, src
label2:

但是,在 , 的情况下ADC,会SRC先添加DEST,然后再CF添加?这很重要,因为如果是这样,它将对 FLAGS 产生不同的影响。

4

1 回答 1

5

ADC 和 SBB 的执行均基于整个操作。
如果您写sbbdst -= CF, dst -= src,如果其中任何一个产生借位,则应设置 CF。

伪代码中的括号并不是要告诉您操作的哪一部分实际设置了 FLAGS。您对它的阅读过多,并且模拟全加器(adcsbb进位并执行)并不容易。这就是为什么为它们提供硬件支持的指令非常有帮助的原因。)

对于换行为 0sbb的情况,您的仿真src+CF是错误的。 您无法将 src=-1 CF=1 情况(始终携带)与 src=0、CF=0 区分开来。(dst-=0 总是产生 CF=0)。在带有调试器的真实 CPU 上尝试一下。


您可以将 ADC 视为dst += src + CF(或-=用于 SBB),其中src+CF临时计算而不截断;例如 32 位操作数大小的 33 位和。ADD / SUB / ADC / SBB的dst输出和CF 也可以看成是一个33 位的值。

简单的例子:

mov al, 0xFF         ; AL=0xFF
stc                  ; CF=1
adc al, 0xFF         ; CF:AL = AL + (0xFF+CF) = AL + 0x100
; AL = 0xFF,  CF=1

它足够复杂,可以模拟adc它对 IMO 更有帮助,仅从加法的进位和进位方面理解它。或者如果它有帮助,比如一个全加器,或者实际上是一个由 8、16、32 或 64 个全加器组成的链。(当然,物理实现的延迟低于波纹进位)。

对我来说,计算出烦人的复杂分支序列或任何需要模拟的东西,adc或者sbb就 32 位固定宽度操作而言,对于理解它们的作用是零帮助。它们很简单,可以认为是原始操作,但很难模仿。

于 2020-06-09T18:51:07.527 回答