关于引导程序(我们这里特指PC架构的系统)网络上的介绍比较多了,实例也很多,正好前阵子在学习,现把我写的一个引导程序发布出来,权作为一个参考吧!
首先介绍一下我这段程序的功能:引导计算机启动,并在屏幕左上角显示当前系统时钟,采用"HH:MM:SS”
的格式显示,并且时钟颜色在黄色和红色间交替变化。
程序使用了以下几个BIOS中断调用,分别是10h号、1ah号、1ch号中断。其中10h中断是我们大家比较熟悉的BIOS显示中断,可以用来在标准输出设备上输出字符、字串、图形等信息;1ah中断则是获取当前系统时间的中断,也就是CMOS中记录的时间信息;1ch中断是系统时钟中断,PC架构的系统中,每55ms左右就会自动调用一次1ch中断,默认情况下,该中断不执行任何操作然后直接返回。为什么是55ms呢?这个我还真不清楚,反正PC的系统是这样定义的。换句话说,1s钟的时间里一共将执行18次1ch中断(1000/55≈18)。
程序体包括主程序(start)、时钟中断程序(intClock)、获取时钟子程序(GET_T)、数字转对应ASCII数字字符子程序(TTASC)四个部分。
以下是程序运行流程,计算机启动后便会将该段程序加载到0x7c00开始的一块内存中。如果加载成功,便会从0x7c00处开始执行。第一开始运行的当然是主程序了,主程序做的工作非常简单,仅仅是重新定义了BIOS的1ch中断,将其入口地址指向intClock,然后进入无限循环。在这个过程中,每隔55ms系统就会产生一次1ch中断,也就是说我们的intClock每55ms就被调用一次,每当intClock被调用时首先检查是否够1s钟了,判断依据是调用次数,满18次了则认为过了1s钟,于是intClock再调用GET_T子程序,获取当前系统时钟信息,并使用TTASC将数字转换为对应的ASCII码数字字符,最后调用10h中断将时间信息显示在输出设备上。然后这个过程周而复始直到天荒地老(关机)!:)
代码编译及运行方法。本程序使用NASM编译,编译以后得到一个文件直接就是720K的软盘镜像文件,可以直接放入虚拟机的虚拟的软驱中运行。编译方法如下:C:\>nasmw
-o clock.img clock.asm。
;=============clock.asm===============
Start: org
07c00h ;程序开始
mov ax,cs ;设置ds,es段寄存器
mov
ds,ax
mov es,ax
mov bx,1ch * 4
;1c号向量的入口地址=>bx
cli ;关闭中断
mov word
[bx],intClock ;新中断的偏移地址=>[bx]
mov word [bx+2],ax
;新中断的段地址=>[bx+2]
sti ;打开中断
End: jmp $
;无限循环
;======================================
intClock:
;新中断代码
cmp byte [cs:Count],0 ;判断是否到显示的时候(一秒钟显示一次)
jz
Next ;是,则转到Next执行显示代码
dec byte [cs:Count]
;否,则计数器减一
iret ;中断返回
Next:
mov byte
[cs:Count],18 ;重新设置计数器,并开始执行显示代码
push ax
;保存现场
push bp
push cx
push bx
push
dx
call GET_T
;调用子程序GET_T
mov bp,HHHH ;显示字串,字串首字节地址=>bp
mov cx,8
;字串长度=>cx
mov ax,01301h
;设定显示模式,13=>ah,01=>al
mov bh,0 ;显示页号=>bh
mov
bl,[cs:Color] ;显示属性=>bl
xor bl,2
;使显示属性在黄色和红色间交替变化
mov [cs:Color],bl ;保存属性值
mov dx,0
;在屏幕上显示字串的位置,行dh=0,列dl=0
int 10h ;调用 BIOS
10h号中断
pop dx ;恢复现场
pop bx
pop cx
pop
bp
pop ax
iret
;中断返回
;======================================
GET_T:
mov ah,2
;使用 Bios 1ah 号中断的 2 号功能
int 1ah ;调用 Bios 1ah
号中断
mov al,ch ;将小时数转化为可以显示的形式
CALL TTASC
;调用形式转化子程序 TTASC
xchg ah,al
mov [cs:HHHH],ax
;保存小时数,以下代码采用相同方法处理分数和秒数
mov al,cl
CALL TTASC
xchg ah,al
mov
[cs:MMMM],ax
mov al,dh
CALL TTASC
xchg ah,al
mov
[cs:SSSS],ax
ret ;子程序返回
TTASC:
mov ah,al
;该子程序将数值加30后转化为对应的ASCII码数字字符
and al,0fh
shr ah,4
add
ax,3030h
ret
;========================================
Count db 18
;定义计数器
Color db 0x0c
;定义显示颜色,0ch表示红色
HHHH db 0,0,':'
MMMM db 0,0,':'
SSSS db 0,0
times
510-($-$$) db 0 ;用0填充本扇区剩余内容,一扇区为512字节(默认情况下)
dw 0xaa55
;引导扇区末尾两字节必须为0xaa55
times 736768 db 0
;用0填充后续磁盘空间,使汇编后的文件大小为720K
;刚好是一张软盘的容量
欢迎转载本站文章,但请保留版权信息!
http://www.Bacysoft.cn如果您觉得本站资源对您有帮助,也请您支持本站发展,谢谢!
本站的发展,需要您的支持!