Allocate and initialize a vector of 20 elements in the range [20-200]. Calculate and print the average of elements divisible by 3

huangapple go评论62阅读模式
英文:

Allocate and initialize a vector of 20 elements in the range [20-200]. Calculate and print the average of elements divisible by 3

问题

我不知道我做错了什么。我是一个初学者。请帮助我。
这是我的代码:

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
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                         ;impart
<details>
<summary>英文:</summary>
I don&#39;t know what I&#39;m doing wrong. I&#39;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,&#39;Nr=$&#39;
MEDIE_ELEM_DIV3  DB 0
NR_ELEMENTE_DIV3 DB 0
SUMA             DW 0
MSJ_SUMA         DB &#39;SUMA=$&#39;
FLAG             DB 0
MSJ_CONTOR       DB &#39;NR_DIV3=$&#39;
NUMAR            DW 0
NUMASC           DB 0Dh,0Ah,&#39;Suma=     $&#39;
.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 &#39;NR_DIV3=&#39;
INT  21H
MOV  AL, [NR_ELEMENTE_DIV3]         ;NUMARUL
MOV  AH, 0                          ; deimpartitul este ax
MOV  BL, 10                         ;impartitorul
DIV  BL                             ;imparitm ax la bl -&gt; 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
- I stored the numbers that I read from the stdin in ASCII and in the function where I want to make the sum. 
- I iterate the array and convert each element in binary
- Then I tried to check the divisibility by dividing the number with 3.
But it doesn&#39;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.
</details>
# 答案1
**得分**: 0
*NUMAR* 不正确
-
每次你想要计算它时,你需要先将其值重置为零。在*AGAIN2*循环中,你忘记了增加SI以使用所有不同的数字。一旦`inc si`放在适当的位置,你就不再需要在*NU_E_DIV3:*标签周围拥有其他`INC SI`指令。

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


*SUMA* 小了3倍
-
因为你在将AX除以3之后直接将AX添加到*SUMA*,所以你添加的值将不反映*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


*SUMA_NUMERE* 循环不正确
-
你有一个`MOV CX,5`,后面没有使用,而且你有一个`CMP BP, 35H` `JE END`,这远远超过了你的数据项数量!你需要选择要使用的部分...
*AFISARE_SUMA* 做得太多
-
*TEN_POWER* 列表只有3个元素。你不能迭代4(+ 1)次(`; pot rezulta siruri ASCII cu 5 cifre`)。
<details>
<summary>英文:</summary>
*NUMAR* is not correct
-
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    &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;
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          &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;
LOOP AGAIN2
*SUMA* is 3x smaller
-
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  &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;
ADD  [SUMA], AX
inc  [NR_ELEMENTE_DIV3]
JMP  AGAIN2
*SUMA_NUMERE* does not loop good
-
You have `MOV CX,5` that you don&#39;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...
*AFISARE_SUMA* does too much
-
The *TEN_POWER* list has but 3 elements. You can&#39;t iterate 4 (+ 1) times (`; pot rezulta siruri ASCII cu 5 cifre`).
</details>

huangapple
  • 本文由 发表于 2023年6月22日 05:21:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76527222.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定