王爽《汇编语言》(第3版)课程设计2上篇

主体程序的基本样式,3、4功能可以运行显示相应结果
1、2功能并不是最终形式,不要运行,以免出现意外的情况
程序较为复杂,篇幅较长,源码请耐心阅读仔细分析

初步源程序

 ;autoact安装程序
 ;autoact程序可以自行启动计算机
 ;功能:(1)列出功能选项,让用户通过键盘进行选择,界面如下。
  ; 1) reset pc
  ; 2) start system
  ; 3) clock
  ; 4) set clock
 ;(2)用户输入“1”后重新启动计算机
 ;(3)用户输入“2”后引导现有的操作系统
 ;(4)用户输入“3”后,执行动态显示当前日期、时间的程序
 ; 显示格式:年/月/日 时:分:秒
 ; 一直动态显示当前的时间,在屏幕上将出现时间按秒变化的效果
 ; 当按下F1键后,改变显示颜色;按下Esc键后,返回到主菜单
 ;(5)用户输入“4”后可更改当前的日期、时间,更改后返回到主菜单
 ;
 ;
assume cs:code
code segment
;
 ;目标程序
 ;名称:autoact
 ;
autoact:jmp autostart
 table dd 0ffff0000h,7c00h
 subtab dw sub1,sub2,sub3,sub4   ;功能程序入口地址
 str db '1) reset pc',0,'2) start system',0,'3) clock',0,'4) set clock',0
 mastack dw 32 dup (0)    ;定义栈空间
;
 ;界面
autostart: mov ax,cs
 mov ss,ax   ;设置栈空间
 mov sp,offset mastack + 64
;
 mov ax,0b800h
 mov ds,ax
 call clrscr
;
 mov cx,4
 mov bx,0
 mov si,0
interface:push cx
 mov di,0
 mov ch,0
;
row:mov cl,str[si]    ;显示行
 inc si
 jcxz rowend
 mov [bx + di],cl
 add di,2
 jmp row
;
rowend:add bx,160
 pop cx
 loop interface
;
input: mov ah,0
 int 16h
 cmp al,'1'
 jb input
 cmp al,'4'
 ja input    ;输入不在1~4的范围返回重新输入
; 
 mov ah,0
 sub ax,'1'
 mov bx,ax
 shl bx,1    ;根据用户输入计算功能程序入口地址在subtab表中的偏移
 call word ptr subtab[bx]
 jmp autostart   ;返回初始化界面
;
;清屏
 ;参数:需要初始化(ds)=b800h
clrscr: push cx
 push di
 mov di,0
 mov cx,2000
clears:mov byte ptr [di],' '  ;清空屏幕
 mov byte ptr [di + 1],07h  ;还原颜色属性
 add di,2
 loop clears
 pop di
 pop cx
 ret
;
;重启计算机
sub1:
 call clrscr  ;清屏
 call dword ptr table[0]
;
;引导操作系统
sub2:
 call clrscr  ;清屏
 mov ax,0
 mov es,ax
 mov bx,7c00h ;设置es:bx指向接收从扇区读入数据的内存区
;
 mov al,1
 mov ch,0
 mov cl,1
 mov dl,80h ;硬盘C驱动器号
 mov dh,0
 mov ah,2
 int 13h
 call dword ptr table[4]
;
;动态显示当前日期、时间
sub3:
 push ax
 push bx
 push cx
 push dx
 push si
 push di
;
 call clrscr  ;清屏
 ;日期补全
 mov byte ptr ds:[160*12+30*2],'2'
 mov byte ptr ds:[160*12+31*2],'0'
;
 mov si,32*2 ;设置显存
 mov dl,9  ;初始访问单元
 mov dh,'/' ;日期分隔符
 mov bl,1  ;设置访问单元增量,日期部分为1,时间部分为2
 call datetime
;
 ;时间部分的处理
 mov byte ptr [160*12+si-2],' '
 mov byte ptr [160*12+si],' ' ;日期和时间分隔
 add si,2
 mov bl,2
time: push si
 mov dl,4
 mov dh,':'  ;时间分隔符
;
 call datetime
 mov byte ptr [160*12+si-2],' '
 pop si
 mov bh,al
;
update: mov ah,0ch
 int 21h   ;作用是清除键盘缓冲区
 in al,60h
 cmp al,3bh
 je color    ;按F1键改变显示颜色
 cmp al,01h
 je return3  ;按下Esc键返回主菜单
;
 mov al,0
 out 70h,al
 in al,71h
 and al,00001111b ;取秒的个位数
 add al,30h
 cmp al,bh
 je update    ;刷新时间
 jmp time    ;直接显示刷新时间
