assemblyx86dosreal-mode

Reading integers > 9 in x86 assembly


I want to read integers from input in x86 assembly but have some problems doing so when the integer is bigger than 9.

I tried the following code (found in internet) :

.code
  mov bh,0
  mov bl,10
inputloop:
  mov ah,1
  int 21h
  cmp al,13
jne convertion
jmp startcalc

convertion:
  sub al,48
  mov cl,al
  mov al,bh
  mul bl
  add al,cl
  mov bh,al
jmp inputloop    

startcalc:

I want my program to store the correct number in ax register at the start of startcalc label.

What should I do and what should I change in this program?


Solution

  • Oh! My! That code limits your input to a number within 1 byte, so between 0 and 255.

    Using bx to store the result, I would use something like this:

      mov bx, 0
    
    inputloop:
    
      mov ah, 1   ; getc()
      int 21h
    
      cmp al, 13  ; enter?
      je startcalc
    
      sub al, 48  ; character to number (assuming user only types '0' to '9')
      mov ah, 0   ; clear ah
    
      shl bx, 1   ; x2
      mov cx, bx
      shl bx, 2   ; x4 (so x8 total)
      add bx, cx  ; x2 + x8 = x10
      add bx, ax
    
      jmp inputloop
    
    startcalc:
       mov ax, bx  ; if you want the result in ax instead
    

    Now your number is between 0 and 65535, at least.

    Note: the shl and add to do the "bx × 10" could be replaced by an imul on newer processors since those run that instruction in three cycle. Much older processors were really slow and the 4 instructions above were more than twice faster (or 5 instructions on 8086 where shl did not accept an immediate other than 1). As Peter mentioned below, the lea trick can also be used.