将ASCII数字数组转换为x86 16位汇编中的二进制数字

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

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

问题

我想将数组'VECTOR'中存储的所有ASCII数字转换为二进制形式,因为我想对它们进行求和,但我不知道如何计算一个数字有多少位以执行转换。有人可以修改我的函数ASCBIN2吗?

DOSSEG
.MODEL SMALL
.STACK 32

.DATA
        VECTOR           DB 5 DUP(20H,20H,20H)            ;20个数字,最多3位
        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                             ; 二进制形式的数字
        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                           ; 显示查询字符串

                MOV  [KBD+1],0
                MOV  AH,0Ah
                MOV  DX,OFFSET KBD
                INT  21H                           ; 读取1到3位数字
    
                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                           ; 显示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                        ; 但如果数字有3位呢?
                MOV  BX, 10
                MOV  SI, OFFSET VECTOR

        AGAIN2: MOV  AX, [NUMAR]
                MUL  BX                            ; 用10乘以部分和
                MOV  DL,[SI]
                MOV  DH,0
                AND  DL,0FH                        ; 将当前数字转换为二进制的ASCII码
                ADD  AX,DX                         ; 加上当前数字
                MOV  [NUMAR],AX
                INC  SI
                LOOP AGAIN2
                POP  CX

                RET

    END START

需要迭代每个元素并将其转换为二进制形式。我不知道如何计算每个数字的位数。

英文:

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

答案1

得分: 1

以下是已翻译的代码部分:

ASCBIN2:
  push cx
  xor  bx, bx            ; 所以 BH 为零
  mov  cx, 3             ; 总是处理所有三个字节
  mov  si, OFFSET VECTOR
  xor  di, di            ; 让 DI 扮演 NUMAR 的角色
AGAIN2:
  mov  bl, [si]          ; BH=0 BL={“ ”, “0”, “1”, ... , “9”}
  sub  bl, “0”           ; 从[“0”,”9”]到[0,9],但是 ...
  jb   SkipSpace         ; 如果 BL 是空格字符,则产生借位
  mov  ax, 10            ; 不需要浪费一个寄存器来存储常数 10
  mul  di
  mov  di, ax
  add  di, bx
SkipSpace:
  inc  si
  dec  cx
  jnz  AGAIN2
  mov  NUMAR, di
  pop  cx

如果任务允许,可以将扩展乘法 mul di 替换为非扩展乘法 IMUL DI, 10,这样 DX 就可以作为计数器可用:

ASCBIN2:
  mov   dx, 3             ; 总是处理所有三个字节
  mov   si, OFFSET VECTOR
  xor   di, di            ; 让 DI 扮演 NUMAR 的角色
AGAIN2:
  movzx bx, byte ptr [si] ; BX={“ ”, “0”, “1”, ... , “9”}
  sub   bx, “0”           ; 从[“0”,”9”]到[0,9],但是 ...
  jb    SkipSpace         ; 如果 BX 是空格字符,则产生借位
  imul  di, 10
  add   di, bx
SkipSpace:
  inc   si
  dec   dx
  jnz   AGAIN2
  mov   NUMAR, di

请注意,这是对给定汇编代码的翻译和注释,不包括完整上下文。

英文:

> 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: https://stackoverflow.com/questions/76527222/allocate-and-initialize-a-vector-of-20-elements-in-the-range-20-200-calculate/76527726#76527726, 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

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

发表评论

匿名网友

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

确定