栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

汇编语言王爽课程设计二

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

汇编语言王爽课程设计二

前言:本文涉及两种代码,未安装虚拟机的参照第一种代码实现三四功能即可,

阅读下面的材料
开机后,CPU自动进入到FFFF:0单元处执行,此处有一条跳转指令。CPU执行该指令后,转去执行BIOS中的硬件系统检测和初始化程序。
初始化程序将建立BIOS所支持的中断向量,即将BIOS提供的中断例程的入口地址登记在中断向量表中。
硬件系统检测和初始化完成后,调用int 19h进行操作系统的引导。
如果设为从软盘启动操作系统,则int 19h将主要完成以下工作。

控制0号软驱,读取软盘0道0面1扇区的内容到0:7c00;
将CS:IP指向0:7c00。
软盘的0道0面1扇区中装有操作系统引导程序。int 19h将其装到0:7c00处后,设置CPU从0:7c00开始执行此处的引导程序,操作系统被激活,控制计算机。
如果在0号软驱中没有软盘,或发生软盘I/O错误,则int 19h将主要完成以下工作。

读取硬盘C的0道0面1扇区的内容到0:7c00;
将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”后可更改当前的日期,时间,更改后返回到主选单(提示:输入字符串)

以下内容进实现 3 4号功能  

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

data segment

BEGIN		db	 512 dup(0)				;因为一个扇区字节大小为512

BEGIN_BOOT	db       512 dup(0)				;2号扇区	ds:[si]->es:[di]
		db  	 512 dup(0)				;3
		db  	 512 dup(0)				;4

data ends

stack segment 
	db 128 dup(0)
stack ends

code segment
	start:	mov ax,stack
		mov ss,ax
		mov sp,128(0)

;		mov bx,OFFSET Boot_end - OFFSET Boot

;		call cpy_boot_toDiskA	;把上述代码复制到软盘中

		call cpy_Boot
		call sav_old_int9	;因为要编写新的int9

		mov bx,0
		push bx
		mov bx,7e00h
		push bx
		retf		;相当于执行 pop ip pop cs  返还到保存在0:7e00h中的 Boot代码
				;ret 相当于 pop ip

		mov ax,4c00h
		int 21h

;int 19h 的内容: 将软盘0面0道1扇区(512)-》写入 0:7c00h  cs:ip=0:7c00h 
;将0面0到2扇区开始的 3个扇区中的内容 复制 到 0:7e00h 	cs:ip-07e00h
;先将 OFFSET Boot_end -OFFSET Boot 复制到 0面0道2扇区开始的3个扇区
;es:[bx]->复制到 1 2 3 4扇区
;==========================================================
Boot:		jmp BOOT_START

;*******************************************************************
;*******************************************************************
;*******************************************************************
									;数据区
OPTION_1		db	'1) restart pc ',0		;地址两个字节????
OPTION_2		db	'2) start system ',0	
OPTION_3		db	'3) show clock ',0	
OPTION_4		db	'4) set clock ',0	

ADDRESS_OPTION		dw 	OFFSET OPTION_1 - OFFSET Boot + 7e00h		;ADDRESS_OPTION[0]     可以不加OFFSET的!!!
			dw	OFFSET OPTION_2 - OFFSET Boot + 7e00h
			dw	OFFSET OPTION_3 - OFFSET Boot + 7e00h
			dw	OFFSET OPTION_4 - OFFSET Boot + 7e00h

TIME_CMOS		db  	9,8,7,4,2,0			;CMOS RAM中存储的时间信息	详情看实验16
TIME_STYLE		db	'YY/MM/DD HH:MM:SS',0		

STRING_STACK            db	12 dup('0'),0			;time_style 中12个字节型数据

;*******************************************************************
;*******************************************************************
;*******************************************************************



BOOT_START:	call init_reg			;寄存器 对es ds赋值 es 0b800 ds 0
		call clear_screen		;清屏
		call show_option		

		jmp choose_option

		mov ax,4c00h
		int 21h
;==========================================================
choose_option:	call clear_buff			;调用了int 16h 来处理键盘缓冲区中已经输入数据		详情看实验十七

		mov ah,0			;从数据缓存区中读取数据
		int 16h				; ah 扫描码 al ASCII码

		cmp al,'1'
		je isChooseOne
		cmp al,'2'
		je isChooseTwo
		cmp al,'3'
		je isChooseThree
		cmp al,'4'
		je isChooseFour


		jmp choose_option	;不用管ret

;==========================================================
isChooseOne:	mov di,160*3
		mov byte ptr es:[di],'1'	;es是0b800h  将写入的数据 显示到屏幕上	
		jmp choose_option

