assemblyx86-1616-bit

convert an array of ascii numbers in binary numbers assembly x86 16-bit


I want to convert all the ascii numbers that i stored in the array 'VECTOR' in binary form because i want to make the sum of them, but i don't know how to count how many digits that a number has to perform the convert.. can someone modify my function ASCBIN2??

DOSSEG
.MODEL SMALL
.STACK 32


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 1000,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=$'
        MSJ_CONTOR       DB 'NR_DIV3=$'
        NUMAR            DW 0                             ; numar in cod binar
        MESAJ_SUMA       DB 0Dh,0Ah,'Suma =     $'

.CODE
        START:  
                MOV  AX, @DATA
                MOV  DS, AX

                CALL CITESTE
                CALL CRLF
                CALL AFISARE
                CALL CRLF
                CALL ASCBIN

                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 IN ASCII

                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

        ASCBIN: MOV  CX, 5

        ASCBIN2:
                PUSH CX
                MOV  CX, 2                        ; but if i have a number on 3 digits??
                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
                INC  SI
                LOOP AGAIN2
                POP  CX

                RET

    END START

I need to iterate each element and convert it in binary. i dont know how to count the digits of every number


Solution

  • can someone modify my function ASCBIN2??

    Your concern is about ASCBIN2 only, and more precisely about MOV CX, 2 ; but if i have a number on 3 digits??.
    Because of the definition VECTOR DB 5 DUP(20H,20H,20H) and the fact that you insert the numbers using right-alignment and space-padding on the left, you have to deal with next cases:

    0-digit number eg. "   "
    1-digit number eg. "  7"
    2-digit number eg. " 94"
    3-digit number eg. "208"
    

    The solution must always process all 3 bytes, and simply skip the byte if it contains a space character:

    ASCBIN2:
            PUSH CX
            mov  cx, 3               ; ALWAYS ALL THREE BYTES
            MOV  BX, 10
            MOV  SI, OFFSET VECTOR
    
    AGAIN2:
            cmp  byte ptr [si], " "  ; SKIP LEADING SPACE(S)
            je   SkipSpace
            MOV  AX, [NUMAR]
            MUL  BX
            MOV  DL,[SI]             ; THIS IS "0" ... "9"
            MOV  DH,0
            AND  DL,0FH              ; CONVERT INTO 0 ... 9
            ADD  AX,DX
            MOV  [NUMAR],AX
    SkipSpace:
            INC  SI
            LOOP AGAIN2
            POP  CX
    

    Just like I wrote in the answer to another question of yours: Allocate and initialize a vector of 20 elements in the range [20-200]. Calculate and print the average of elements divisible by 3, you still need to zero the NUMAR variable before doing this calculation. Adding the zeroing and coming up with some improvements like combining 'Test For Space' with 'Conversion From ASCII':

    ASCBIN2:
      push cx
      xor  bx, bx            ; So BH is zero
      mov  cx, 3             ; ALWAYS ALL THREE BYTES
      mov  si, OFFSET VECTOR
      xor  di, di            ; Let DI play the part of NUMAR
    AGAIN2:
      mov  bl, [si]          ; BH=0 BL={" ", "0", "1", ... , "9"}
      sub  bl, "0"           ; From ["0","9"] to [0,9], BUT ...
      jb   SkipSpace         ; produces a borrow if BL was a space character
      mov  ax, 10            ; No need to waste a register on the CONST 10
      mul  di
      mov  di, ax
      add  di, bx
    SkipSpace:
      inc  si
      dec  cx
      jnz  AGAIN2
      mov  NUMAR, di
      pop  cx
    

    If allowable for the task at hand, replace the widening multiplication mul di by the non-widening multiplication IMUL DI, 10 so that DX comes available as the counter:

    ASCBIN2:
      mov   dx, 3             ; ALWAYS ALL THREE BYTES
      mov   si, OFFSET VECTOR
      xor   di, di            ; Let DI play the part of NUMAR
    AGAIN2:
      movzx bx, byte ptr [si] ; BX={" ", "0", "1", ... , "9"}
      sub   bx, "0"           ; From ["0","9"] to [0,9], BUT ...
      jb    SkipSpace         ; produces a borrow if BX was a space character
      imul  di, 10
      add   di, bx
    SkipSpace:
      inc   si
      dec   dx
      jnz   AGAIN2
      mov   NUMAR, di