Write an ATmega32-compatible program that adds two 10-digit ASCII numbers (which
ID: 3856742 • Letter: W
Question
Write an ATmega32-compatible program that adds two 10-digit ASCII numbers (which are located in code ROM), that is, DATA1 + DATA2. The result should be saved to RESULT in ASCII located in data RAM (accounting for the possibility of carry-out). They can be defined as follows: CSEG ORG 0x100 DATA1: .DB "2468101214" DATA2: .DB "1357911130" DSEG ORG 0x100 RESULT: .BYTE 11 Note that there are many ways you can approach solving this problem: Convert the ASCII representation to a 36-bit binary number and then add the two 5-byte representations. Add the corresponding ASCII digits 10 times, and write code to handling carry out d conversions to ensure the result looks correct. Convert to a BCD representation (or packed BCD) and adding that way, then converting back.Explanation / Answer
CONVERT NULL-TERMINATED STRING TO 32 BIT BINARY ; *=_origin_ ; strbin stx ptr01 ;save string pointer LSB sty ptr01+1 ;save string pointer MSB lda #0 ldx #s_fac-1 ;accumulator size ; strbin01 sta pfac,x ;clear dex bpl strbin01 ; ; ------------------------ ; process radix if present ; ------------------------ ; tay ;starting string index clc ;assume no error for now lda (ptr01),y ;get a char bne strbin02 ; rts ;null string, so exit ; strbin02 ldx #n_radix-1 ; strbin03 cmp radxtab,x ;recognized radix? beq strbin04 ;yes ; dex bpl strbin03 ;try next ; stx radxflag ;assuming decimal... inx ;which might be wrong ; strbin04 lda basetab,x ;number bases table sta valdnum ;set valid numeral range lda bitstab,x ;get bits per digit sta bitsdig ;store txa ;was radix specified? beq strbin06 ;no ; iny ;move past radix ; strbin05 sty stridx ;save string index ; ; -------------------------------- ; process number portion of string ; -------------------------------- ; strbin06 clc ;assume no error for now lda (ptr01),y ;get numeral beq strbin17 ;end of string ; inc stridx ;point to next cmp #'a' ;check char range bcc strbin07 ;not ASCII LC ; cmp #'z'+1 bcs strbin08 ;not ASCII LC ; and #a_maskuc ;do case conversion ; strbin07 sec ; strbin08 sbc #'0' ;change numeral to binary bcc strbin16 ;numeral > 0 ; cmp #10 bcc strbin09 ;numeral is 0-9 ; sbc #a_hexnum ;do a hex adjust ; strbin09 cmp valdnum ;check range bcs strbin17 ;out of range ; sta curntnum ;save processed numeral bit radxflag ;working in base 10? bpl strbin11 ;no ; ; ----------------------------------------------------------- ; Prior to combining the most recent numeral with the partial ; result, it is necessary to left-shift the partial result ; result 1 digit. The operation can be described as N*base, ; where N is the partial result & base is the number base. ; N*base with binary, octal & hex is a simple repetitive ; shift. A simple shift won't do with decimal, necessitating ; an (N*8)+(N*2) operation. PFAC is copied to SFAC to gener- ; ate the N*2 term. ; ----------------------------------------------------------- ; ldx #0 ldy #s_fac ;accumulator size clc ; strbin10 lda pfac,x ;N rol ;N=N*2 sta sfac,x inx dey bne strbin10 ; bcs strbin17 ;overflow = error ; strbin11 ldx bitsdig ;bits per digit ; strbin12 asl pfac ;compute N*base for binary,... rol pfac+1 ;octal &... rol pfac+2 ;hex or... rol pfac+3 ;N*8 for decimal bcs strbin17 ;overflow ; dex bne strbin12 ;next shift ; bit radxflag ;check base bpl strbin14 ;not decimal ; ; ------------------- ; compute (N*8)+(N*2) ; ------------------- ; ldx #0 ;accumulator index ldy #s_fac ; strbin13 lda pfac,x ;N*8 adc sfac,x ;N*2 sta pfac,x ;now N*10 inx dey bne strbin13 ; bcs strbin17 ;overflow ; ; ------------------------------------- ; add current numeral to partial result ; ------------------------------------- ; strbin14 clc lda pfac ;N adc curntnum ;N=N+D sta pfac ldx #1 ldy #s_fac-1 ; strbin15 lda pfac,x adc #0 ;account for carry sta pfac,x inx dey bne strbin15 ; bcs strbin17 ;overflow ; ; ---------------------- ; ready for next numeral ; ---------------------- ; ldy stridx ;string index bpl strbin06 ;get another numeral ; ; ---------------------------------------------- ; if string length > 127 fall through with error ; ---------------------------------------------- ; strbin16 sec ;flag an error ; strbin17 rts ;done ; ;================================================================================ ; ;CONVERSION TABLES ; basetab .byte 10,2,8,16 ;number bases per radix bitstab .byte 3,1,3,4 ;bits per digit per radix radxtab .byte " %@$" ;valid radix symbols ; ;================================================================================ ; ;DYNAMIC STORAGE ; bitsdig *=*+1 ;bits per digit curntnum *=*+1 ;numeral being processed radxflag *=*+1 ;$80 = processing base-10 valdnum *=*+1 ;valid range +1 for selected radix ; ;================================================================================ .end
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.