Ahtisham
Ahtisham

Reputation: 10106

Why does the following 8086 assembly code only display numbers up to 2559?

What am I trying to do ?

I want to get a 16-bit number from the user and print It on the console.

What Is the problem ?

Well my code works fine If the number entered Is less than 2600 but the moment I enter 2600 It displays "40" and for 2601 "41" and so on. Shouldn't It display numbers up to 65535 ? Because I am storing the value In the bx register which Is 16-bit and which can store at most 65535. Then why only 2559 ?

My code:

.model small
.data

msg db 10,13,'Enter a 16bit number: $'             
newline db 10,13,'$'

.code
main:

mov ax, @data
mov ds, ax

mov cl, 10
mov bx, 0

mov ah, 09h
lea dx, msg
int 21h

call get16bitNum

mov ah, 09h
lea dx, newline
int 21h

mov ax, '$'

push ax

mov ax, bx      

store:  

div cl
cmp al, 0 
mov bh, 0
mov bl, ah    
push bx
je continue        
mov ah, 0
jmp store

continue:

pop ax
cmp ax, '$'
je ext 
mov bx, ax
mov ah, 02h
mov dx, bx
add dx, 48
int 21h


jmp continue

ext:        

mov ah, 04ch
int 21h

proc get16bitNum

aggregate:

mov ah, 01h 
int 21h

cmp al, 13
je return 

mov ah, 0
sub al, 48     

mov dx, bx
mov bx, ax
mov ax, dx

mul cl
add bx,ax         
jmp aggregate                        

return:

ret    

endp                

end main

Upvotes: 2

Views: 278

Answers (2)

1010
1010

Reputation: 1848

8 bit div produces 8 bit quotient and remainder.
When you divide 2600 by 10 you get an 8 bit quotient, losing higher bits.

You should use 16 bit division.

Upvotes: 2

Fifoernik
Fifoernik

Reputation: 9899

You don't actually retrieve a 16-bit number!

You keep the desired input in BX, and so you need to multiply the whole of BX by 10. You do this using a word sized multiplication.

proc get16bitNum
  aggregate:
    mov  ah, 01h 
    int  21h
    cmp  al, 13
    je   return 
    mov  ah, 0
    sub  al, 48    ;AX is 0 to 9
    xchg ax, bx    ;New digit temporarily in BX
    mov  cx, 10
    mul  cx        ;Product is in DX:AX, but we won't use DX!
    add  bx ,ax    ;Add new digit
    jmp  aggregate                        
 return:
    ret

You don't display the 16-bit number

The procedure to convert the number into text will definitely need to use the word sized division.

For an excellent explanation on how to do this see this recent post Displaying numbers with DOS. It explains in great detail everything you need to know about converting numbers. It even uses the same technique of pushing some value in the stack (You used a $ character for this) to know where the number ends.

ps. If you find the info in the linked post useful don't hesitate to upvote it. (Of course I hope you find my answer useful too!)

Upvotes: 2

Related Questions