isChooseTwo:	mov di,160*3
		mov byte ptr es:[di],'2'	;es是0b800h
		jmp choose_option

isChooseThree:	mov di,160*3
		mov byte ptr es:[di],'3'	;es是0b800h
		call show_clock			;功能3:执行动态显示当前日期,时间的程序!!!
		jmp BOOT_START

isChooseFour:	mov di,160*3
		mov byte ptr es:[di],'4'	;es是0b800h
		call set_clock
		jmp choose_option

;======================================================================
set_clock:	call clear_string_stack
		call show_string_stack
		call get_string
		call set_time			;修改cmos中的时间


		ret

;=======================================================
set_time:	
		mov bx,OFFSET TIME_CMOS -Boot+7e00h
		mov si,OFFSET STRING_STACK - OFFSET Boot + 7e00h
		mov cx,6

setTime:	mov dx,ds:[si]			;换位 bcd码
		sub dh,30h			;ds:[si] ='12'
		sub dl,30h			; dh ='2' dl= '1'
		shl dl,1
		shl dl,1
		shl dl,1
		shl dl,1
		and dh,00001111b
		or dl,dh

		mov al,ds:[bx]			;传递给cmos
		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			;偏移地址 0-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 show_string

		pop di
		pop si

		ret
;====================================================================

clear_string_stack:
		push bx
		push cx
		push es
		push si
		push di

		mov bx,OFFSET STRING_STACK -OFFSET Boot +7e00h
		mov dx,3030h

		mov cx,6

clearStringStack:

		mov ds:[bx],dx
		add bx,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 TIME_CMOS -OFFSET Boot +7e00h

showTime:	mov si,bx
		mov cx,6
		mov di,160*20

showDate:	mov al,ds:[si]
		out 70h,al			;访问CMOS端口 与cpu建立链接 十四章知识 70h为地址端口 将ds:[si] (单元号)送入端口70h out 为向此端口写入
		in al,71h			;71H为数据端口 in 为向此单元读出
		
		mov ah,al
		shr ah,1
		shr ah,1
		shr ah,1
		shr ah,1
		and al,00001111b		;因4位一个字节=一个字符  因此读出时间信息 把其分别至于ah 与al中

		add ah,30h
		add al,30h
	
		mov es:[di],ah
		mov es:[di+2],al


		add di,6			;因还有一个 / 字符“ ” 字符  :字符
		inc si
		loop showDate

		jmp showTime

showTimeRet:	call set_old_int9		;把原来的int 9重新设置回来

		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 new_int9 -OFFSET Boot +7e00h
		mov word ptr es:[9*4+2],0
		sti

		pop es
		pop bx

		ret

;==========================================================
new_int9:					;第十五章内容 外中断
	;	push bx
		push ax

		call clear_buff			;调用int 16h 来进行   即 把缓存区中的数据清理一下

		in al,60h			;读出键盘的输入 随后引发int9中断
		pushf				;开始int 9 标志寄存器入栈		设置int 9
		
	;	pushf
	;	pop bx
	;	and bh,11111100b
	;	push bx
	;	popf				;if=0 tf=0	通常不设置

		call dword ptr cs:[200h]	;cs ip 入栈 	相关内容在 第十章 转移地址在内存中的call指令
						; ip=cs*16+200	cs=cs*16+202 从内存地址位中断类型吗*4和终端类型码*4+2 的两个子单元中读取中断处理程序的地址设置 ip和cs
		
		cmp al,01h			;ESC	
		je isEsc			;此时仍有一个问题 若按了esc 确实停止了 但此时屏幕上仍然有color
						;因此需要跳转到开头
		cmp al,3Bh			;F1的意思
		jne int9Ret
		call change_time_color	


int9Ret:	pop ax
	;	pop bx
		iret				;pop ip pop cs popf

;=========================================================
isEsc:		pop ax				;此步的目的 即复刻int9Ret 
		add sp,4			;但不同的是  不需要pop ip 与cs  直接返回showTimeRet即可
		popf				;从栈中弹出数据送入标志寄存器中
		
		jmp showTimeRet

		
;==========================================================
change_time_color:
		push bx
		push cx
		push es

		mov bx,0b800h
		mov es,bx
		mov bx,160*20+1   		;时间显示的位置
		
		mov cx,17			;时间字符的长度 没必要改变太多的颜色

changeTimeColor:
		inc byte ptr es:[bx]
		add bx,2
		loop changeTimeColor

		pop es
		pop cx
		pop bx
		ret