;
color:mov di,1
 mov cx,2000
loopc:inc byte ptr [di]
 add di,2
 loop loopc
 jmp update    ;刷新时间
;
return3: pop di
 pop si
 pop dx
 pop cx
 pop bx
 pop ax
 ret
;
 ;日期时间处理子程序
 ;参数:(dl)=入口单元,(dh)=分隔符,(bl)=地址变量
 ;ds:si指向显示地址
 ;返回:(si)=处理后指向的位置,(al)=末位有效数字
 ;
datetime: push cx
 push dx
 mov cx,3 
;
loopdt: push cx
 mov al,dl
 out 70h,al
 in al,71h  ;取访问单元中的数据
;
 mov ah,al
 mov cl,4
 shr ah,cl  ;ah为十位数码值
 and al,00001111b ;al为个位数码值
 add ah,30h
 add al,30h ;得到ASCII码
;
 mov byte ptr [160*12+si],ah
 mov byte ptr [160*12+si+2],al
 mov byte ptr [160*12+si+4],dh
;
 add si,6
 sub dl,bl
 pop cx
 loop loopdt
;
 pop dx
 pop cx
 ret
;
;更改当前的日期、时间
sub4:
 push ax
 push dx
 push es
 push si
 push bp
 call clrscr     ;清屏
 mov byte ptr ds:[0],'2'
 mov byte ptr ds:[2],'0'  ;初始化日期、时间显示
;
 jmp start4
 stringsk db 18 dup (0)  ;定义字符串存储空间——字符栈
 dw 0      ;预留空间
start4: mov dx,2h  ;显示位置为0行2列
  mov ax,cs
  mov es,ax
  mov si,offset stringsk  ;设置es:si指向字符栈
  mov bp,0     ;设置栈顶
 call getstr 
;
;修改日期、时间
 mov bp,0
 mov dl,9
 mov bl,1
 call writedt
;
 mov dl,4
 mov bl,2
 call writedt
;
 pop bp
 pop si
 pop es
 pop dx
 pop ax
 ret
;
 ;修改CMOS单元的子程序
 ;参数:(dl)=入口单元,(bl)=地址变量
 ;es:bp指向写入的字符串
 ;返回:(bp)=末尾位置
writedt: push ax
 push cx
;
 mov cx,3
loopwdt: push cx
 mov ah,es:[si][bp]
 sub ah,30h
 mov cl,4
 shl ah,cl
 sub byte ptr es:[si][bp + 1],30h
 or ah,es:[si][bp + 1]
;
 mov al,dl
 out 70h,al
 mov al,ah
 out 71h,al
 add bp,3
 sub dl,bl
 pop cx
 loop loopwdt
;
 pop cx
 pop ax
 ret
;
;完整的接收字符串输入的子程序
getstr: push ax 
;
getstrs:mov ah,0
 int 16h
; 
 cmp al,30h
 jb nonumber     ;判断的是ASCII码小于30h,说明不是数字
 cmp al,39h
 ja nonumber     ;判断的是ASCII码大于39h,说明不是数字
 mov ah,0
 call charstack  ;字符入栈
 mov ah,2
 call charstack  ;显示栈中的字符
 jmp getstrs
;
;
nonumber: cmp ah,0eh  ;退格键的扫描码
 je backspace
 cmp ah,1ch   ;回车键的扫描码
 je enter
 jmp getstrs
; 
; 
backspace: ;退格
 mov ah,1 
 call charstack  ;字符出栈
 mov ah,2
 call charstack  ;显示栈中的字符
 jmp getstrs
;
enter:  ;回车
 mov al,' '
 mov ah,0
 call charstack   ;0入栈
 mov ah,2
 call charstack  ;显示栈中的字符
;
 pop ax
 ret ;getstr ends
;
;
;字符串功能子程序实现
charstack:jmp short charstart
 ;
 strtable dw charpush,charpop,charshow
 ;
charstart:  push cx
 push bx
 push dx
 push di
; 
 cmp ah,2
 ja overflow
 mov bl,ah
 mov bh,0
 add bx,bx
 jmp word ptr strtable[bx]
;
overflow: jmp sret  ;值超出返回
charpush:cmp bp,18
 je overflow   ;栈满不再入栈
 mov es:[si][bp],al
 inc bp
;
 mov cl,'/'
 ;字符栈2、5单元判断
 cmp bp,2
 je sform
 cmp bp,5
 je sform
;
 mov cl,' '
 ;字符栈8、17单元判断
 cmp bp,8
 je sform
 cmp bp,17
 je sform
