asm中的ADC指令

par*_*vin 5 x86 assembly cpu-registers carryflag

在以下代码中,

MOV AL,NUMBER1
ADD AL,NUMBER2
MOV AH, 00H
ADC AH, 00H
Run Code Online (Sandbox Code Playgroud)

第3和第4行是什么?他们在做什么?

另外,为什么代码清除AH?(我假设因为AL的"ADD"操作可能会产生进位.)

Cod*_*ray 10

要弄清楚这一点,首先要查看每条指令的作用:

  • MOV AH, 00H

    MOV指令AH寄存器设置为0 而不影响标志.

  • ADC AH, 00H

    ADC指令将添加源操作数(0),进位标志(CF)和目标操作数(AH),将结果存储在目标操作数(AH)中.

    符号上,它确实: AH = AH + 0 + CF

    请记住,MOV没有影响的标志,以便使用由CF值ADC指示任何先前被设置ADD指令(在第2行).

    此外,AH为0在这一点上,所以这真的只是:AH = CF.

现在您知道代码的作用:

  1. NUMBER1进入AL寄存器:AL = NUMBER1

  2. 它增加NUMBER2AL注册表:AL = NUMBER1 + NUMBER2

  3. 它清除AH:AH = 0

  4. 它设置为AH等于CF,由添加NUMBER1和设置NUMBER2.因此,AH如果添加需要进位,则为1,否则为0.(AH = CF)

至于这段代码的目的,它清楚地执行了两位8位数的16位加法.在伪C中,它基本上是:

BYTE NUMBER1;
BYTE NUMBER2;
WORD RESULT = (WORD)NUMBER1 + (WORD)NUMBER2;
Run Code Online (Sandbox Code Playgroud)

其中BYTE大小的输入扩展到WORD并加在一起.为什么这样?好吧,处理溢出.如果将两个8位值相加,则结果可能大于8位.

理解这一点的真正技巧可能是寄存器ALAH寄存器分别是寄存器的低位和高位AX.因此,在这些说明之后,您可能会看到AX被使用.这包含添加和的16位结果.NUMBER1NUMBER2