王爽《汇编语言》课程设计2完整版

assume cs:code,ds:data,ss:stack

stack segment
 db 128 dup (0)
stack ends

data segment
 begin        db 512 dup (0)
 begin_boot   db 512 dup (0)
              db 512 dup (0)
              db 512 dup (0)
data ends

code segment
start: 
       mov ax,stack
       mov ss,ax
       mov sp,128
       
       call copy_introduce
       call copy_boot_disk


       mov ax,4c00h
       int 21h
;---------------------------------
introduce:                     ;引导程序,将程序复制到0:7c00处,
        mov bx,0
	mov ss,bx
	mov sp,7c00h

	call save_old_int9
	call copy_Boot_fromdisk

	mov bx,0
	push bx
	mov bx,7e00h           ;设置cs:ip为0:7e00h执行Boot程序
	push bx
	retf
;-----------------------------
copy_Boot_fromdisk:
        mov bx,0
	mov es,bx
	mov bx,7e00h

	mov al,2
	mov ch,0
	mov cl,2
	mov dl,0
	mov dh,0
	mov ah,2
	int 13h

	ret
;----------------------------------
 save_old_int9:
       mov bx,0
       mov es,bx

       push es:[9*4]
       pop es:[200h]
       push es:[9*4+2]
       pop es:[202h]
       ret
;-----------------------
       db 512 dup (0)
introduce_end:nop
 ;=================================
copy_introduce:
       mov bx,cs
       mov es,bx
       mov bx,offset introduce

       mov al,1
       mov ch,0
       mov cl,1
       mov dl,0
       mov dh,0
       mov ah,3
       int 13h
       ret
;----------------------
copy_boot_disk:
       mov bx,cs
       mov es,bx
       mov bx,offset Boot

       mov al,2
       mov ch,0
       mov cl,2
       mov dl,0
       mov dh,0
       mov ah,3
       int 13h
       ret
;--------------------------------
Boot:
       jmp Boot_start
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
option1   db '(1) reset pc',0
option2   db '(2) start system',0
option3   db '(3) clock',0
option4   db '(4) set clock',0

address_option   dw offset option1 - offset Boot + 7e00h
                 dw offset option2 - offset Boot + 7e00h
                 dw offset option3 - offset Boot + 7e00h
                 dw offset option4 - offset Boot + 7e00h
 timestyle   db '00/00/00 00:00:00',0
 timeadress  db 9,8,7,4,2,0
 string_stack   db 12 dup ('0'),0
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx     

Boot_start:
        call init_reg
	call clear_screen
	call show_option

	jmp short choose_option
        
	mov ax,4c00h
        int 21h
;-----------------------
choose_option:
        call clear_buff
        
	mov ah,0
	int 16h

	cmp al,'1'
	je choose1
	cmp al,'2'
	je choose2
	cmp al,'3'
	je choose3
	cmp al,'4'
	je choose4

        jmp choose_option

choose1:mov di,160*3
        mov byte ptr es:[di],'1'
	mov bx,0ffffh
	push bx
	mov bx,0
	push bx
	retf
        jmp choose_option

choose2:mov di,160*3
        mov byte ptr es:[di],'2'
	call start_old_system
        jmp choose_option

choose3:mov di,160*3
        mov byte ptr es:[di],'3'
	call show_clock
        jmp Boot_start

choose4:mov di,160*3
        mov byte ptr es:[di],'4'
	call set_clock
        jmp choose_option
;-----------------------
start_old_system:
        mov bx,0
	mov es,bx
	mov bx,7c00h

	mov al,1
	mov ch,0
	mov cl,1
	mov dl,80h     ;80h代表C盘
	mov dh,0
	mov ah,2
	int 13h

        mov bx,0
	push bx
	mov bx,7c00h
	push bx
	retf
;------------------------
set_clock:
        call clear_string_stack
        call show_string_stack
	call get_string
	call set_time

	ret
;--------------------
set_time:
        mov bx,offset timeadress - offset Boot + 7e00h
	mov si,offset string_stack - offset Boot +7e00h
	mov cx,6
settime:
        mov dx,ds:[si]
	sub dh,30h
	sub dl,30h
	shl dl,1
	shl dl,1
	shl dl,1
	shl dl,1
	and dh,00001111b
	or dl,dh
	mov al,ds:[bx]
	out 70h,al
	mov al,dl
	out 71h,al
        add si,2
	inc bx
	loop settime
        ret
;-------------------------
get_string:
        mov si,offset string_stack - offset Boot + 7e00h
	mov bx,0
getstring:
        call clear_buff
	mov ah,0
	int 16h
	cmp al,'0'
	jb notnumber
	cmp al,'9'
	ja notnumber
	call char_push
	call show_string_stack

	jmp getstring
