【问题标题】:How do I use ADC in assembly?如何在汇编中使用 ADC?
【发布时间】:2012-07-19 14:20:49
【问题描述】:
.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 的真正作用?我应该如何处理我的代码?

【问题讨论】:

  • ADC 在这里真的没有用,因为添加 2 位数字永远不会给出无法修复的结果。
  • 我的意思是“适合”而不是“修复”对不起

标签: assembly x86


【解决方案1】:

您似乎正在使用十进制数学,但您没有使用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

AAA (ASCII Adjust for Addition) 测试al 是否大于 9,如果是:

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

【讨论】:

  • 对不起,我是组装新手。 aaa 和 xchg 实际上是做什么的?
  • @jrmeasures 它交换(eXCHanGes)两件事
  • @jrmeasures 很好,事实证明它的作用与我记忆中的不同,所以我编辑了我的答案。
  • 我真的需要使用al、dl、ah和dh吗?
  • @jrmeasures你确实需要使用alah,你可以把d改成你喜欢的样子
【解决方案2】:

SO 上查看这个问题,答案解释了 ADC - Add with carry 的工作原理。基本上,您需要首先使用普通的 ADD 指令将低位字节相加。然后使用 ADC 将高位字节相加(带进位相加),如果低字节相加产生进位,则将添加进位。

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

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

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

如果您继续使用您的方法执行此任务,那么您需要手动检查两个低位小数的相加是否导致进位,方法是检查相加的结果是否大于 10 以及是否是从数字中减去 10,然后在高位计算中加 1。

这有意义吗?

这是家庭作业吗?如果是的话,作业的目的是学习进位的工作原理还是只是编写一个程序来将两个两位数相加?

【讨论】:

  • 请看我的代码,我有两行与该示例相同。
  • 查看@harold 发布的答案。他的解决方案更好,因为它使用了一个名为 Ascii Adjust after Additon 的指令来完成您需要做的事情,并且还使用进位标志来完成您需要做的事情。
  • 我只想写一个加两位数的程序
猜你喜欢
  • 2013-11-22
  • 2011-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-03
  • 2012-03-07
相关资源
最近更新 更多