;
 mov cl,':'
 ;字符栈11、14单元判断
 cmp bp,11
 je sform
 cmp bp,14
 je sform
 ;直接返回
 jmp sret
;
   ;格式符显示
sform: mov ah,2
 call charstack   ;显示字符
 mov es:[si][bp],cl
 inc bp
 jmp sret
;
charpop:cmp bp,0
 je sret
 dec bp
;
 cmp bp,2
 je cform
 cmp bp,5
 je cform
 cmp bp,8
 je cform
 cmp bp,11
 je cform
 cmp bp,14
 je cform
;
rcform: mov al,es:[si][bp] 
 jmp sret
;
 ;格式符清除
cform: mov ah,2
 call charstack   ;显示字符
 dec bp
 jmp rcform    ;返回
;
charshow: mov al,160
 mov ah,0 
 mul dh
 mov di,ax
 add dl,dl
 mov dh,0
 add di,dx
;
 mov bx,0
;
charshows:cmp bx,bp
 jne noempty
 mov byte ptr [di],' ' 
 jmp sret
;
noempty:mov al,es:[si][bx]
 mov [di],al
 mov byte ptr [di+2],' '
 inc bx
 add di,2
 jmp charshows
;
sret: pop di
 pop dx
 pop bx
 pop cx
 ret
;
autoactend:nop
 mov ax,4c00h
 int 21h
code ends
end autoact

运行结果

在这里插入图片描述
3号功能
在这里插入图片描述
4号功能
在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
阅读下面的材料 : 开机后, CPU 自动进入到 FFF0:0 单元处执行,此处有一条跳转指令。 CPU 执行该指令后,转去执行 BIOS 中的硬件系统检测和初始化程序。 初始化程序将建立 BIOS 所支持的中断向量,即将 BIOS 提供的中断历程的入口地址登记在中断向量表中。 硬件系统检测和初始化完成后,调用 INT 19H 进行操作系统的引导。 如果设为从软盘启动操作系统,则 INT 19H 将主要完成一下工作: ( 1 )控制 0 号软驱,读取软盘 0 道 0 面 1 扇区的内容到 0 : 7C 00 。 ( 2 )将 CS:IP 指向 0 : 7C 00 。 软盘的 0 道 0 面 1 扇区中装有操作系统引导程序。 INT 19H 将其装到 0 : 7C 00 处后,设置 CPU 从 0 : 7C 00 开始执行此处的引导程序,操作系统被激活,控制计算机。 如果在 0 号软驱中没有软盘,或发生软盘 I/O 错误,则 INT 19H 将主要完成以下工作 ; (1) 读取硬盘 C 的 0 道 0 面 1 扇区的内容到 0 : 7C 00 ; (2) 将 CS:IP 指向 0 : 7C 00 。 这次课程设计的任务是编写一个可以自行启动计算机,不需要在现有操作系统环境中运行的程序。 改程序的功能如下: ( 1 )列出功能选项,让用户通过键盘进行选择,界面如下: 1 ) reset pc ; 重新启动计算机 2 ) Start system ; 引导现有的操作系统 3 ) Clock ; 进入时钟程序 4 ) Srt clock ; 设置时间 ( 2 )用户输入“ 1 ”后重新启动计算机。(提示:考虑 FFFF:0 ) ( 3 )用户输入“ 2 ” 后引导现有的操作系统。(提示:考虑硬盘 C 的 0 道 0 面 1 扇区) ( 4 )用户输入“ 3 ”后,执行动态现实当前日期,时间的程序。 现实格式如下:年 / 月 / 日 时:分:秒 进入此项功能后,一直动态现实当前的时间,在屏幕上将出现时间按秒变化的效果。(提示:循环读取 CMOS ) 当按下 F1 键后,改变现实颜色;按下 ESC 键后,返回到主选单。(提示:利用键盘中断) ( 5 )用户输入“ 4 ”后可更改当前的日期,时间,更改后返回到主选单。(提示:输入字符串) 下面给出的几点建议: ( 1 )在 DOS 下编写安装程序,在按转程序中包含任务程序; ( 2 )运行安装程序,将任务程序写到软盘上; ( 3 )若要任务程序可以在开机后自行执行,要将它写到软盘的 0 道 0 面 1 扇区上。如果程序长度大于 512B ,则需要用多个扇区存放,这种情况下,处于软盘 0 道 0 面 1 扇区中的程序就必须负责将其他扇区中的内容读入内存。 这个程序较为复杂,它用到了我们所学到的所有技术,需要进行仔细地分析和耐心地调试。这个程序对于我们的整个学习过程是具有总结性的,希望读者能够尽力完成。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值