jeset 发表于 2013-4-13 11:13:51

实验10(3)解析

自己做的程序,如果有什么不对的地方,或者没有优化的地方,请指出!
assume cs:code,ds:data,ss:stack
data segment
db 10 dup (0)
data ends
stack segment
dw 16 dup (0)
stack ends
code segment
start:
mov ax,12666
mov bx,data
mov ds,bx
mov bx,stack
mov ss,bx
mov si,0
call dtoc

mov dh,8
mov dl,3
mov cl,2
call show_str

mov ax,4c00h
int 21h
;程序开始,参数:ax等于被除数,ds:si指向要转换的首地址
dtoc:
mov dx,0   ;先至零dx一次
push dx    ;然后push dx=0,用于后面pop cx=0检测
mov bx,10   ;除数
chufa:
mov dx,0
div bx    ;得到余数以及商
mov cx,ax   ;检测商是否为零
add dl,30H   ;余数+30H等于字符串16进制的ascii码
push dx    ;保存dx
jcxz xrnc   ;商不为零则向下继续执行,为零则跳转
jmp chufa
xrnc:
pop cx    ;弹出余数至零
mov ch,0   ;ch至零,因为开始压入一个dx=0
jcxz dtocover;如果为零则跳转结束
mov ds:,cl;不为零则复制至ds:数据段
inc si
jmp xrnc

dtocover:
mov si,0   ;至si为零,因为show_str程序参数需要
ret


;参数:dh=行号,dl=列号,cl等于颜色,di:si指向字符串首地址
show_str:
;寄存器保存
push ax
push bx
push cx
push dx
push di
push si
;结束保存
;主程序开始
mov ax,0B800H
mov es,ax
mov bx,0

mov al,160 ;每行160个内存单元
mul dh;ax得到行号
mov bx,ax ;保存到bx

mov al,2;每行80个字符,每个字符后面单元为属性
mul dl;得到显示列号
mov di,ax;保存至di
mov al,cl   ;把属性给al,因为cl要用来做检测是否为零
mov ch,0 ;把ch至零

;开始显示
xianshi:

mov cl,ds:    ;把内存单元中的字符给cl,因为一个字符等于一个内存单元,所以用cl
jcxz xianshiover;如果检测到cx 为零,那么跳转至结束,如果没有结束,那么向下继续执行
mov es:,cl ;把cl中的字符复制给es:中的显存地址
mov es:,al ;把属性复制给+1的位置
add di,2   ;目标地址列号+2,因为一个地址放置字符,一个地址放置属性
inc si    ;源地址内存单元si+1
jmp xianshi
xianshiover:
pop si
pop di
pop dx
pop cx
pop bx
pop ax
ret

code ends
end start


页: [1]
查看完整版本: 实验10(3)解析