汇编语言标志寄存器adc 指令

 指令格式:adc 操作对象 1, 操作对象 2
  功能:操作对象 1 = 操作对象 1 + 操作对象 2 + CF
  比如指令 adc ax,bx,实现的功能是: (ax) = (ax) + (bx) + CF
  例:

  mov ax,2
  mov bx,1
  sub bx,ax
  adc ax,1

  执行后,(ax)=4。adc 执行时,相当于计算:(ax) = (ax) + 1 + CF = 2 + 1 + 1 = 4。

  mo ax,1
  add ax,ax
  adc ax,3

执行后,(ax)=5 adc执行时,相当于计算:(ax)+3+Cf=2+3+0=5

  mov  al,98h
  add  al,al
  adc  al,3

执行后,(al)=34H adc执行时,相当于计算:(al)+3+CF=30H+3+1=34H
可以看出,adc指令比add指令多加了一个CF位的值
为什么要加上CF的值呢?CPU为什么要提供这样一条指令呢?
先来看一下CF的值的含义。在执行adc指令的时候加上的CF的值的含义,是由adc指令前面的指令决定的,也就是说,关键在于所加上的CF值是被什么指令设置的。显然,如果CF的值是被sub指令设置的,那么它的含义就是借位值;如果是被add指令设置的,那么它的含义就是进位值。我们来看一下两个数据:0198H和0183H如何相加的:

          01  98
       +  01  83
             1
       ————————————
          03   1B

可以看出,加法可以分两步来进行:
①低位相加:
②高位相加再加上低位相加产生的进位值。
下面的指令和add ax, bx具有相同的结果:

 add al,bl
 adc ah,bh

看来CPU提供adc指令的目的,就是来进行加法的第二步运算的。adc指令和add指令相配合就可以对更大的数据进行加法运算。我们来看一个例子:
编程,计算1 EF000H+201000H,结果放在ax(高16位)和bx(低16位)中。
因为两个数据的位数都大于16,用add指令无法进行计算。我们将计算分两步进行,
先将低16位相加,
然后将高16位和进位值相加。
程序如下:

  mov ax,001EH
  mov bx,0F000H
  add bx,1000H
  adc ax,0020H

  adc 指令执行后,也可能产生进位值,所以也会对 CF 位进行设置。由于有这样的功能,我们就可以对任意大的数据进行加法运算。看一个例子:
编程,计算1EF0001000H+2010001EFOH,结果放在ax(最高16位),bx(次高16位),cx(低16位)中。
计算分3步进行:
(1)先将低16位相加,完成后,CF中记录本次相加的进位值;
(2)再将次高16位和CF(来自低16位的进位值)相加,完成后,CF中记录本次相加的进位值;
(3)最后高16位和CF(来自次高16位的进位值)相加,完成后,CF中记录本次相加的进位值。
程序如下:

mov ax,001EH
mov bx,OF000H
mov cx,1000H
add cx,lEFOH
adc bx,1000H
adc ax,0020H

  编写一个子程序,对两个 128 位数据进行相加。
  名称:add128
  功能:两个 128 位数据进行相加。
  参数:ds:si 指向存储第一个数的内存空间,因数据为 128 位,所以需要 8 个字单元,由低地址单元到高地址单元依次存放 128 位由低到高的各个字。运算结果存储在第一个数的存储空间中。
  ds:di 指向存储第二个数的内存空间。

   程序如下:

add128:
    push ax
    push cx
    push si
    push di
 
    sub ax,ax    ;将 CF 设置为 0
 
    mov cx,8
 s:mov ax,[si]
    adc ax,[di]
    mov [si],ax
    inc si
    inc si
    inc di
    inc di
    loop s
 
    pop di
    pop si
    pop cx
    pop ax
     
    ret

inc和loop指令不影响CF位,思考一下,上面的程序中,能不能将4个inc指令,用

 add si ,2
 add di,2

来取代?


发布日期:

所属分类: 编程 标签:   


没有相关文章!