;==========================================================
show_style:
		mov si,OFFSET TIME_STYLE-OFFSET Boot +7E00h
		mov di,160*20
		
		call show_string		;可直接调用


		ret

;==========================================================
clear_buff:	mov ah,1			;ah=1 即向键盘缓冲区中写入数据
		int 16h
		jz clearBuffRet
		mov ah,0			;ah=0 即向键盘缓冲区中读出数据
		int 16h
		jmp clear_buff

clearBuffRet:	ret

;==========================================================
show_option:
		mov bx,OFFSET ADDRESS_OPTION - OFFSET Boot + 7e00h
		mov di,160*10+30*2
		mov cx,4

showOption:	mov si,ds:[bx]			;地址赋予si!!
		call show_string
		add bx,2
		add di,160			;换下一行
		loop showOption		

		ret

;==========================================================
show_string:	push dx
		push ds
		push es
		push si
		push di	

showString:	mov dl,ds:[si]
		cmp dl,0
		je showStringRet
		mov es:[di],dl
		add di,2
		inc si
		jmp showString

showStringRet:
		pop di
		pop si
		pop es
		pop ds
		pop dx

		ret

;==========================================================
clear_screen:
		mov bx,0
		mov dx,07000h		
		mov cx,2000

clearScreen:	mov es:[bx],dx
		add bx,2
		loop clearScreen
		
		ret
		
;==========================================================
init_reg:	mov bx,0b800h
		mov es,bx

		mov bx,0
		mov ds,bx
		ret



Boot_end: 	nop





;==========================================================
sav_old_int9:
		mov bx,0
		mov es,bx

		push es:[9*4]		;将原来的int 9 保存到此单元
		pop es:[200h]
		push es:[9*4+2]
		pop es:[202h]

		ret
;==========================================================
cpy_Boot:
		mov bx,cs
		mov ds,bx
		mov si,OFFSET Boot

		mov bx,0
		mov es,bx
		mov di,7E00H

		mov cx,OFFSET Boot_end - OFFSET Boot
		cld
		rep movsb

		ret


code ends
end start

没有虚拟机的话 写到这一步就ok了  以下代码在虚拟机下运行即可

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

data segment

BEGIN		db	 512 dup(0)				;因为一个扇区字节大小为512

BEGIN_BOOT	db       512 dup(0)				;2号扇区	ds:[si]->es:[di]
		db  	 512 dup(0)				;3
		db  	 512 dup(0)				;4

data ends

stack segment 
	db 128 dup(0)
stack ends

code segment
	start:	mov ax,stack
		mov ss,ax
		mov sp,128(0)

		mov bx,OFFSET Boot_end - OFFSET Boot

		call cpy_introduce_toDiskA	;引导程序
		call cpy_boot_toDiskA		;把上述代码复制到软盘中

;		call cpy_Boot
;		call sav_old_int9	;因为要编写新的int9

;		mov bx,0
;		push bx
;		mov bx,7e00h
;		push bx
;		retf		;相当于执行 pop ip pop cs  返还到保存在0:7e00h中的 Boot代码
				;ret 相当于 pop ip

		mov ax,4c00h
		int 21h

;int 19h 的内容: 将软盘0面0道1扇区(512)-》写入 0:7c00h  cs:ip=0:7c00h 
;将0面0到2扇区开始的 3个扇区中的内容 复制 到 0:7e00h 	cs:ip-07e00h
;先将 OFFSET Boot_end -OFFSET Boot 复制到 0面0道2扇区开始的3个扇区
;es:[bx]->复制到 1 2 3 4扇区

;===================================================================
introduce:	mov bx,0
		mov ss,bx
		mov sp,7c00h

		call sav_old_int9
		call cpy_boot_FromDiskA

		mov bx,0
		push bx
		mov bx,7e00h
		push bx
		retf

;========================================================
cpy_boot_FromDiskA:
		mov bx,0
		mov es,bx
		mov bx,7e00h


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



		ret



;==========================================================
sav_old_int9:
		mov bx,0
		mov es,bx

		push es:[9*4]		;将原来的int 9 保存到此单元
		pop es:[200h]
		push es:[9*4+2]
		pop es:[202h]

		ret

		db 512 dup(0)
	

introduce_end:	nop

;===============================================================
cpy_introduce_toDiskA:
		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

;===============================================================
cpy_boot_toDiskA:
		mov bx,cs
		mov es,bx
		mov bx,OFFSET Boot
						;利用 int 13h 中断例程对磁盘进行读写
		mov al,2			;写入的扇区数	因下面代码的大小 两个512 扇区足够
		mov ch,0			;磁道号
		mov cl,2			;扇区号
		mov dl,0			;驱动器号  软驱从0开始 0:软驱A 1:软驱B  硬盘从80h开始 80h:硬盘C 81h: 硬盘D
		mov dh,0			;面号
		mov ah,3			;int 13h的3号功能表示写扇区
		int 13h



		ret

