3
votes

I got the user to enter a 16 bit number. I want to display the number entered by the user.

This is what I've come up with so far.

As you can see, I have subtracted 30H from the input to convert it to decimal. Where should I add 30H back to get it back to its original ASCII value?

        MOV AH,1H         ;user input for first number part 1 
        INT 21H 
        SUB AL,30H  
        MOV NUM1,AL

        MOV AH,1H         ;1st number part 2
        INT 21H           
        SUB AL,30H 
        MOV NUM2,AL  

        MOV AH,1H         ;1st number part 3
        INT 21H
        SUB AL,30H
        MOV NUM3,AL                         

        MOV AH,1H         ;1st number part 4
        INT 21H
        SUB AL,30H 
        MOV NUM4,AL

        XOR AH,AH                  
        MOV AL,NUM1       
        MOV DX,1000D
        MUL DX            ;1*1000
        ADD AH,30H
        ADD AL,30H
        MOV BX,AX        

        XOR AH,AH                  
        MOV AL,NUM2
        MOV DX,100D       
        MUL DX            ;2*100
        ADD BX,AX

        XOR AH,AH
        MOV AL,NUM3
        MOV DX,0010D
        MUL DX            ;3*10
        ADD AH,30H
        ADD AL,30H
        ADD BX,AX  

        XOR CH,CH
        MOV CL,NUM4
        ADD CH,30H
        ADD CL,30H
        ADD BX,CX       ;BX now has the 16 bit number


        MOV FNUM1,BX      ;final 1st 16 bit number


        PRINTN

        LEA DX,MSG8       ;msg for output
        MOV AH,9H
        INT 21H

        PRINT FNUM1

For eg: when I enter the number as 1234, I get output as F. Can you guys let me know what I'm doing wrong and help me out? Any help would be appreciated at this point.

1
so if the bytes 0x31, 0x32, 0x33, 0x34 represent your input of the value 1234 what is your expected output? kinda looks like you are trying to get 0x31, 0x32, 0x33, 0x34 out which is the input, but I assume that is not the case? Your code doesnt make sense yet so thus the question of what your goal isold_timer
your input wasnt decimal so using terms like that dont mean much, lets talk bits and bytes. I start with these bits/bytes and I want to end up with these bits or bytes.old_timer
ADD AX,3030H after a 16-bit multiply makes zero sense. You have a binary integer, not two BCD digits. See NASM Assembly convert input to integer? for simple / working string->int functions that take an ASCII decimal string and produce a binary integer in a register.Peter Cordes

1 Answers

4
votes

First get the input right.

Once you got the 4 digits from input you need to combine them adhering to the formula
d1 * 1000 + d2 * 100 + d3 *10 + d4 Nowhere in this calculation are you required to add in 48!

The multiplication *1000 needs a word-sized mul, but multiplying *100 and *10 can do with a byte-sized mul.

mov     al, NUM1
cbw                   ; -> AH=0
mov     dx, 1000
mul     dx            ; Product 1*1000 in DX:AX but with DX=0
mov     bx, ax        

mov     al, 100
mul     NUM2          ; Product 2*100 in AX
add     bx, ax

mov     al, 10
mul     NUM3          ; Product 3*10 in AX
add     bx, ax  

add     bl, NUM4
adc     bh, 0         ; BX now has the 16 bit number

A nicer version of the above uses a loop. This loop can only work if you define your NUMx variables as consecutive bytes in memory!

NUM1 db 0
NUM2 db 0
NUM3 db 0
NUM4 db 0

...

    mov     cx, 4    ; Number of digits
    lea     si, NUM1 ; Address of 1st digit (most significant digit)
    xor     bx, bx   ; The 16-bit result
More:
    imul    bx, 10   ; BX = BX * 10
    lodsb            ; NUM1 then NUM2 then NUM3 then NUM4
    cbw
    add     bx, ax
    dec     cx
    jnz     More

Then output to the screen.

I want to display the number entered by the user.

Move the 16-bit number stored in BX (from the previous steps) to the AX register and then read my explanations on how to convert a 16-bit number in AX into text so it can be printed to the screen at Displaying numbers with DOS.