我不知道我做错了什么。我是初学者。请帮帮我
这是我的代码:
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
- 我将从stdin中读取的数字以ASCII格式存储在要求和的函数中。
- 我迭代数组并将每个元素转换为二进制
- 然后我试着用3除这个数来检查整除性。
但它不起作用。它告诉我0和能被3整除的数的contor的和是1。
我将感谢任何有用的输入。
1条答案
按热度按时间yv5phkfx1#
NUMAR 不正确
每次要计算它时,都需要事先将其值重置为零。在 * AGAIN 2 * 循环中,您忘记了递增SI,以便使用所有不同的数字。一旦这个
inc si
到位,您就不再需要标签 NU_E_DIV3: 周围的其他INC SI
指令。SUMA 小3倍
因为在将AX除以3之后直接将AX加到 SUMA 上,所以所加的内容不会反映 NUMAR 的原始值。
SUMA_NUMERE 循环不好
你有
MOV CX,5
,你不使用以后,你有CMP BP, 35H
JE END
,这是远远超过你有数据项!你需要选择你想要使用的...
AFISARE_SUMA 做得太多
; pot rezulta siruri ASCII cu 5 cifre
)。