任意输入两个数,如:123456,并在屏幕上输出:123+456=579

;0xB8000~0xBFFFF 这段物理地址空间,是留给显卡的,由显卡来提供,用来显示文本。
mov ax, 0xB800
mov es, ax

;初始化数据段寄存器
mov ax, 0x07C0
mov ds, ax 


mov di, 0 ;(目标地址段寄存器初始化)初始化显示段 偏移寄存器

jmp near Code

Number1:
    dw 123 ;输入第一个数的位置

Number2:
    dw 456 ;输入第二个数的位置


Split:
    db 0,0,0,0,0   ;个,十,百,千,万


Divisor:
    dw 10 ;除数



;-------------------------------输出第一个数-------------------------------------

; 第二种用法
; 32位除以16位
; div 16位寄存器
; div 16位内存  
; 被除数在DX:AX中,商在AX中,余数在DX中

Code:
    mov dx, 0
    mov ax, word[ds:Number1] ;dx:ax=123
    mov bx, Split


;把被除数通过div分解到Split处
StartSplit:
    ;ax(123) / 10, 余数在dx中,dx=0000 0000 0000 0011, dh=00000000, dl=00000011
    ;商在ax中,ax=12=0x000c
    div word[ds:Divisor] 

    ;就是把余数放到Split处
    mov byte[ds:bx], dl  

    ;被除数在dx:ax中,商又在ax中,所以重置dx=0
    mov dx, 0

    ;Split 下一位
    inc bx


;判断商ax是否为0,不为0就跳转到前面继续执行
cmp ax, 0
jne near StartSplit


;为了输出到屏幕做准备工作
sub bx, Split ;相减后,bx的值就是计算了Split存储了几位数
mov cx, bx    ;cx代表循环次数
mov si, Split ;(原始地址段寄存器初始化)初始化数据段 偏移寄存器
add si, bx    ;定位到Split分解数的最后一位(下面还需要减一),从最后一位开始输出
dec si


Print:
    mov al, byte[ds:si]
    add al, 48
    mov byte[es:di], al
    inc di
    mov byte[es:di], 0x07
    dec si
    inc di
loop Print



;-------------------------------输出+号---------------------------------------
mov byte[es:di], '+'
inc di
mov byte[es:di], 0x07
inc di



;-------------------------------输出第二个数----------------------------------
    mov dx, 0
    mov ax, word[ds:Number2] ;dx:ax=456
    mov bx, Split


;把被除数通过div分解到Split处
StartSplit2:
    ;ax(123) / 10, 余数在dx中,dx=0000 0000 0000 0011, dh=00000000, dl=00000011
    ;商在ax中,ax=12=0x000c
    div word[ds:Divisor] 

    ;就是把余数放到Split处
    mov byte[ds:bx], dl  

    ;被除数在dx:ax中,商又在ax中,所以重置dx=0
    mov dx, 0

    ;Split 下一位
    inc bx


;判断商ax是否为0,不为0就跳转到前面继续执行
cmp ax, 0
jne near StartSplit2


;为了输出到屏幕做准备工作
sub bx, Split ;相减后,bx的值就是计算了Split存储了几位数
mov cx, bx    ;cx代表循环次数
mov si, Split ;(原始地址段寄存器初始化)初始化数据段 偏移寄存器
add si, bx    ;定位到Split分解数的最后一位(下面还需要减一),从最后一位开始输出
dec si


Print2:
    mov al, byte[ds:si]
    add al, 48
    mov byte[es:di], al
    inc di
    mov byte[es:di], 0x07
    dec si
    inc di
loop Print2




;-------------------------------输出=号---------------------------------------
mov byte[es:di], '='
inc di
mov byte[es:di], 0x07
inc di




;-------------------------------输出第三个数----------------------------------
    mov dx, 0
    mov ax, word[ds:Number1]  
    add ax, word[ds:Number2]  ;123 + 456
    mov bx, Split


;把被除数通过div分解到Split处
StartSplit3:
    ;ax(123) / 10, 余数在dx中,dx=0000 0000 0000 0011, dh=00000000, dl=00000011
    ;商在ax中,ax=12=0x000c
    div word[ds:Divisor] 

    ;就是把余数放到Split处
    mov byte[ds:bx], dl  

    ;被除数在dx:ax中,商又在ax中,所以重置dx=0
    mov dx, 0

    ;Split 下一位
    inc bx


;判断商ax是否为0,不为0就跳转到前面继续执行
cmp ax, 0
jne near StartSplit3


;为了输出到屏幕做准备工作
sub bx, Split ;相减后,bx的值就是计算了Split存储了几位数
mov cx, bx    ;cx代表循环次数
mov si, Split ;(原始地址段寄存器初始化)初始化数据段 偏移寄存器
add si, bx    ;定位到Split分解数的最后一位(下面还需要减一),从最后一位开始输出
dec si


Print3:
    mov al, byte[ds:si]
    add al, 48
    mov byte[es:di], al
    inc di
    mov byte[es:di], 0x07
    dec si
    inc di
loop Print3


;----------------------------------------------------------------------------
End:
    jmp 0x07C0:End

times 510 - ($ -$$) db 0x00
dw 0xAA55 ; 相当于 db 0x55,0xAA