|
主题 : : 我的子程序代码,大家也贴出自己的相互学习吧? [待解决] |
回复[ 7次 ]
点击[ 2037次 ] | |
|
|
|
|
[帖 主] [ 发表时间:2007-10-05 13:15 ] | |
荣誉值:0
信誉值:13
注册日期:2007-09-26 02:27 |
assume cs:code
data segment
db 10 dup (0)
data ends
stack segment
db 16 dup(0)
stack ends;
code segment
start:
mov ax,12666
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
dtoc:
push cx
push si
push bx
push dx
push ds
mov dx,0
mov bx,0
div_cur:
mov cx,0Ah
call divdw ;调用解决溢出的除法
jcxz s ;余数=0,跳出
add cx,30H ;将余数转换成ASCII码
push cx
inc bx
jmp short div_cur
s:
mov cx,bx
s1:
pop ax
mov byte ptr ds:[si],al
inc si
loop s1
ok1:
pop ds
pop dx
pop bx
pop si
pop cx
ret
divdw:
push bx
push ax
mov ax,dx
mov dx,0
div cx
mov bx,ax ;将商的高位临时放到bx中
pop ax
div cx ;上一步div的余数(在dx中)做高位,连同ax中的数据(低位)一起做被除数
mov cx,dx ;将余数给cx
mov dx,bx
pop bx
ret
show_str:
push dx
push cx
push si
push es
push di
push ax
mov ax,0B800H
mov es,ax
mov ch,0
;计算dh*160,保存(dh*160)到di中
mov ax,0A0H
mul dh
mov di,ax
;计算2dl-1,保存(dh*160)+(2*dl-1)到di中,得到字符写入显存的偏移地址di
mov ax,2
mul dl
add di,ax
mov al,cl
next_zf:
mov cl,[si]
jcxz ok
;写入字符
mov byte ptr es:[di],cl
;写入颜色
mov byte ptr es:[di+1],al
add di,2
inc si
jmp short next_zf
ok:
pop ax
pop di
pop es
pop si
pop cx
pop dx
ret
code ends
end start | | |
|
|
|
|
[第3楼] [ 回复时间:2007-10-06 17:43 ] | |
荣誉值:0
信誉值:13
注册日期:2007-09-26 02:27 |
//修改后的,我的第一个存在问题,就是当数据末尾是零的时候会有问题
assume cs:code
data segment
db 10 dup (0)
data ends
stack segment
db 60 dup(0)
stack ends;
code segment
start:
mov ax,12660
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
;功能:将数字转换成字符后显示在屏幕上
;要求数小于65535
;参数说明:(ds数转换成字符后存储的段地址,si偏移首地址,字符存储后的末尾要为0,
ax存放dw数)
dtoc:
push cx
push si
push bx
push dx
push ds
push di
mov dx,0
mov bx,0
mov di,0
div_cur:
mov cx,0Ah
call divdw ;调用解决溢出的除法
mov bx,cx ;因为商是存放在cx中的所以要求处理的数一定要小于65535
mov cx,ax
jcxz my_s ;商=0,跳出
add bx,30H ;将余数转换成ASCII码
push bx
inc di ;di用于累计余数压入栈的次数
jmp short div_cur
my_s:
add bx,30H
mov byte ptr ds:[si],bl
mov cx,di
inc si
s1:
pop ax
mov byte ptr ds:[si],al
inc si
loop s1
ok1:
pop di
pop ds
pop dx
pop bx
pop si
pop cx
ret
;功能:避免溢出的除法
;公式:x/n=int(H/n)*65535+[rem(H/n)+L]/n
;参数:(ax,dd类型被除数的低位,dx高位,cx存放除数;)
;返回值:(dx,ax中放商,cx中放余数)
divdw:
push bx
push ax
mov ax,dx
mov dx,0
div cx
mov bx,ax ;将商的高位临时放到bx中
pop ax
div cx ;上一步div的余数(在dx中)做高位,连同ax中的数据(低位)一起做被除数
mov cx,dx ;将余数给cx
mov dx,bx
pop bx
ret
;功能:在屏幕指定位置显示字符
;参数:(dh:行号,dl:列号,cl字符的颜色属性,ds:字符的段地址,si:段偏移首地址)
;调用:要求字符末尾以0结束
show_str:
push dx
push cx
push si
push es
push di
push ax
mov ax,0B800H
mov es,ax
mov ch,0
;计算dh*160,保存(dh*160)到di中
mov ax,0A0H
mul dh
mov di,ax
;计算2dl-1,保存(dh*160)+(2*dl-1)到di中,得到字符写入显存的偏移地址di
mov ax,2
mul dl
add di,ax
mov al,cl
next_zf:
mov cl,[si]
jcxz ok
;写入字符
mov byte ptr es:[di],cl
;写入颜色
mov byte ptr es:[di+1],al
add di,2
inc si
jmp short next_zf
ok:
pop ax
pop di
pop es
pop si
pop cx
pop dx
ret
code ends
end start | | |
|