为什么下面的8086汇编代码只能显示2559以内的数字?

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

我想做什么?

我想从用户那里得到一个16位的数字并在控制台上打印它。

问题是什么?

我的代码工作正常如果输入的数字小于 2600 但当我输入 2600 时它显示“40”,对于 2601 显示“41”等等。它不应该显示最多 65535 的数字吗?因为我把值存入bx寄存器里,它是16位的,最多能存65535。那为什么只能存2559?

我的代码:

.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

8div产生8位商和余数。
当您将 2600 除以 10 时,您会得到一个 8 位的商,丢失更高的位。

你应该使用16位除法。

您实际上并没有检索到 16 位数字!

您将所需的输入保留在 BX 中,因此您需要将整个 BX 乘以 10。您使用 word 大小的乘法 [=30] =].

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

您没有显示 16 位数字

将数字转换为文本的过程肯定需要使用字大小划分

有关如何执行此操作的精彩解释,请参阅最近的 post Displaying numbers with DOS。它非常详细地解释了您需要了解的有关转换数字的所有信息。它甚至使用相同的技术在堆栈中压入一些值(你为此使用了 $ 字符)来知道数字在哪里结束。

ps。如果您觉得 the linked post 中的信息有用,请毫不犹豫地点赞它。 (当然也希望我的回答对你有用!)