终于完成了课件设计2了.... 虽然不是很好. 但是也贴上来与大家分享我的快乐
assume cs:code,ds:data,ss:stack
stack segment
db 256 dup (0)
stack ends
data segment
buffer db 1024 dup (0) ;经测试不需要0xaa55作为结尾也能引导
data ends
code segment
;名称 copy
;功能 将指定的数据复制到指定的地方
;参数 copy(源段地址,源段偏移,到段地址,到段偏移,复制字节数)
; 参数入栈形式 从右到左
copy proc
;*****************************************************************************
push bp
mov bp,sp
;*****************************************************************************
push ax
push cx
push si
push di
push ds
push es
;*******************************************************************************
mov cx,[bp+12] ;复制字节数
mov es,[bp+8] ;到段地址
mov di,[bp+10] ;到段偏移
mov ds,[bp+4] ;源段地址
mov si,[bp+6] ;源段偏移
;*******************************************************************************
copy_s2: mov al,[si]
mov es:[di],al
inc si
inc di
loop copy_s2
pop es
pop ds
pop di
pop si
pop cx
pop ax
mov sp,bp
pop bp
ret 10
copy endp
main proc
;********************************************************************************************
mov ax,offset main_do1end - offset main_do1
push ax
mov ax,offset buffer
push ax
mov ax,data ;将下面的代码复制到缓冲区中
push ax
mov ax,offset main_do1
push ax
push cs
call copy
;*******************************************************************************************
jmp main_next ;跳过下面的需要安装的代码
org 7c00h ;准备安装到7c00h,需要设置\
main_do1: xor ax,ax ;否则引导程序启动以后偏移量将不正确
mov ds,ax
push ds:[9*4] ;保存键盘中断
pop ds:[200h]
push ds:[9*4+2]
pop ds:[202h]
;*******************************************************************************************
mov ah,2
mov al,2
xor ch,ch
mov cl,2
xor dh,dh ;读取2和3扇区的数据到内存7e00h
xor dl,dl ;因为7c00+512字节等于7e00h
xor bx,bx
mov es,bx
mov bx,7e00h
int 13h
;*******************************************************************************************
db 0eah
db 00h
db 7eh ;跳转到7e00h
db 00h ;这句等于jmp 0000:7e00h
db 00h
;*******************************************************************************************
main_do1end: nop
;*****************************************************************************************
main_next: mov ah,3
mov al,1
xor cx,cx
inc cl
xor dx,dx ;将缓冲区中的数据复制到\
mov bx,data ;0面0道1扇区中
mov es,bx
xor bx,bx
int 13h
;*******************************************************************************************
mov ax,offset main_do0end - offset main_do0
push ax
mov ax,offset buffer
push ax
mov ax,data
push ax
mov ax,offset main_do0 ;将下面的数据复制到缓冲区
push ax
push cs
call copy
jmp main_next1
;******************************************************************************************
org 7E00h
;******************************************************************************************
main_do0: cli
mov word ptr ds:[9*4],offset head9start
mov word ptr ds:[9*4+2],0 ;修改键盘中断
sti
xor ax,ax
mov ds,ax
mov es,ax
mov ss,ax
mov sp,0ffffh
call cls ;清屏
call interphase ;显示菜单
xor ax,ax
push ax
call choice ;激活菜单
db 0eah
db 00h
db 7eh
db 00h
db 00h
;名称 head9.asm
;功能 进行9号中断拦截
;参数 无
;返回 无
head9 proc
head9start: push ax
push bx
push cx
push es
;*****************************************************************************************
in al,60h
pushf
call dword ptr cs:[200h] ;调用原来的9号中断,完成硬件细节
;******************************************************************************************
cmp al,3bh
jne head9_esc
;******************************************************************************************
mov ax,0b800h
mov es,ax
mov bx,1
mov cx,2000 ;如果是f1的话
head9_f1: inc byte ptr es:[bx]
add bx,2
loop head9_f1
jmp head9_end
;*******************************************************************************************
head9_esc: cmp al,01
jne head9_end ;都不是则返回
head_esc_y: mov cx,15
xor ah,ah
int 16h
cmp ah,1
je head_q
loop head_esc_y
head_q: db 0eah
db 00h
db 7eh ;如果为ESC的话
db 00h
db 00h
;*******************************************************************************************
head9_end: pop es
pop cx
pop bx
pop ax
iret
head9 endp
;名称 cls
;功能 清屏
cls proc
push bx
push cx
push es
;*****************************************************************************
mov bx,0b800h
mov es,bx
xor bx,bx
mov cx,2000
cls_s: mov byte ptr es:[bx],' '
inc bx
mov byte ptr es:[bx],7
inc bx
loop cls_s
;******************************************************************************
pop es
pop cx
pop bx
ret
cls endp
;名称 interphase ;界面
;功能 显示界面
;参数 无
;返回 无
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
interphase proc
push ax
push bx
push cx
push dx
jmp short interphase_start
interphase_menu db '1) reset pc ' ;重新启动计算机
db '2) start system ' ;引导现有操作系统
db '3) clock ' ;进入时钟程序
db '4) set clock ' ;设置时间
;*******************************************************************************************
interphase_start: xor bx,bx
xor ah,ah
mov dh,10 ;设置光标
mov dl,35
call cursor
;******************************************************************************************
mov cx,4
interphase_while: push cx
;******************************************************************************************
mov cx,16
interphase_while1: mov ah,7
mov al,interphase_menu[bx]
call show_char
inc bx
xor ah,ah
inc dl ;显示菜单
call cursor
loop interphase_while1
inc dh
mov dl,35
xor ah,ah
call cursor
pop cx
loop interphase_while
;******************************************************************************************
pop dx
pop cx
pop bx
pop ax
ret
interphase endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;名称 show_char
;功能 在当前光标处按指定的颜色显示指定的字符
;参数 ah=颜色
; al=字符
show_char proc
push ax
push bx
push cx
mov bl,ah
xor bh,bh ;在当前光标处按指定的颜色显示指定的字符
mov cx,1
mov ah,09
int 10h
pop cx
pop bx
pop ax
ret
show_char endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;名称 cursor
;功能 在当前光标下,使光标增加或设置到指定行和列
;参数 ah=0(设置光标位置)
; ah=1(增加光标位置)
; dh=增加或设置的行数
; dl=增加或设置的列数
;返回 无
cursor proc
push bp
push ax
push bx
push cx
push dx
;******************************************************************************************
cmp ah,1
je cursor_1
xor bh,bh
mov ah,2
int 10h
jmp short cursor_end
;*******************************************************************************************
cursor_1: push dx
xor bh,bh
mov ah,3
int 10h ;获取光标信息
mov bp,sp
add [bp],dx
pop dx
;*******************************************************************************************
mov ah,02 ;设置光标
int 10h
;*******************************************************************************************
cursor_end: pop dx
pop cx
pop bx
pop ax
pop bp
ret
cursor endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;名称 activation
;功能 给指定菜单上色
;参数 al=指定菜单
; ah=颜色
activation proc
push ax
push bx
push cx
push dx
;*******************************************************************************************
and al,00000011b
mov bl,ah
xor ah,ah ;设置指向选定的菜单
mov dh,10
mov dl,35
add dh,al
call cursor
;*******************************************************************************************
mov cx,16
activation_s: mov al,bl ;上色
call alter
xor ah,ah
inc dl
call cursor
loop activation_s
;*****************************************************************************************
pop dx
pop cx
pop bx
pop ax
ret
activation endp
;名称 alter
;功能 改变当前光标下字符的颜色
;参数 al=需要改变的颜色(0~255)
;返回 无
alter proc
push ax
push bx
push cx
;************************************************************************************
push ax
xor bh,bh
mov ah,08h
int 10h
;改变当前的颜色
pop bx
xor bh,bh
mov cx,1
mov ah,9
int 10h
;**************************************************************************************
pop cx
pop bx
pop ax
ret
alter endp
;名称 startsystem
;功能 引导现有的操作系统
;参数 无
;返回 无
startsystem proc
xor ax,ax
mov ds,ax
;*******************************************************************************************
mov ah,2
mov al,1
xor ch,ch
mov cl,1
xor dh,dh ;读取c盘0道0面1扇区到内存7c00h
mov dl,80h
xor bx,bx
mov es,bx
mov bx,7c00h
int 13h
;*******************************************************************************************
db 0eah
db 00h
db 7ch ;跳转
db 00h
db 00h
;*******************************************************************************************
startsystem endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;名称 runcode
;功能 执行用户选择的代码
;参数 al=选择的功能号
;返回 无
runcode proc
push ax
push bx
and al,00000011b
;*******************************************************************************************
cmp al,2
jne runcode_start
call cls
mov ah,2
xor bh,bh
mov dx,2500h ;选择了时间程序的话循环读取时间
int 10h
runcode_ss: call clock
jmp short runcode_ss
;******************************************************************************************
runcode_tab dw resetpc,startsystem,clock,setclock
runcode_start: xor bx,bx
mov bl,al
add bx,bx
cmp bx,6 ;选择了设置时间的话不恢复9号中断
je runcode_s
push cs:[200h]
pop cs:[9*4]
push cs:[202h] ;恢复9号中断
pop cs:[9*4+2]
runcode_s: call runcode_tab[bx]
;*****************************************************************************************
pop bx
pop ax
ret
runcode endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;名称 choice
;功能 提供给用户选择菜单
;参数 (bp+4)=当前的激活菜单
;返回 无
choice proc
push bp
mov bp,sp
push ax
;*****************************************************************************************
mov al,[bp+4]
mov ah,4 ;激活菜单
call activation
;*****************************************************************************************
choice_while: xor ah,ah
int 16h
;*****************************************************************************************
cmp al,20h
jb choice_nochar
dec al
cmp al,'3'
ja choice_while
cmp al,'0'
jb choice_while ;判断用户的选择调用相应的程序
sub al,30h
and al,00000011b
mov [bp+4],al
jmp short choice_ok
;******************************************************************************************
choice_nochar: cmp ah,48h
je short choice_up
cmp ah,50h
je short choice_below ;判断非数字的情况
cmp ah,1ch
je short choice_ok
jmp short choice_while
;*****************************************************************************************
choice_up: mov al,[bp+4]
mov ah,7 ;清空所在行的颜色
call activation
;****************************************************************************************
dec byte ptr [bp+4]
mov al,[bp+4]
mov ah,4 ;调整到上一行,上色
call activation
jmp short choice_while
;*****************************************************************************************
choice_below: mov al,[bp+4]
mov ah,7 ;清空当前所在行
call activation
;****************************************************************************************
inc byte ptr [bp+4]
mov al,[bp+4]
mov ah,4 ;调成到下一行
call activation
jmp short choice_while
;******************************************************************************************
choice_ok: mov al,[bp+4]
call runcode
;********************************************************************************************
pop ax
pop bp
ret 2
choice endp
;名称 resetpc
;功能 作为引导程序重新启动计算机
;参数 无
;返回 无
resetpc proc
resetpc_table db 0eah
db 00h
db 00h ;重启计算机
db 0ffh
db 0ffh
resetpc endp
;名称 setclock
;功能 修改时间
;参数 无
;返回 无
setclock proc
push bp
sub sp,6
mov bp,sp
push ax
push bx
push cx
push si
push es
;********************************************************************************************
mov byte ptr [bp+5],0
mov byte ptr [bp+4],2
mov byte ptr [bp+3],4
mov byte ptr [bp+2],7 ;时间在COMS中的相应位置
mov byte ptr [bp+1],8
mov byte ptr [bp+0],9
;********************************************************************************************
xor si,si
mov bx,0b800h
mov es,bx
mov bx,160*24+2*63
;******************************************************************************************
setclock_while: mov byte ptr es:[bx+1],01000111b
mov byte ptr es:[bx+3],01000111b ;调用时间显示子程序
call clock
;******************************************************************************************
xor ah,ah
int 16h
cmp al,20h
jb setclock_nochar
mov es:[bx+0],al
mov ch,al
xor ah,ah
int 16h
cmp al,20h
jb setclock_nochar
mov es:[bx+2],al
sub ch,30h ;修改时间
sub al,30h
mov cl,4
shl ch,cl
or ch,al
mov al,[bp+si]
out 70h,al
mov al,ch
out 71h,al
jmp setclock_right
;*****************************************************************************************
setclock_nochar:cmp ah,0eh
je setclock_back
cmp ah,1ch
je setclock_enter
cmp ah,4bh ;非数字的情况
je setclock_left
cmp ah,4dh
je setclock_right
jmp setclock_while
;***************************************************************************************
setclock_end: pop es
pop si
pop cx
pop bx
pop ax
add sp,6
pop bp
ret
setclock_back: mov byte ptr [bx+0],' '
mov byte ptr [bx+2],' ' ;退格
jmp setclock_while
setclock_enter: jmp short setclock_end ;回车
;*******************************************************************************************
setclock_left: mov byte ptr es:[bx+1],7
mov byte ptr es:[bx+3],7
sub bx,6
dec si
cmp bx,160*24+63*2
jnb setclock_while ;左
mov bx,160*24+78*2
mov si,6
jmp setclock_while
;*******************************************************************************************
setclock_right: mov byte ptr es:[bx+1],7
mov byte ptr es:[bx+3],7
add bx,6
inc si
cmp bx,160*24+78*2
jna setclock_1
mov bx,160*24+63*2 ;右
xor si,si
setclock_1: jmp setclock_while
;******************************************************************************************
setclock endp
;名称 clock
;功能 时钟显示引导
;参数 无
;返回 无
clock proc
push bp
sub sp,6
mov bp,sp
push ax
push bx
push cx
push si
push es
;********************************************************************************************
mov byte ptr [bp+5],9
mov byte ptr [bp+4],8
mov byte ptr [bp+3],7
mov byte ptr [bp+2],4 ;COMS中对应的时间数据口
mov byte ptr [bp+1],2
mov byte ptr [bp+0],0
;********************************************************************************************
mov bx,0b800h
mov es,bx
mov bx,24*160+2*63
mov si,6
;*******************************************************************************************
clock_while: mov cx,si
push cx
dec si
mov al,[bp+si]
out 70h,al
in al,71h
mov ah,al ;读取时间
mov cl,4
shr ah,cl
and al,00001111b
;******************************************************************************************
add ah,30h
add al,30h
mov es:[bx+0],ah
mov es:[bx+2],al
add bx,6 ;显示时间
pop cx
loop clock_while
;******************************************************************************************
sub bx,6*6
mov byte ptr es:[bx+4],'-'
mov byte ptr es:[bx+10],'-'
mov byte ptr es:[bx+16],' ' ;打印格式
mov byte ptr es:[bx+22],':'
mov byte ptr es:[bx+28],':'
;******************************************************************************************
pop es
pop si
pop cx
pop bx
pop ax
add sp,6
pop bp
ret
clock endp
;引导程序
main_do0end: nop
main_next1: mov ah,3
mov al,2
xor cx,cx
add cl,2
xor dx,dx
mov bx,data
mov es,bx
xor bx,bx
int 13h
ret
main endp
start: mov ax,stack
mov ss,ax
mov sp,256
mov ax,data
mov ds,ax
call main
mov ax,4c00h
int 21h
code ends
end start
- [zd3870262] 有朋友和我说不知道怎么运行,这里附上运行的过程. 大家可以直接复制源码编译.....启动虚拟机后 11/19 07:00
- [yuzhong] 空白一片 104空间 http://104kj.net.cn/ 10/23 00:40