. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->CALL和RET指令
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  第十章 实验十 (3) 接口化实现 算是我至今最满意的程序了!  [待解决] 回复[ 1次 ]   点击[ 317次 ]  
zhenglxd
[帖 主]   [ 发表时间:2009-05-16 10:31 ]   [引用]   [回复]   [ top ] 
荣誉值: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
mess
[第1楼]   [ 回复时间:2009-05-17 17:41 ]   [引用]   [回复]   [ top ] 
荣誉值:337
信誉值:0
注册日期:2008-01-01 17:48
还不错,完成了课设一就更觉得满意了 ^_^
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved