assembly 分配并初始化一个在[20-200]范围内的20个元素的向量,计算并打印可被3整除的元素的平均值

njthzxwz  于 2023-06-30  发布在  其他
关注(0)|答案(1)|浏览(117)

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

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。
我将感谢任何有用的输入。

yv5phkfx

yv5phkfx1#

NUMAR 不正确

每次要计算它时,都需要事先将其值重置为零。在 * AGAIN 2 * 循环中,您忘记了递增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, 35HJE END,这是远远超过你有数据项!
你需要选择你想要使用的...

AFISARE_SUMA 做得太多

  • TEN_POWER* 列表只有3个元素。你不能迭代4(+ 1)次(; pot rezulta siruri ASCII cu 5 cifre)。

相关问题