assembly - asm中的ADC指令

标签 assembly x86 cpu-registers carryflag

在以下代码中,

MOV AL,NUMBER1
ADD AL,NUMBER2
MOV AH, 00H
ADC AH, 00H

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

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

最佳答案

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

  • MOV AH, 00H
    MOV instruction将设置 AH在不影响标志的情况下注册为 0。
  • ADC AH, 00H
    ADC instruction将添加源操作数 (0)、进位标志 (CF) 和目标操作数 ( AH ),并将结果存储在目标操作数 ( AH ) 中。

    那么,象征性地,它确实:AH = AH + 0 + CF
    请记住 MOV没有影响标志,所以 ADC 使用的 CF 值指令是之前由 ADD instruction 设置的任何内容(在第 2 行)。

    另外,AH此时为 0,所以这实际上只是:AH = CF .

  • 现在你知道代码做了什么:
  • 它移动 NUMBER1AL注册:AL = NUMBER1
  • 它添加 NUMBER2AL注册:AL = NUMBER1 + NUMBER2
  • 清除 AH :AH = 0
  • 它集 AH等于 CF,由 NUMBER1 相加而设置和 NUMBER2 .因此,AH如果加法需要进位,则为 1,否则为 0。 ( AH = CF )

  • 至于这段代码的用途,它显然执行了两个 8 位数字的 16 位加法。在伪 C 中,它基本上是:
    BYTE NUMBER1;
    BYTE NUMBER2;
    WORD RESULT = (WORD)NUMBER1 + (WORD)NUMBER2;
    

    其中 BYTE 大小的输入扩展为 WORD 并相加。为什么要这样做?好吧,处理溢出。如果将两个 8 位值相加,结果可能会大于 8 位。

    理解这一点的真正诀窍可能是 ALAH寄存器分别是 AX 的低位和高位寄存器。因此,在这些说明之后,您可能会立即看到 AX正在使用。这包含了 NUMBER1 相加的 16 位结果。和 NUMBER2 .

    关于assembly - asm中的ADC指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44540078/

    相关文章:

    c - 内联汇编程序 : What scratch registers can be used?

    c - GCC 更改为小于或等于

    c - AVR I/O 宏定义如何工作以允许访问寄存器?

    c# - 哪些场景最大限度地发挥了 x64 系统中更高寄存器数量对 C# 代码的性能影响?

    assembly - ascii char 到 char 的转换 汇编x86?

    GDB 信息寄存器命令 - 输出的第二列

    assembly - 向学生解释位操作的最佳方法是什么?

    c - 如何计算周期?

    security - 为什么堆栈不向上增长(出于安全考虑)?

    创建 x86 Bootstrap