Handling of Hexadecimal numbers for 8051 Assembly
Question
I am having trouble looping through the Hexadecimal numbers in 8051 Assembly for proper subtraction,
Here is the simple code that iterate 30 times and shows value from 40 to 70 (40,41,42,43,....70)
MOV A,#40H ;first value of the loop
MOV R0,#0H
MOV R1,#30 ;Number of iterations
LOOP:
ADD A,R0
DA A ;To Adjust the decimal values after each addition
INC A
DJNZ R1,LOOP
END
This is how it is adjusting each value,
; 40H = 64D --(+0D)--> 64D = 40H
; 41H = 65D --(+0D)--> 65D = 41H
; 42H = 66D --(+0D)--> 66D = 42H
; 43H = 67D --(+0D)--> 67D = 43H
; 44H = 68D --(+0D)--> 68D = 44H
; 45H = 69D --(+0D)--> 69D = 45H
; 46H = 70D --(+0D)--> 70D = 46H
; 47H = 71D --(+0D)--> 71D = 47H
; 48H = 72D --(+0D)--> 72D = 48H
; 49H = 73D --(+0D)--> 73D = 49H
; 4AH = 74D --(+6D)--> 80D = 50H
But when i want to reverse the loop i.e if i want the output in reverse order from 70 to 40 (70,69,68,67,66,65,64,.....40)
what should i have to do ?
Here is the example how it should work if the first number is 90
; 90H = 144D --(+0D)--> 144D = 90H
; 8FH = 143D --(-6D)--> 137D = 89H
; 8EH = 142D --(-6D)--> 136D = 88H
; 8DH = 141D --(-6D)--> 135D = 87H
; 8CH = 140D --(-6D)--> 134D = 86H
; 8BH = 139D --(-6D)--> 133D = 85H
; 8AH = 138D --(-6D)--> 132D = 84H
but since there is nothing for Decimal Adjust after subtraction how could i achieve the desired result ?
The desired output,
90 89 88 87 86 85....
Solution
You can't subtract 1, but you can add 99.
ADD A, #99H
DA A
OTHER TIPS
What I understand from your question is that you want to display a 2-digit decimal down count starting with initial value 99d and ending with 00d.
I agree with NovaDenizen. Here is the explanation :
The limitation what you encounter is that the DA A instruction doesn't work after subtraction. Now then you have to make use of alternative logic wherein the subtraction operation is implemented as special form of addition. Immediate implication of this idea is to make use of complement's method. In 10s' complement method adding 99 is equivalent to subtracting -01. Hence this is how your code should be :
ORG 0000H
MOV P1,#99H
MOV A,#99H ; A=99h
BACK: ACALL DELAY ; Call Delay Routine
ADD A,#99H ; Realize count down action by adding 99H
(equivalent to subtracting 01)
DA A ; Decimal Adjust to realize the BCD format representation
MOV P1,A ; Display the count on P1
JNZ BACK ; Continue till the count ends with 00
SJMP $ ; termination of the program
DELAY: MOV R1,#0FFH ; Delay Routine to generate certain delay.
DEC1: MOV R2,#0FFH
DEC2: MOV R3,#0FFH
DJNZ R3,$
DJNZ R2,DEC2
DJNZ R1,DEC1
RET
END
( Run the program in Keil and check for output on Port 1. )
Hope this helps you. Regards