- [h2o] 在子程序dtoc2中调用了divdw了 11/23 11:09
- [752495796] 你编写的子程序divdw 在主程序中都没有调用 是不是应该要在算人均的时候调用一下呢? 11/17 17:17
- [hky987654321] 祝贺毕业! 08/11 10:45
- [cutebe] 哇,恭喜完成课程设计二 ^_^ 08/10 15:56
- [h2o] 做课程设计2时有显示日期时间的功能,又写了一遍,不仅增加了动态显示时间而且添加了q键退出功能 - 08/08 18:41
- [h2o] 感觉写得复杂了,改天重写一遍 07/27 22:05
- [hky987654321] 自我纠正:mov cx,40h 是对的。 07/27 09:46
- [hky987654321] 第二题 assume cs:code code segment mov 07/26 21:05
[2013-08-10 13:17] 课程设计2
-------------------------------
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;任务:编写一个可以自行启动计算机,不需要在现有操作系统环境中运行的程序
;功能:1)重新启动计算机
; 2)引导现有的操作系统
; 3)进入时钟程序
; 4)设置时间
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
assume cs:code
code segment
setsystem:
jmp set_init
menu_str_1 db '1) reset pc',0
menu_str_2 db '2) start system',0
menu_str_3 db '3) clock',0
menu_str_4 db '4) set clock',0
menu_array dw menu_str_1,menu_str_2,menu_str_3,menu_str_4
table dw reset_pc,start_system,clock,set_clock
reset dw 0,0ffffh
csip dw showmenu,7c0h
t_f db '00/00/00 00:00:00',0
t_p db 9,0,8,3,7,6,4,9,2,12,0,15
color db 2
;一些初始化操作
set_init:
mov ax,7c0h
mov ds,ax
jmp dword ptr ds:csip
;显示菜单
showmenu:
push cs
pop ds
mov cl,2
mov dh,8
mov dl,30
mov bp,0
showmenu_repeat:
mov si,menu_array[bp]
call show_str
inc dh
add bp,2
cmp bp,8
jb showmenu_repeat
;监听键盘
listener_keyboard:
sub ah,ah
int 16h
cmp al,31h
jb lk_next
cmp al,34h
ja lk_next
mov bl,al
sub bl,31h
mov bh,0
add bx,bx
call word ptr table[bx]
lk_next:
jmp short listener_keyboard
;重新启动计算机
reset_pc:
jmp dword ptr reset
;引导现有操作系统
start_system:
call cls
push cs
pop ds
mov si,offset do_start_system
push cs
pop es
mov di,200h
mov cx,offset do_start_system_end - offset do_start_system
cld
rep movsb
mov bx,200h
jmp bx
do_start_system:
mov bx,0
mov dx,80h
mov cx,1
mov ax,0201h
int 13h
mov bx,0
jmp bx
do_start_system_end: nop
;时钟程序
clock:
call cls
;复制日期、时间
clock_copy:
mov si,0
mov bh,0
clock_repeat:
mov al,t_p[si]
out 70h,al
in al,71h
mov ah,al
mov cl,4
shr al,cl
and ah,00001111B
add ax,3030h
mov bl,t_p[si+1]
mov word ptr t_f[bx],ax
add si,2
cmp si,12
jb clock_repeat
;Esc退出,F1改变颜色
in al,60h
cmp al,1
je back_menu
mov cl,color
cmp al,3bh
jne clock_show
inc cl
and cl,00000111b
mov color,cl
;显示日期、时间
clock_show:
mov si,offset t_f
mov dh,8
mov dl,30
call show_str
jmp short clock_copy
back_menu:
call cls
jmp showmenu
;设置时间
set_clock:
call cls
;输入日期字符串
mov ax,0b800h
mov es,ax
mov di,160*8+30*2
mov si,offset t_f
clock_input:
mov ah,0
int 16h
cmp al,20h
jb nochar
mov es:[di],al
mov [si],al
inc si
add di,2
jmp clock_input
nochar:
cmp ah,0eh
je backspace
cmp ah,1ch
je enter
jmp clock_input
backspace:
enter:
;修改日期、时间
mov si,0
mov bh,0
clock_edit:
mov al,t_p[si]
out 70h,al
mov bl,t_p[si+1]
mov ax,word ptr t_f[bx]
sub ax,3030h
mov cl,4
shl al,cl
or al,ah
out 71h,al
add si,2
cmp si,12
jb clock_edit
jmp clock
;----------------------------------------------------
;功能:清屏
;参数:无
;返回:无
;----------------------------------------------------
cls:
push ax
push di
push es
mov ax,0b800h
mov es,ax
mov di,0
mov ax,720h
mov cx,2000
cls_s:
mov es:[di],ax
add di,2
loop cls_s
pop es
pop di
pop ax
ret
;----------------------------------------------------
;功能:显示以0为结尾的字符串
;参数:ds:si指向字符串,(dh)=行号,(dl)=列号,(cl)=字符属性
;返回:无
;----------------------------------------------------
show_str:
push ax
push dx
push si
push di
push es
mov ax,0b800h
mov es,ax
mov ax,160
mul dh
mov dh,0
add ax,dx
add ax,dx
mov di,ax
mov ah,cl
show_str_copy:
mov al,[si]
cmp al,0
je show_str_exit
mov es:[di],ax
inc si
add di,2
jmp show_str_copy
show_str_exit:
pop es
pop di
pop si
pop dx
pop ax
ret
setsystemend: nop
start:
;安装到软盘0面0道1扇区处
push cs
pop es
mov bx,offset setsystem ;es:bx指向写入磁盘的数据
mov dx,0 ;软区A,0面
mov cx,1 ;0道,1扇区
mov ax,0301h ;写扇区,扇区数
int 13h
;jmp setsystem
mov ax,4c00h
int 21h
code ends
end start
-------------------------------
易忽略的问题:
(1)注意数据标号的偏移地址,在安装程序中是相对于code段的
而int 19h将软盘程序复制到0:7c00h处,同时cs:ip指向0:7c00h偏移地址变了,上述代码中,将cs:ip改为7c0:0,这样数据标号的偏移地址就相同了
(2)关于第2个功能引导现有操作系统,将C盘的0面0道1扇区读入到0:7c00h处,而当前执行的代码(将C盘的引导程序这段代码复制到0:7c00h)也在这个区域,为了不被覆盖,所以将这段代码(上述代码中的do_start_system段)先复制到内存0:200处,再将cs:ip指向0:200
(3)关于修改日期、时间,上述代码在修改的时候没有限制什么的,所以要修改的话必须输入正确的格式
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;任务:编写一个可以自行启动计算机,不需要在现有操作系统环境中运行的程序
;功能:1)重新启动计算机
; 2)引导现有的操作系统
; 3)进入时钟程序
; 4)设置时间
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
assume cs:code
code segment
setsystem:
jmp set_init
menu_str_1 db '1) reset pc',0
menu_str_2 db '2) start system',0
menu_str_3 db '3) clock',0
menu_str_4 db '4) set clock',0
menu_array dw menu_str_1,menu_str_2,menu_str_3,menu_str_4
table dw reset_pc,start_system,clock,set_clock
reset dw 0,0ffffh
csip dw showmenu,7c0h
t_f db '00/00/00 00:00:00',0
t_p db 9,0,8,3,7,6,4,9,2,12,0,15
color db 2
;一些初始化操作
set_init:
mov ax,7c0h
mov ds,ax
jmp dword ptr ds:csip
;显示菜单
showmenu:
push cs
pop ds
mov cl,2
mov dh,8
mov dl,30
mov bp,0
showmenu_repeat:
mov si,menu_array[bp]
call show_str
inc dh
add bp,2
cmp bp,8
jb showmenu_repeat
;监听键盘
listener_keyboard:
sub ah,ah
int 16h
cmp al,31h
jb lk_next
cmp al,34h
ja lk_next
mov bl,al
sub bl,31h
mov bh,0
add bx,bx
call word ptr table[bx]
lk_next:
jmp short listener_keyboard
;重新启动计算机
reset_pc:
jmp dword ptr reset
;引导现有操作系统
start_system:
call cls
push cs
pop ds
mov si,offset do_start_system
push cs
pop es
mov di,200h
mov cx,offset do_start_system_end - offset do_start_system
cld
rep movsb
mov bx,200h
jmp bx
do_start_system:
mov bx,0
mov dx,80h
mov cx,1
mov ax,0201h
int 13h
mov bx,0
jmp bx
do_start_system_end: nop
;时钟程序
clock:
call cls
;复制日期、时间
clock_copy:
mov si,0
mov bh,0
clock_repeat:
mov al,t_p[si]
out 70h,al
in al,71h
mov ah,al
mov cl,4
shr al,cl
and ah,00001111B
add ax,3030h
mov bl,t_p[si+1]
mov word ptr t_f[bx],ax
add si,2
cmp si,12
jb clock_repeat
;Esc退出,F1改变颜色
in al,60h
cmp al,1
je back_menu
mov cl,color
cmp al,3bh
jne clock_show
inc cl
and cl,00000111b
mov color,cl
;显示日期、时间
clock_show:
mov si,offset t_f
mov dh,8
mov dl,30
call show_str
jmp short clock_copy
back_menu:
call cls
jmp showmenu
;设置时间
set_clock:
call cls
;输入日期字符串
mov ax,0b800h
mov es,ax
mov di,160*8+30*2
mov si,offset t_f
clock_input:
mov ah,0
int 16h
cmp al,20h
jb nochar
mov es:[di],al
mov [si],al
inc si
add di,2
jmp clock_input
nochar:
cmp ah,0eh
je backspace
cmp ah,1ch
je enter
jmp clock_input
backspace:
enter:
;修改日期、时间
mov si,0
mov bh,0
clock_edit:
mov al,t_p[si]
out 70h,al
mov bl,t_p[si+1]
mov ax,word ptr t_f[bx]
sub ax,3030h
mov cl,4
shl al,cl
or al,ah
out 71h,al
add si,2
cmp si,12
jb clock_edit
jmp clock
;----------------------------------------------------
;功能:清屏
;参数:无
;返回:无
;----------------------------------------------------
cls:
push ax
push di
push es
mov ax,0b800h
mov es,ax
mov di,0
mov ax,720h
mov cx,2000
cls_s:
mov es:[di],ax
add di,2
loop cls_s
pop es
pop di
pop ax
ret
;----------------------------------------------------
;功能:显示以0为结尾的字符串
;参数:ds:si指向字符串,(dh)=行号,(dl)=列号,(cl)=字符属性
;返回:无
;----------------------------------------------------
show_str:
push ax
push dx
push si
push di
push es
mov ax,0b800h
mov es,ax
mov ax,160
mul dh
mov dh,0
add ax,dx
add ax,dx
mov di,ax
mov ah,cl
show_str_copy:
mov al,[si]
cmp al,0
je show_str_exit
mov es:[di],ax
inc si
add di,2
jmp show_str_copy
show_str_exit:
pop es
pop di
pop si
pop dx
pop ax
ret
setsystemend: nop
start:
;安装到软盘0面0道1扇区处
push cs
pop es
mov bx,offset setsystem ;es:bx指向写入磁盘的数据
mov dx,0 ;软区A,0面
mov cx,1 ;0道,1扇区
mov ax,0301h ;写扇区,扇区数
int 13h
;jmp setsystem
mov ax,4c00h
int 21h
code ends
end start
-------------------------------
易忽略的问题:
(1)注意数据标号的偏移地址,在安装程序中是相对于code段的
而int 19h将软盘程序复制到0:7c00h处,同时cs:ip指向0:7c00h偏移地址变了,上述代码中,将cs:ip改为7c0:0,这样数据标号的偏移地址就相同了
(2)关于第2个功能引导现有操作系统,将C盘的0面0道1扇区读入到0:7c00h处,而当前执行的代码(将C盘的引导程序这段代码复制到0:7c00h)也在这个区域,为了不被覆盖,所以将这段代码(上述代码中的do_start_system段)先复制到内存0:200处,再将cs:ip指向0:200
(3)关于修改日期、时间,上述代码在修改的时候没有限制什么的,所以要修改的话必须输入正确的格式
评论次数(2) |
浏览次数(1136) |
类型(汇编实验) |
收藏此文 |