课程设计2
阅读下面的材料:
开机后,CPU自动进入到FFFF:0单元处执行,此处有一条跳转指令。CPU执行该指令后,转去执行BIOS中的硬件系统检测和初始化程序。
初始化程序将建立BIOS所支持的中断向量,即将BIOS提供的中断例程的入口地址登记在中断向量表中。
硬件系统检测和初始化完成后,调用int 19h进行操作系统的引导。
如果设为从软盘启动操作系统,则int 19h将主要完成以下工作。
(1)控制0号软驱,读取软盘0道0面1扇区的内容到0:7c00;
(2)将CS:IP指向0:7c00。
软盘的0道0面1扇区中装有操作系统引导程序。int 19h将其装到0:7c00处后,设置CPU从0:7c00开始执行此处的引导程序,操作系统被激活,控制计算机。
如果在0号软驱中没有软盘,或发生软盘I/O错误,则int 19h将主要完成以下工作。
(1)读取硬盘C的0道0面1扇区的内容到0:7c00;
(2)将CS:IP指向0:7c00。
这次课程设计的任务是编写一个可以自行启动的计算机,不需要在现有操作系统环境中运行的程序。
该程序的功能如下:
(1)列出功能选项,让用户通过键盘进行选择,界面如下
1) reset pc ;重新启动计算机
2) start system ;引导现有的操作系统
3) clock ;进入时钟程序
4) set clock ;设置时间
(2)用户输入"1"后重新启动计算机(提示:考虑ffff:0单元)
(3)用户输入"2"后引导现有的操作系统(提示:考虑硬盘C的0道0面1扇区)。
(4)用户输入"3"后,执行动态显示当前日期、时间的程序。
显示格式如下:年/月/日 时:分:秒
进入此项功能后,一直动态显示当前的时间,在屏幕上将出现时间按秒变化的效果(提示: 循环读取CMOS)。
当按下F1键后,改变显示颜色;按下Esc键后,返回到主选单(提示:利用键盘中断)。
(5)用户输入"4"后可更改当前的日期、时间,更改后返回到主选单(提示:输入字符串)。
assume cs:code
code segment
org 7c00h
begin:mov ax,32 ;将二、三扇区内容写入内存
mov es,ax
mov bx,7c00h
mov al,2
mov ch,0
mov cl,2
mov dx,0
mov ah,2
int 13H
menu:jmp smenu
;存放各种数据
view: db '1.reset pc ' ;显示菜单用
db '2.start system '
db '3.clock '
db '4.set clock '
dat: db 9,8,7,4,2,0 ;显示时间用
tt: db 'yy/mm/dd hh:mm:ss',0
strstack:db 32 dup (0) ;字符栈
table dw charpush,charpop,charshow ;读键盘缓冲区用到
top dw 0 ;栈顶
smenu:call clsr ;显示菜单程序
mov ax,0b800h
mov es,ax
mov di,160*4+12*2
mov ax,cs
mov ds,ax
mov si,offset view
mov cx,4
s:push cx
mov cx,16
s1:mov al,[si]
mov es:[di],al
inc si
add di,2
loop s1
add di,128
pop cx
loop s
jmp key_in ;显示菜单后跳转到监听键盘输入
;-----------清屏子程序clsr------------
clsr: push cx
push ax
push si
mov ax,0b800h
mov es,ax
mov si,0
mov cx,2000
clslp:mov byte ptr es:[si],' '
add si,2
loop clslp
pop si
pop ax
pop cx
ret
;-----------ASCII转BCD码子程序,并将日期写入BIOS-------
c_bcd: push bx
push di
push ax
mov bx,offset strstack ;bx指向字符栈
mov di,offset dat
mov cx,6
s2:push cx
mov ax,[bx]
sub ah,30h
sub al,30h
mov cl,4
shl al,cl
or ah,al
mov al,[di]
out 70h,al
mov al,ah
out 71h,al
add di,1
ckl: add bx,3
pop cx
loop s2
pop ax
pop di
pop bx
ret
;-------显示时钟程序-----------------
clock: call clsr
mov bx,4
clockstart:
mov si,offset dat
mov di,offset tt
mov cx,6
clp:push cx
mov al,[si]
out 70h,al
in al,71h
mov ah,al ;BCD码转换ASCII码
mov cl,4
shr ah,cl
and al,00001111b
add ah,30h
add al,30h
mov [di],ah
mov [di+1],al
inc si
add di,3
pop cx
loop clp
in al,60h ;判断是否有Esc和F1键输入
cmp al,01
je inst ;有Esc键输入刚返回菜单
cmp al,3bh
jne nccolor
inc bl ;改变颜色
and bl,10001111b
nccolor: mov ax,0b800h
mov es,ax
mov di,160*12+34*2
mov si,offset tt
mov ax,cs
mov ds,ax
slp:mov al,[si]
cmp al,0
je clockstart
mov es:[di],al
mov es:[di+1],bl
inc si
add di,2
jmp slp
inst:jmp menu
;-------用于设置时钟程序及相应子程序,和书上差不多---------
;-------ah=功能号,0表示入栈,1出栈,2显示(dh=行,dl=列),DS:SI指向字符栈
charstack: push bx
push dx
push di
push es
mov si,offset strstack
cmp ah,2
ja tosret
mov bl,ah
mov bh,0
add bx,bx
jmp word ptr table[bx]
tosret:jmp sret
charpush: cmp top,17 ;设置字符串长度,不能大于17
je tosret
mov bx,2 ;使输入跳格
mov cx,5
c_mp:cmp top,bx
je n_x
add bx,3
loop c_mp
mov bx,top
mov [si][bx],al
inc top
jmp sret
n_x:mov bx,top
mov byte ptr [si][bx],' '
inc top
mov bx,top
mov byte ptr [si][bx],al
inc top
jmp sret
charpop: cmp top,0
je sret
dec top
mov bx,top
mov al,[si][bx]
jmp sret
charshow: mov bx,0b800h ;显示字符栈内容
mov es,bx
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,top
jne noempty
mov byte ptr es:[di],' '
jmp sret
noempty: mov al,[si][bx]
mov es:[di],al
mov byte ptr es:[di+2],' '
inc bx
add di,2
jmp charshows
sret: pop es
pop di
pop dx
pop bx
ret
;---------设置时钟程序入口,接收字符串输入的子程序--
setclock:call clsr
mov ax,0b800h
mov es,ax
mov bx,160*12+32*2
mov di,offset tt
sst:mov al,[di]
cmp al,0
je getstrs
mov es:[bx],al
mov byte ptr es:[bx+1],2
inc di
add bx,2
jmp sst
getstrs: mov ah,0
int 16h
cmp al,30h
jb nochar
cmp al,39h
ja nochar
mov ah,0
call charstack
mov dh,13
mov dl,32
mov ah,2
call charstack
jmp getstrs
nochar: cmp ah,0eh
je backspace
cmp ah,1ch
je enter
jmp getstrs
backspace: mov ah,1 ;按backspace的相应操作
call charstack
mov ah,2
call charstack
jmp getstrs
enter: mov al,0 ;按enter键后的相应操作
mov ah,0
call charstack
call c_bcd
jmp menu
;----------------------------
resetpc:mov ax,0ffffh ;重启PC程序
push ax
mov ax,0
push ax
retf
startsys:mov bx,0 ;启动现有操作系统
mov es,bx
mov bx,7c00h
mov al,1
mov dh,0
mov ch,0
mov cl,1
mov dl,80h
mov ah,2
int 13h
mov ax,0
push ax
mov ax,7c00h
push ax
retf
;监听菜单键盘输入,不能用int 16h,因为在进入key_in之前,键盘缓冲区可能有数据
key_in: in al,60h
;mov ah,0
;int 16h
cmp al,2
je resetpc
cmp al,3
je startsys
cmp al,4
je starttem
cmp al,5
je setcl
jmp key_in
starttem:jmp clock
setcl:jmp setclock
;----------------------------
start:mov ax,cs ;将程序写入软盘,共3个扇区,
mov es,ax
mov bx,7c00h
mov al,3
mov ch,0
mov cl,1
mov dl,0
mov dh,0
mov ah,3
int 13h
mov ax,4c00h
int 21h
code ends
end start
- [游客] 飘过 06/11 13:31
- [fpamc] 貌似我正在步入你的路线……`(*∩_∩*)′Up!Up! 05/24 07:46
- [782936509] 敢问高手你是什么基础开始学的,我没有基础想学编程可以的吗?很想成为一个编程员,希望多多指教,呵呵 12/24 19:26
- [aten] 上面的程序我忘记设置要写入的扇区数了,……-_-~! 08/07 15:50
- [keyia] 啊,如梦初醒!万分感谢 05/28 01:32
- [aten] 好久没来汇编网了,拿你调试的结果来说吧! F:\dosimg\>debug c0s.exe - 05/26 22:52
- [keyia] keyia:变成游客了 05/22 19:42
- [游客] 向您请教: (8)从上我们可以看出tc.exe把c0s.obj和用户obj文件一同进行连接,生成e 05/22 19:40
- [aten] dw 定义的应该是10个字单元,我写成了8个了!所以答案就成了20H 04/26 22:01
- [aten] 恩,^_^ 04/24 18:36
- [游客] 这个,你的那个安装INT9中断程序的程序有一点错误,以下这个是我改正后的: assume cs:c 10/08 07:28
- [游客] 没想到我想走的路和正在走的路你已经走过一遍了,可以的话请加865650570——凌陶 愿我们在同一 10/07 23:30
- [keyia] 向您请教: (8)从上我们可以看出tc.exe把c0s.obj和用户obj文件一同进行连接,生成 05/22 19:44