Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use ADC in assembly?

.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

Above is my code for adding 2 two-digit numbers in assembly. I wonder why the ADC doesn't work. If the ones digits don't obtain a carry when added, my code works. But not otherwise. Did I misunderstand what the ADC really does? What should I do with my code?

like image 380
six.strings.and.a.bit Avatar asked Jul 19 '12 14:07

six.strings.and.a.bit


2 Answers

You appear to be working with decimal math, but you're not using AAA. ADC does what you'd expect, but with that code there is never an actual carry from the first addition (9+9 is not bigger than 255, after all).

So the solution, of course, is to use AAA, like this (not tested):

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) tests if al is bigger than 9, and if so:

  • adjusts al,
  • sets the carry flag, and
  • increments ah
like image 113
harold Avatar answered Nov 16 '22 18:11

harold


Check out this question here on SO the answer explains how the ADC - Add with carry works. Basically you need to add together the low order bytes first using a plain ADD instruction. Then add together the high order bytes using ADC (add with carry) which will add the carry if the lower byte add generated a carry.

For example, if you are adding AX and BX you would do the following:

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

As the comments to your question have mentioned, you are actually performing decimal arithmetic by taking each ASCII character then subtracting '0' from it. Each of these operations will only generate a binary number between 0 and 9 being stored in a 8 bit register. As the comments say, adding together two number each less than 10 will never result in a carry which can only happen when the result is greater than 256.

If you continue to use your method of performing this task, then you need to manually check if the addition of the two lower order decimal digits has caused a carry by checking if the result of the addition is greater than 10 and if it is subtract 10 from the number and then add 1 to the higher order digit calculation.

Does that make sense?

Is this a homework assignment? If it is, is the purpose of the assignment to learn how carry works or to just write a program to add two two-digit numbers together?

like image 1
HeatfanJohn Avatar answered Nov 16 '22 18:11

HeatfanJohn