I don't know what I'm doing wrong. I'm a beginner. Please help me.
This is my code:
DOSSEG
.MODEL SMALL
.STACK 32
.DATA
VECTOR DB 5 DUP(20H,20H,20H) ;20 DE NR PE MAXIM 3 CIFRE
KBD DB 4,0,0,0,0,0
TEN_POWER DW 100,10,1
NUMERE DB 0Dh,0Ah,'Nr=$'
MEDIE_ELEM_DIV3 DB 0
NR_ELEMENTE_DIV3 DB 0
SUMA DW 0
MSJ_SUMA DB 'SUMA=$'
FLAG DB 0
MSJ_CONTOR DB 'NR_DIV3=$'
NUMAR DW 0
NUMASC DB 0Dh,0Ah,'Suma= $'
.CODE
START:
MOV AX, @DATA
MOV DS, AX
CALL CITESTE
CALL CRLF
CALL AFISARE
CALL CRLF
CALL SUMA_NUMERE
CALL AFISARE_SUMA
CALL CRLF
CALL AFISARE_CONTOR
MOV AH, 4CH
INT 21H
CITESTE:
MOV CX, 5
MOV DI,(OFFSET VECTOR)+3
AGAIN: PUSH CX
MOV DX,OFFSET NUMERE
MOV AH,9
INT 21H ; afiseaza sir de interogare
MOV [KBD+1],0
MOV AH,0Ah
MOV DX,OFFSET KBD
INT 21H ; citeste numar cu 1 pana la 3 cifre
MOV CL,[KBD+1]
MOV CH,0
MOV SI,(OFFSET KBD)+2
PUSH DI
SUB DI,CX
NEXT:
MOV AL,[SI]
MOV [DI],AL
INC SI ; memoreaza numar
INC DI
LOOP NEXT
POP DI
ADD DI,3
POP CX
LOOP AGAIN
RET
AFISARE:
MOV CX, 5
MOV SI,OFFSET VECTOR
DISP:
CALL CRLF
PUSH CX
MOV CX,3
NUM:
MOV AH,2
MOV DL,[SI]
INT 21h ; afiseaza sirul de numere
INC SI
LOOP NUM
POP CX
LOOP DISP
RET
CRLF:
MOV AH,2
MOV DL,0Ah
INT 21h
MOV AH,2
MOV DL,0Dh
INT 21h
RET
SUMA_NUMERE:
MOV CX, 5 ;ITERARE CELE 20 ELEM VECTOR
MOV SUMA, 0 ; INITIALIZARE CU 0
MOV [NR_ELEMENTE_DIV3], 0
MOV BP, 0
ASC_BIN:
PUSH CX
MOV CX, 3 ;AM 3 CIFRE
MOV BX, 10
MOV SI, OFFSET VECTOR
AGAIN2: MOV AX,[NUMAR]
MUL BX ; inmulteste suma partiala cu 10
MOV DL,[SI]
MOV DH,0
AND DL,0FH ; conversie ASCII binar pentru cifra curenta
ADD AX,DX ; aduna cifra curenta
MOV [NUMAR],AX ;NUMAR E NR MEU IN BINAR
LOOP AGAIN2
POP CX
CMP BP, 35H
JE END
INC BP
CONDITIE_DIV3:
XOR AX,AX
MOV AX,[NUMAR] ;PUN IN AX NR IN BINAR
MOV BL, 3
DIV BL ;IMPART ELEMENTUL LA 3
CMP AH, 0 ;COMPAR RESTUL CU 0
JNE NU_E_DIV3
ADD [SUMA], AX ;ADAUGA IN SUMA NR DIV 3
ADD [NR_ELEMENTE_DIV3], 1
INC SI
NU_E_DIV3:
INC SI
JMP AGAIN2
END: RET
AFISARE_SUMA:
BIN_ASC: MOV CX,4 ; din numere binare pe 16 biti
; pot rezulta siruri ASCII cu 5 cifre
MOV SI,OFFSET TEN_POWER ; pointer spre tabela puterilor lui 10
MOV DI,(OFFSET NUMASC)+7
NEXT3:
MOV AX,[SUMA]
MOV DX,0 ; pregateste deimpartitul pe 32 de biti
DIV WORD PTR [SI] ; obtine catul curent
MOV [SUMA],DX ; salveaza restul curent
OR AL,30H ; salveaza codul ASCII al cifrei curente
MOV [DI],AL
INC DI
ADD SI,2 ; avanseaza pointerul spre urmatoarea putere a lui 10
LOOP NEXT3
OR DL,30H ; salveaza codul ASCII al ultimei cifre (cifra unitatilor)
MOV [DI],DL
MOV AH, 09h
MOV DX, OFFSET NUMASC
INT 21H
RET
AFISARE_CONTOR:
AND [NR_ELEMENTE_DIV3], 0FH ; masca ultimii 4 biti - obtinem cifra coresp caracterului
MOV AH, 2 ;pregatire pt afisarea caracterului
MOV DL, 0DH ; carriage return
INT 21H ;apelarea intreruperii
MOV AH, 2
MOV DL, 0AH ;line feed
INT 21H
REZULTAT:
MOV AH, 9 ;pregatirea pentru afisarea unui string
MOV DX, OFFSET MSJ_CONTOR ;sirul FINAL 'NR_DIV3='
INT 21H
MOV AL, [NR_ELEMENTE_DIV3] ;NUMARUL
MOV AH, 0 ; deimpartitul este ax
MOV BL, 10 ;impartitorul
DIV BL ;imparitm ax la bl -> al = catul si ah = restul
PUSH AX ;salvez pe stiva rez impartirii
CMP AL, 0 ;daca suma are o singrua cifra
JE O_CIFRA ; sare si nu o mai afiseaza pe prima
MOV DL, AL ; pt afisarea catului, adica a primei cifre din suma
OR DL, 30H ;codul ascii al caracterului coresp cifrei din tabela ascii
MOV AH, 2
INT 21H
O_CIFRA:
POP AX ;scoate din stiva continutul reg ax
MOV DL, AH ;pt afisarea restului, adica celei de a doua cifre
OR DL, 30H ;obtinerea caract corespunzator
MOV AH, 2 ;pregatirea pt afisare
INT 21H ;apelarea intreruperii
RET
END START
But it doesn't work. It shows me the sum 0 and the contor of the numbers that are divisible with 3 to be 1.
I would appreciate any helpful input.
Each time that you want to calculate it, you need to reset its value to zero beforehand. And in the AGAIN2 loop you forgot to increment SI so as to use all the different digits. Once this inc si
is in place, you no longer need the other INC SI
instructions that you have around the label NU_E_DIV3:.
mov NUMAR, 0 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
MOV CX, 3 ; AM 3 CIFRE
MOV SI, OFFSET VECTOR
AGAIN2:
MOV AX, 10
MUL NUMAR ; inmulteste suma partiala cu 10
MOV DL, [SI]
AND dx, 000Fh ; conversie ASCII binar pentru cifra curenta
ADD AX, DX ; aduna cifra curenta
MOV NUMAR, AX ; NUMAR E NR MEU IN BINAR
inc si <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
LOOP AGAIN2
Because you add AX to SUMA directly after you divided AX by 3, what you add will not reflect the original value of NUMAR.
MOV AX, NUMAR ; PUN IN AX NR IN BINAR
MOV BL, 3
DIV BL ; IMPART ELEMENTUL LA 3
CMP AH, 0 ; COMPAR RESTUL CU 0
JNE AGAIN2 ; NU_E_DIV3
mov ax, NUMAR <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
ADD [SUMA], AX
inc [NR_ELEMENTE_DIV3]
JMP AGAIN2
You have MOV CX,5
that you don't use later on, and you have CMP BP, 35H
JE END
that is much more than you have data items for!
You need to choose which you want to use...
The TEN_POWER list has but 3 elements. You can't iterate 4 (+ 1) times (; pot rezulta siruri ASCII cu 5 cifre
).