雪球丶 发表于 2020-3-17 17:39:21

实验10(3)数值显示

本帖最后由 雪球丶 于 2020-3-17 22:46 编辑

assume cs:code,ss:stack

data segment
        db 10 dup(0)
data ends

stack segment
        db 128 dup(0)
stack ends

;将12666以十进制的形式在屏幕的8行3列用绿色显示出来
code segment
start:
                mov ax,stack
                mov ss,ax
                mov sp,128
               
                mov ax,12666;12666=317AH
                mov dx,0H
                mov bx,data
                mov ds,bx
                mov si,0
                call dtoc
               
                mov dh,8
                mov dl,3
                mov cl,2
                call show_str
               
                mov ax,4C00H
                int 21H


;将word(16位)型数据转变位标识十进制数的字符串,字符串以0结尾,存放在ds处
;输入参数:
;                (ax)=word型数据
;                ds:si指向字符串首地址
;返回值: 无
;32位除法所需的寄存器:DX被除数的高16位,AX被除数的低16位,reg,除数(这里是cx)结果:AX商,DX余数
dtoc:        ;mov dx,0000H
                mov di,si
                mov bx,0        ;字符长度计数
                ;输入参数:
                ;        (ax)=dword型数据的低16位
                ;        (dx)=dowrd型数据的高16位
                ;        (cx)=除数
                ;返回值:
                ;        (dx)=结果的高16位,(ax)=结果的低16位
                ;        (cx)=余数
        s0:        mov cx,0AH
                push bx                                ;divdw函数内部会改变bx的值,把bx暂存起来
                push si
                call divdw
                pop si
                pop bx
                push cx                                ;数据入栈,因为算出来的顺序是反的,所以用栈来倒一下;
                inc bx
                ;检查商是否为0,为0则计算结束,跳出循环
                push ax                                ;ax寄存器的值后面还有用,先保存起来
                or ax,dx
                mov cx,ax
                pop ax
                jcxz s1
                inc di
                mov cx,2
                loop s0
        s1:        mov di,si
                mov cx,bx
        ens:
                pop ax
                add ax,30H                        ;转换为ASCII
                mov ds:,al
                inc di
                loop ens
                mov cl,0                        ;末尾写入0
                mov ds:,cl
                ret
               
show_str:
                mov ax,0b800H        ;显存地址
                mov es,ax
                ;计算像素点索引 8行3列像素点索引=8*160+3*2
                add dl,dl
                mov al,dh
                mov bl,160
                mul bl                        ;计算出来的行号存储在ax中
               
                mov dh,0
                add ax,dx               
                mov di,ax                ;像素写索引
                mov dh,cl                ;先用dl记录下颜色值,后面直接用dx寄存器写显存;CX寄存器在循环中会被用到,释放cl
        ws:                                        ;写显存
                mov dl,ds:
                mov es:,dx
                inc si
                add di,2
                ;查看下一位是否为0
                mov cx,0
                mov cl,ds:
                jcxz wd                        ;若下一位为0,则跳转到wd处
                mov cx,2                ;给CX赋值,如果程序走到这里说明下一位不为0就让其不断循环继续往下写
                loop ws
        wd:        ret

divdw:
                mov si,ax        ;低16位暂存在si中
                ;计算高16位,将16位计算转化为32位计算
                mov ax,dx
                mov dx,0
                div cx
                mov bx,ax         ;H/N存放在BX中
                ;计算低16位
                mov ax,si
                div cx
               
                mov cx,dx
                mov dx,bx
                ret
               
       
code ends
end start
页: [1]
查看完整版本: 实验10(3)数值显示