;==========================================================
Boot:		jmp BOOT_START
	
;*******************************************************************
;*******************************************************************
;*******************************************************************
									;数据区
OPTION_1		db	'1) restart pc ',0		;地址两个字节????
OPTION_2		db	'2) start system ',0	
OPTION_3		db	'3) show clock ',0	
OPTION_4		db	'4) set clock ',0	

ADDRESS_OPTION		dw 	OFFSET OPTION_1 - OFFSET Boot + 7e00h		;ADDRESS_OPTION[0]     可以不加OFFSET的!!!
			dw	OFFSET OPTION_2 - OFFSET Boot + 7e00h
			dw	OFFSET OPTION_3 - OFFSET Boot + 7e00h
			dw	OFFSET OPTION_4 - OFFSET Boot + 7e00h

TIME_CMOS		db  	9,8,7,4,2,0			;CMOS RAM中存储的时间信息	详情看实验16
TIME_STYLE		db	'YY/MM/DD HH:MM:SS',0		

STRING_STACK            db	12 dup('0'),0			;time_style 中12个字节型数据

;*******************************************************************
;*******************************************************************
;*******************************************************************



BOOT_START:	call init_reg			;寄存器 对es ds赋值 es 0b800 ds 0
		call clear_screen		;清屏
		call show_option		

		jmp choose_option

		mov ax,4c00h
		int 21h
;==========================================================
choose_option:	call clear_buff			;调用了int 16h 来处理键盘缓冲区中已经输入数据		详情看实验十七

		mov ah,0			;从数据缓存区中读取数据
		int 16h				; ah 扫描码 al ASCII码

		cmp al,'1'
		je isChooseOne
		cmp al,'2'
		je isChooseTwo
		cmp al,'3'
		je isChooseThree
		cmp al,'4'
		je isChooseFour


		jmp choose_option	;不用管ret

;==========================================================
isChooseOne:	mov di,160*3
		mov byte ptr es:[di],'1'	;es是0b800h  将写入的数据 显示到屏幕上	
		mov bx,0ffffh			;每次重启后都是从此处开始读入
		push bx
		mov bx,0
		push bx
		retf

		jmp choose_option

isChooseTwo:	mov di,160*3
		mov byte ptr es:[di],'2'	;es是0b800h
		call start_system
		jmp choose_option

isChooseThree:	mov di,160*3
		mov byte ptr es:[di],'3'	;es是0b800h
		call show_clock			;功能3:执行动态显示当前日期,时间的程序!!!
		jmp BOOT_START

isChooseFour:	mov di,160*3
		mov byte ptr es:[di],'4'	;es是0b800h
		call set_clock
		jmp choose_option

;=================================================================
start_system:	mov bx,0
		mov es,bx
		mov bx,7c00h

		mov al,1
		mov ch,0
		mov cl,1
		mov cl,80h			;硬盘c
		mov dh,0
		mov ah,2
		int 13h


		mov bx,0
		push bx
		mov bx,7c00h
		push bx
		retf
	

		ret


;======================================================================
set_clock:	call clear_string_stack
		call show_string_stack
		call get_string
		call set_time			;修改cmos中的时间


		ret

;=======================================================
set_time:	
		mov bx,OFFSET TIME_CMOS -Boot+7e00h
		mov si,OFFSET STRING_STACK - OFFSET Boot + 7e00h
		mov cx,6

setTime:	mov dx,ds:[si]			;换位 bcd码
		sub dh,30h			;ds:[si] ='12'
		sub dl,30h			; dh ='2' dl= '1'
		shl dl,1
		shl dl,1
		shl dl,1
		shl dl,1
		and dh,00001111b
		or dl,dh

		mov al,ds:[bx]			;传递给cmos
		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			;偏移地址 0-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 show_string

		pop di
		pop si

		ret
;====================================================================

clear_string_stack:
		push bx
		push cx
		push es
		push si
		push di

		mov bx,OFFSET STRING_STACK -OFFSET Boot +7e00h
		mov dx,3030h

		mov cx,6

clearStringStack:

		mov ds:[bx],dx
		add bx,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 TIME_CMOS -OFFSET Boot +7e00h

showTime:	mov si,bx
		mov cx,6
		mov di,160*20

