|
主题 : : 第十章 实验十 (3) 接口化实现 算是我至今最满意的程序了! [待解决] |
回复[ 1次 ]
点击[ 317次 ] | |
荣誉值:30
信誉值:0
注册日期:2009-04-09 10:05 |
;'0~9'对应ASCII码为 30H~39H
;0代表字符按窜的结束,不显示
;不进行除法的防溢出,因为题目不要求
;就本题适应范围有限,不能识别为0的数值,遇到0就会返回
;目的是实现代码模块化,所学知识有限未免有疏忽
;以目前学到知道这个是我现在做出最满意的程序了
;标号紧贴左边的代表特殊作用的接口,以主程序为主体,接口为分支,进行跳转。
assume cs:code,ss:stack
data segment
dw 123,12666,1,8,3,38,0
data ends
show segment
dw 32 dup (0) ;line 10
show ends
stack segment
dw 32 dup (0)
stack ends
code segment
start: mov ax,stack ;start开始为主代码段引导其他接口工作
mov ss,ax ; 初始化 line 20
mov sp,64
mov bx,data
mov ds,bx
mov si,0
call dtoc ;访问dtoc接口
mov dh,16 ;行
mov dl,3 ;列
mov cl,2 ;颜色
call show_str ;访问show_str接口
mov ax,4c00h ;line 33
int 21H
dtoc: call backup ;原始数据保存
sub sp,16 ;寄存器备份栈状态还原
mov ax,show ;show segment=extra segment
mov es,ax
mov bx,10 ;除数
mov bp,0
;line 43
strip:mov ax,ds:[si] ;遇到0表示字符窜结束返回调用程序
mov cx,ax
jcxz return
mov di,0
div2: mov dx,0 ;高位清0
mov cx,ax
jcxz next ;遇到0表示商为0. 跳转到next
div bx ;否则进行除法 line53
add dl,30H ;余数+30H表示数字字符窜的ASCII码
mov ss:[di],dl ;用栈暂存数据
add di,1 ;表示这个字符窜长度
loop div2
next: mov cx,di ;进行一个数字字符窜位数交换
change: mov al,ss:[di-1] ;line 59
mov es:[bp],al
inc bp
dec di
loop change
mov byte ptr es:[bp],' ' ;添加空格区分数字 ;line 65
inc bp
add si,2
jmp strip ;跳转到strip进行其他数值处理
show_str:
call backup ;原始数据保存
sub sp,16 ;寄存器备份栈状态还原
mov bx,0 ;数据初始化
mov ax,0b800H ;确定显存所在段
mov es,ax
mov ax,show ;改变ds段为show
mov ds,ax
mov al,160 ;确定显存起始偏移地址
dec dh
mul dh
mov dh,0
dec dl
add dl,dl ;列偏移地址
add ax,dx ;行偏移地址加列偏移地址
mov bx,ax ;bx表示起始偏移地址
mov al,cl ;al表示颜色
mov ch,0 ;counter高位清0
s: mov cl,ds:[si] ;用cl检字符窜是否为0
jcxz return ;如果为0,程序转移到return
;不为0执行下列程序
mov es:[bx],cl ;字符ASCII码写入显存地址
mov es:[bx+1],al ;字符属性写入显存地址
inc si ;si定位字符窜ASCII偏移地址
add bx,2 ;bX定位写入显存的偏移地址
loop s ;循环
backup: push ax ;寄存器原始数据用栈备份
push bx ;backup为通用寄存器备份程序
push cx
push dx
push si
push di
push bp
add sp,14
ret
return: pop si ;相关寄存器数据还原
pop dx ;return为通用返回调用程序
pop cx
pop bx
pop ax
pop di
pop bp
add sp,2
ret ;返回调用程序
code ends
end start | | |