how to accept input with a large (multi-digit) num

2020-03-08 06:43发布

问题:

How to accept input with a large number then compare it for example

mov ah,01h
int 21h

i want to accept more than one characters and move that number to al to access the port in blinking an led by input of the user example the user wants to type 32 but single character was

mov bl,al
delay:
mov ctr,'0'
mov al,bl
mov cx,100
skip:
x:
mov al,00000000b
mov dx,378h
out dx,al
loop x

Z: mov al,bl
mov dx,378h
out dx,al 
loop z
inc ctr

Cmp ctr,'8'
Je exit
jmp skip
Exit :
Mov ah,4ch
int 21h 
End start

回答1:

To input a 2-digit number you simply repeat the input for 1 character 2 times and combine the results:

mov ah, 01h
int 21h
sub al, '0'
mov bl, al     ;1st digits "tens"
mov ah, 01h
int 21h
sub al, '0'    ;2nd digit "units"
xchg al, bl
mov ah, 10
mul ah
add al,bl

Here AL will hold your number 32 if the first input was character "3" and the second input was character "2".


Without re-initializing the CX register, your Z-loop will iterate 65536 times because at the end of the X-loop the CX register will be 0! Is this intentional?



回答2:

If you need to accept numbers with more than one digit you need to execute two steps:

  1. Accept the number as string, not as individual chars.
  2. Convert the string into a number with a procedure.

This is how you accept a string:

mov ah, 0ah
mov dx, the_string
int 21h

The variable the_string need this specific format:

the_string db 26         ;MAX NUMBER OF CHARACTERS ALLOWED (25).
           db ?          ;LENGTH (NUMBER OF CHARACTERS ENTERED BY USER).
           db 26 dup (?) ;CHARACTERS ENTERED BY USER (END WITH 0AH).

Notice the three sections: the first byte indicates the maximum number of chars allowed (plus one because of the ENTER key at the end), the second byte will store the length of the entered string, the third section is the array of chars (ended with ENTER key = '0ah').

Once you accepted the string, it is necessary to convert it into a number with a known algorithm: process the chars from right to left multiplying each by a power of 10. We will call this procedure "string2number".

The procedure "string2number" takes one parameter: register SI pointing to the string variable (the one with the three sections). The number is returned in register BX. If the number is small it may fit into BL. This procedure will be very useful for you in your future programs.

Next is your code with the changes and the procedure "string2number" at the end :

.model small
.stack 100h
.data                                           

str   db 4         ;MAX NUMBER OF CHARACTERS ALLOWED (3).
      db ?         ;LENGTH (NUMBER OF CHARACTERS ENTERED BY USER).
      db 4 dup (?) ;CHARACTERS ENTERED BY USER (END WITH 0AH).
ctr   db 0      

.code
    mov  ax, @data
    mov  ds, ax   

;   mov ah,01h
;   int 21h
    mov ah, 0ah        ;◄■ CAPTURE STRING FROM KEYBOARD.
    mov dx, offset str ;◄■ VARIABLE TO STORE THE STRING.
    int 21h 

    mov si, offset str ;◄■ STRING TO CONVERT INTO NUMBER.
    call string2number ;◄■ NUMBER WILL RETURN IN BX.
    mov al, bl         ;◄■ COPY NUMBER INTO AL.    

    delay:
    mov ctr,'0'
    mov al,bl
    mov cx,100
    skip:
    x:
    mov al,00000000b
    mov dx,378h
    out dx,al
    loop x

    Z: mov al,bl
    mov dx,378h
    out dx,al 
    loop z
    inc ctr

    Cmp ctr,'8'
    Je exit
    jmp skip
    Exit :
    Mov ah,4ch
    int 21h 
;   End start    
;▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼
;CONVERT STRING TO NUMBER IN BX.
;SI MUST ENTER POINTING TO THE STRING.
proc string2number
;MAKE SI TO POINT TO THE LEAST SIGNIFICANT DIGIT.
  inc  si ;POINTS TO THE NUMBER OF CHARACTERS ENTERED.
  mov  cl, [ si ] ;NUMBER OF CHARACTERS ENTERED.                                         
  mov  ch, 0 ;CLEAR CH, NOW CX==CL.
  add  si, cx ;NOW SI POINTS TO LEAST SIGNIFICANT DIGIT.
;CONVERT STRING.
  mov  bx, 0
  mov  bp, 1 ;MULTIPLE OF 10 TO MULTIPLY EVERY DIGIT.
repeat:
;CONVERT CHARACTER.                    
  mov  al, [ si ] ;CHARACTER TO PROCESS.
  sub  al, 48 ;CONVERT ASCII CHARACTER TO DIGIT.
  mov  ah, 0 ;CLEAR AH, NOW AX==AL.
  mul  bp ;AX*BP = DX:AX.
  add  bx,ax ;ADD RESULT TO BX. 
;INCREASE MULTIPLE OF 10 (1, 10, 100...).
  mov  ax, bp
  mov  bp, 10
  mul  bp ;AX*10 = DX:AX.
  mov  bp, ax ;NEW MULTIPLE OF 10.  
;CHECK IF WE HAVE FINISHED.
  dec  si ;NEXT DIGIT TO PROCESS.
  loop repeat ;COUNTER CX-1, IF NOT ZERO, REPEAT.

  ret 
endp