showDate:	mov al,ds:[si]
		out 70h,al			;访问CMOS端口 与cpu建立链接 十四章知识 70h为地址端口 将ds:[si] (单元号)送入端口70h out 为向此端口写入
		in al,71h			;71H为数据端口 in 为向此单元读出
		
		mov ah,al
		shr ah,1
		shr ah,1
		shr ah,1
		shr ah,1
		and al,00001111b		;因4位一个字节=一个字符  因此读出时间信息 把其分别至于ah 与al中

		add ah,30h
		add al,30h
	
		mov es:[di],ah
		mov es:[di+2],al


		add di,6			;因还有一个 / 字符“ ” 字符  :字符
		inc si
		loop showDate

		jmp showTime

showTimeRet:	call set_old_int9		;把原来的int 9重新设置回来

		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 new_int9 -OFFSET Boot +7e00h
		mov word ptr es:[9*4+2],0
		sti

		pop es
		pop bx

		ret

;==========================================================
new_int9:					;第十五章内容 外中断
	;	push bx
		push ax

		call clear_buff			;调用int 16h 来进行   即 把缓存区中的数据清理一下

		in al,60h			;读出键盘的输入 随后引发int9中断
		pushf				;开始int 9 标志寄存器入栈		设置int 9
		
	;	pushf
	;	pop bx
	;	and bh,11111100b
	;	push bx
	;	popf				;if=0 tf=0	通常不设置

		call dword ptr cs:[200h]	;cs ip 入栈 	相关内容在 第十章 转移地址在内存中的call指令
						; ip=cs*16+200	cs=cs*16+202 从内存地址位中断类型吗*4和终端类型码*4+2 的两个子单元中读取中断处理程序的地址设置 ip和cs
		
		cmp al,01h			;ESC	
		je isEsc			;此时仍有一个问题 若按了esc 确实停止了 但此时屏幕上仍然有color
						;因此需要跳转到开头
		cmp al,3Bh			;F1的意思
		jne int9Ret
		call change_time_color	


int9Ret:	pop ax
	;	pop bx
		iret				;pop ip pop cs popf

;=========================================================
isEsc:		pop ax				;此步的目的 即复刻int9Ret 
		add sp,4			;但不同的是  不需要pop ip 与cs  直接返回showTimeRet即可
		popf				;从栈中弹出数据送入标志寄存器中
		
		jmp showTimeRet

		
;==========================================================
change_time_color:
		push bx
		push cx
		push es

		mov bx,0b800h
		mov es,bx
		mov bx,160*20+1   		;时间显示的位置
		
		mov cx,17			;时间字符的长度 没必要改变太多的颜色

changeTimeColor:
		inc byte ptr es:[bx]
		add bx,2
		loop changeTimeColor

		pop es
		pop cx
		pop bx
		ret

;==========================================================
show_style:
		mov si,OFFSET TIME_STYLE-OFFSET Boot +7E00h
		mov di,160*20
		
		call show_string		;可直接调用


		ret

;==========================================================
clear_buff:	mov ah,1			;ah=1 即向键盘缓冲区中写入数据
		int 16h
		jz clearBuffRet
		mov ah,0			;ah=0 即向键盘缓冲区中读出数据
		int 16h
		jmp clear_buff

clearBuffRet:	ret

;==========================================================
show_option:
		mov bx,OFFSET ADDRESS_OPTION - OFFSET Boot + 7e00h
		mov di,160*10+30*2
		mov cx,4

showOption:	mov si,ds:[bx]			;地址赋予si!!
		call show_string
		add bx,2
		add di,160			;换下一行
		loop showOption		

		ret

;==========================================================
show_string:	push dx
		push ds
		push es
		push si
		push di	

showString:	mov dl,ds:[si]
		cmp dl,0
		je showStringRet
		mov es:[di],dl
		add di,2
		inc si
		jmp showString

showStringRet:
		pop di
		pop si
		pop es
		pop ds
		pop dx

		ret

;==========================================================
clear_screen:
		mov bx,0
		mov dx,07000h		
		mov cx,2000

clearScreen:	mov es:[bx],dx
		add bx,2
		loop clearScreen
		
		ret
		
;==========================================================
init_reg:	mov bx,0b800h
		mov es,bx

		mov bx,0
		mov ds,bx
		ret



Boot_end: 	nop





;==========================================================
cpy_Boot:
		mov bx,cs
		mov ds,bx
		mov si,OFFSET Boot

		mov bx,0
		mov es,bx
		mov di,7E00H

		mov cx,OFFSET Boot_end - OFFSET Boot
		cld
		rep movsb

		ret


code ends
end start

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1028098.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号