如何在装配中使用ADC?

时间:2012-07-19 14:20:49

标签: assembly x86

.MODEL SMALL
.STACK 1000
.DATA

MSGA DB 13,10,"Input first number: ","$"
MSGB DB 13,10,"Input second number:","$"
MSGC DB 13,10,"The sum is: ","$"

NUM1 db ?
NUM2 db ?
NUM3 db ?

.CODE

MAIN PROC NEAR

MOV AX, @DATA
MOV DS, AX

; get first number
LEA DX, MSGA
MOV AH, 09h
INT 21h

MOV AH, 01
INT 21H
SUB AL, '0'

MOV BL, AL

MOV AH, 01
INT 21H
SUB AL, '0'

MOV CL, AL

; get second number
LEA DX, MSGB
MOV AH, 09h
INT 21h

MOV AH, 01
INT 21H
SUB AL, '0'

MOV DL, AL

MOV AH, 01
INT 21H
SUB AL, '0'

MOV DH, AL

; add
ADD CL, DH 
ADC BL, DL
MOV NUM1, CL
ADD NUM1, '0'
MOV NUM2, BL
ADD NUM2, '0'

; output sum
LEA DX, MSGC
MOV AH, 09h
INT 21h

MOV DL, NUM2
MOV AH, 02H
INT 21h

MOV DL, NUM1
MOV AH, 02H
INT 21h

MOV AH, 4Ch
INT 21h

MAIN ENDP
END MAIN

以上是我在汇编中添加2位两位数字的代码。我想知道为什么ADC无效。如果这些数字在添加时没有获得进位,我的代码就可以工作。但不是这样。我误解了ADC真正的作用吗?我该怎么处理我的代码?

2 个答案:

答案 0 :(得分:4)

您似乎正在使用十进制数学,但您没有使用AAAADC做了你所期望的,但是使用那个代码,从来没有第一次加法的实际进位(毕竟9 + 9不大于255)。

所以解决方案当然是使用AAA,就像这样(未经测试):

add al,dl
aaa        ; takes no arguments and works on al
add ah,dh  ; adc not necessary, aaa already incremented ah if there was a carry

AAAASCII Adjust for Addition)测试al是否大于9,如果是,则

  • 调整al
  • 设置进位标志,
  • 增加ah

答案 1 :(得分:1)

SO上查看此问题,答案解释了ADC - 附带进位是如何工作的。基本上,您需要首先使用普通ADD指令将低位字节加在一起。然后使用ADC(add with carry)将高位字节加在一起,如果低位字节添加生成一个进位,则会添加进位。

例如,如果要添加AX和BX,则执行以下操作:

add  al, bl
adc  ah, bh   ; include the carry if previous add generated one

正如你的问题的评论所提到的,你实际上是通过取每个ASCII字符然后从中减去'0'来执行十进制算术。这些操作中的每一个将仅生成0到9之间的二进制数,存储在8位寄存器中。正如评论所说,将两个小于10的数字加在一起将永远不会产生只有当结果大于256时才会发生的进位。

如果继续使用执行此任务的方法,则需要通过检查添加的结果是否大于10来手动检查两个低位十进制数的添加是否导致进位,如果是从数字中减去10,然后将1加到高位数字计算中。

这有意义吗?

这是家庭作业吗?如果是,分配的目的是学习如何进行工作或只是编写一个程序来将两个两位数字加在一起?