getstringret:
        ret
notnumber:
        cmp ah,0eh
	je isbackspace
	cmp ah,1ch
	je getstringret
	jmp getstring
isbackspace:
        call char_pop
	call show_string_stack
        jmp getstring
;--------------------------
char_pop:
        cmp bx,0
	je charpopret
	dec bx
	mov byte ptr ds:[si+bx],'0'
charpopret:
        ret
;-------------------------
char_push:
        cmp bx,11
	ja charpushret
	mov ds:[si+bx],al
	inc bx
charpushret:
        ret
;-------------------
show_string_stack:
        push si
	push di
	mov si,offset string_stack - offset Boot + 7e00h
        mov di,160*4
	call showstr
	pop di
	pop si
	ret
;--------------------
clear_string_stack:
        push bx
	push cx
	push es
	push si
	push di

        mov si,offset string_stack - offset Boot + 7e00h
	mov dx,3030h

	mov cx,6
clearstringstack:
        mov ds:[si],dx
	add si,2
	loop clearstringstack

	pop di
	pop si
	pop es
	pop cx
	pop bx
	ret
;----------------------
show_clock:
        call show_style
	call set_new_int9
        
	mov bx,offset timeadress - offset Boot + 7e00h
 showtime:       
	mov si,bx
	mov di,160*20
	mov cx,6
showdate:
        mov al,ds:[si]
	out 70h,al
	in al,71h

	mov ah,al
	shr ah,1
	shr ah,1
	shr ah,1
	shr ah,1
	and al,00001111b
	add ah,30h
	add al,30h
	mov es:[di],ah
	mov es:[di+2],al
	add di,6
	inc si
	loop showdate

        jmp showtime
show_clockret:
       call set_old_int9
       ret
;----------------------
show_style:
       mov si,offset timestyle - offset Boot + 7e00h
       mov di,160*20
       call showstr
       ret
;--------------------
set_old_int9:
       push bx
       push es

       mov bx,0
       mov es,bx
       cli
       push es:[200h]
       pop es:[9*4]
       push es:[202h]
       pop es:[9*4+2]
       sti

       pop es
       pop bx
       ret
;---------------------
set_new_int9:
       push bx
       push es

       mov bx,0
       mov es,bx

       cli
       mov word ptr es:[9*4],offset newint9 - offset Boot + 7e00h
       mov word ptr es:[9*4+2],0
       sti
       
       pop es
       pop bx
       ret
;------------------------
newint9:
       push ax
       call clear_buff

       in al,60h
       pushf
       call dword ptr cs:[200h]
       
       cmp al,01h
       je inesc
       cmp al,3bh
       jne int9ret
       call change_time_color
       
int9ret:
       pop ax
       iret
inesc:
       pop ax
       add sp,4
       popf
       jmp show_clockret
   ;----------------------
change_time_color:
       push bx
       push cx
       push es

       mov bx,0b800h
       mov es,bx
       mov cx,17
       mov bx,160*20+1
change_time_colors:
       inc byte ptr es:[bx]
       add bx,2
       loop change_time_colors

       pop es
       pop cx
       pop bx     
;-------------------------
clear_buff:
        mov ah,1
	int 16h
	jz clearbuffret
	mov ah,0
	int 16h
	jmp clear_buff
clearbuffret:
	ret
;---------------------
show_option:
        mov bx,offset address_option - offset Boot + 7e00h
        mov cx,4
	mov di,160*10 + 30*2
show_options:
        mov si,ds:[bx]
	call showstr
	add di,160
	add bx,2
	loop show_options
	ret
;------------------------------
showstr:
        push cx  
	push di
showstrs:
	mov cl,ds:[si]
        cmp cl,0
	je showstrret
	mov es:[di],cl
	add di,2
	inc si
	jmp short showstrs
showstrret:
        pop di
        pop cx
	ret

;----------------
init_reg:
       mov bx,0b800h
       mov es,bx

       mov bx,0
       mov ds,bx
       ret
;------------------  
clear_screen:
       mov bx,0
       mov dx,0700h   ;清屏中对字符属性设置应该为07h,而不是0
       mov cx,2000
clearscreen:
       mov es:[bx],dx
       add bx,2
       loop clearscreen
       ret
;-----------------------
       db 512 dup (0)
Boot_end:
       nop
           
 code ends
  end start

阅读下面的材料 : 开机后, 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 扇区中的程序就必须负责将其他扇区中的内容读入内存。 这个程序较为复杂,它用到了我们所学到的所有技术,需要进行仔细地分析和耐心地调试。这个程序对于我们的整个学习过程是具有总结性的,希望读者能够尽力完成。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值