⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 p_int.asm

📁 操作系统实验教程核心技术与编程实例书中地例子代码
💻 ASM
字号:
;600*800 16色 模式下的中断服务程序
;By 潘龙平/nuaa/08990115
;Date:4/30/2002
;===============================================================

;INT 21中断服务程序
;00H 中断:显示一个英文字符
;01H 中断:显示一个中英文字符串(屏幕划分为37行100列)
;02H 中断:用一定颜色来清屏
;03H 中断:显示一个用颜色填充的矩形(屏幕划分为37行100列)
;04H 中断:显示一个点(600行800列)
;05H 中断:显示一个图片(600行800列)
;06H 中断:画一条横/竖线(600行800列)
;07H 中断:显示一个矩形框(600行800列)

;其他接口:GDT_VRAM_SEL,OS_DATA_SEL(英文字符集),HZK_BUF_SEL(汉字集)


SERVE_INT21	PROC FAR 	
		CMP AH,0
		JE LBL_INT21_0
		CMP AH,1
		JE LBL_INT21_1
		CMP AH,2
		JE LBL_INT21_2
		CMP AH,3
		JE LBL_INT21_3
		CMP AH,4
		JE LBL_INT21_4
		CMP AH,5
		JE LBL_INT21_5
		CMP AH,6
		JE LBL_INT21_6
		CMP AH,7
		JE LBL_INT21_7
		JMP LBL_INT21_END

LBL_INT21_0:
		CALL SHOW_CHAR
		IRETD
LBL_INT21_1:
		CALL SHOW_STRING
		IRETD
LBL_INT21_2:
					;CL为颜色
		PUSH AX
		PUSH BX
		PUSH CX
		PUSH DX

		MOV BX,0
		MOV DX,0
		MOV AH,38
		MOV AL,100
		CALL RECT

		POP DX
		POP CX
		POP BX
		POP AX
		IRETD
LBL_INT21_3:
		CALL RECT
		IRETD
LBL_INT21_4:
		PUSH DS
		PUSH AX
		PUSH CX
		PUSH DX
		PUSH DI
		MOV AX,GDT_VRAM_SEL
		MOV DS,AX
		CALL DOT
		POP DI
		POP DX
		POP CX
		POP AX
		POP DS
		IRETD
LBL_INT21_5:
		CALL SHOW_BMP
		IRETD
LBL_INT21_6:
		CALL LINE
		IRETD
LBL_INT21_7:
		CALL RECT_FRAME
		IRETD
LBL_INT21_END:
		IRETD
SERVE_INT21	ENDP


;12h模式下显示一个字符串
;ES:DI字符串所在地址
;DS:SI为汉字点阵所在的32字节首地址
;调用GET_HZ_ADDR过程,SHOWHZ过程
;BX 行(0——29)
;DX 列(0——79)
;CL 颜色(0——15)

SHOW_STRING PROC 
	PUSH AX
	
LBL_SHOW_STRING_LOOP:
	MOV AL,ES:[DI]
	CMP AL,0
	JZ  LBL_SHOW_STRING_EXIT
	CMP AL,127
	JB  LBL_SHOW_STRING_ENG
	MOV AX,ES:[DI]
	CALL GET_HZ_ADDR
	CALL SHOWHZ
	ADD DI,2
	ADD DX,2
	JMP LBL_SHOW_STRING_LOOP
LBL_SHOW_STRING_ENG:
	CALL SHOW_CHAR
	INC DX
	INC DI
	JMP LBL_SHOW_STRING_LOOP
LBL_SHOW_STRING_EXIT:
	POP AX
	RET
SHOW_STRING ENDP



;102h模式下显示一个英文字符(8*16)
;AL 字符的ASCII码
;BX 行(0——36)
;DX 列(0——99)
;CL 颜色(0——15)
SHOW_CHAR PROC 
	PUSH DS
	PUSH ES
	PUSH AX
	PUSH BP
	PUSH DI
	PUSH DX		;保存列数

	PUSH CX		;暂存颜色
	PUSH DX		;暂存列数
	PUSH BX		;暂存行数
	PUSH AX		;暂存字符

	MOV AX,GDT_VRAM_SEL
	MOV DS,AX

	MOV AX,OS_DATA_SEL	;取得字符集的地址ES:BP
	MOV ES,AX
	MOV BP,0

	POP AX
	MOV AH,0
	SHL AX,1
	SHL AX,1
	SHL AX,1
	SHL AX,1
	ADD BP,AX		;该字符的属性地址
	POP BX
	MOV AX,100*16		;100列
	MUL BX
	MOV DI,AX
	POP DX
	ADD DI,DX
	MOV CX,16
SHOW_CHAR_C1:
	MOV DX,3CEH
	MOV AL,8
	MOV AH,ES:[BP]
	INC BP
	OUT DX,AX
	MOV DX,3C4H
	MOV AX,0F02H
	OUT DX,AX

	INC DX
	MOV AL,[DI]		;必须先读
	MOV BYTE PTR [DI],0	;回写黑色
	POP AX			;取颜色
	PUSH AX
	OUT DX,AL		;写颜色
	MOV BYTE PTR [DI],0FFH  ;写内存
	ADD DI,100				;100列
LOOP SHOW_CHAR_C1

	POP CX
	POP DX
	POP DI
	POP BP
	POP AX
	POP ES
	POP DS
	RET
SHOW_CHAR ENDP

;得到该汉字点阵(16*16)
;AX为该汉字的内码
;DS:SI为汉字点阵所在的32字节首地址

GET_HZ_ADDR PROC
	PUSH CX
	PUSH DX
	PUSH DI

	PUSH AX
	XOR AH,AH
	SUB AX,0A1H
	XOR DX,DX
	MOV CX,94
	MUL CX
	INC DI
	POP CX
	PUSH CX
	MOV CL,CH
	XOR CH,CH
	ADD AX,CX
	SUB AX,0A1H
	MOV CX,32
	MUL CX
	XOR ECX,ECX
	MOV CX,DX
	XOR EDX,EDX
	MOV DX,AX


	MOV AX,HZK_BUF_SEL
	MOV DS,AX
	MOV ESI,ECX
	SHL ESI,16
	ADD ESI,EDX
	POP AX

	POP DI
	POP DX
	POP CX
	RET
GET_HZ_ADDR ENDP

;12h模式下显示一个16*16汉字
;DS:SI为汉字点阵所在的32字节首地址
;BX 行(0——36)
;DX 列(0——99)
;CL 颜色(0——15)

SHOWHZ	PROC 
	PUSH ES
	PUSH AX
	PUSH DX
	PUSH DI
	PUSH SI

	MOV AX,GDT_VRAM_SEL
	MOV ES,AX
	MOV CH,0
	PUSH CX		;暂存颜色
	PUSH DX		;暂存列数

	MOV AX,100*16			;100列
	MOV CX,BX
	XOR DX,DX
	MUL CX
	MOV DI,AX
	POP DX		;取出列数
	ADD DI,DX
	MOV CX,16
C1:
	MOV DX,3CEH
	MOV AL,8
	MOV AH,DS:[ESI]
	INC SI
	OUT DX,AX
	
	MOV DX,3C4H
	MOV AX,0F02H
	OUT DX,AX
		
	INC DX
	MOV AL,ES:[DI]			;必须先读
	MOV BYTE PTR ES:[DI],0		;回写黑色
	POP AX				;取颜色
	OUT DX,AL			;写颜色
	MOV BYTE PTR ES:[DI],0FFH	;写内存
	CMP AH,0
	JNZ LBL_SHOWHZ1
	MOV AH,1
	PUSH AX
	INC DI
	JMP C1
LBL_SHOWHZ1:
	MOV AH,0
	PUSH AX
	ADD DI,99			;100列
LOOP C1
	POP CX

	POP SI
	POP DI
	POP DX
	POP AX
	POP ES
	RET
SHOWHZ ENDP

;显示一个填充颜色的矩形(102h模式下)
;调用BLOCK过程
;BX 起始行(0——36)
;DX 起始列(0——99)
;AH 行数
;AL 列数
;CL 颜色(0——15)

RECT PROC NEAR
	PUSH AX
	PUSH BX
	PUSH DX

LBL_RECT_ROW:
	CMP AH,0
	JZ  LBL_RECT_EXIT
	PUSH AX
LBL_RECT_COL:
	CMP AL,0
	JZ LBL_RECT_NEXTROW
	CALL BLOCK
	INC DX
	DEC AL
	JMP LBL_RECT_COL
LBL_RECT_NEXTROW:
	POP AX
	POP DX
	PUSH DX
	INC BX
	DEC AH
	JMP LBL_RECT_ROW
LBL_RECT_EXIT:
	POP DX
	POP BX
	POP AX
	RET
RECT ENDP

;102h模式下
;显示一个块(8*16象素)
;BX 行(0——36)
;DX 列(0——79)
;CL 颜色(0——15)
BLOCK PROC NEAR
	PUSH DS
	PUSH AX
	PUSH DI
	PUSH DX
	PUSH CX			
	PUSH DX

	MOV AX,GDT_VRAM_SEL
	MOV DS,AX

	MOV DX,3CEH
	MOV AL,8
	OUT DX,AL

	MOV DX,3CFH
	MOV AL,0FFH
	OUT DX,AL

	MOV DX,3C4H
	MOV AL,2
	OUT DX,AL
	
	MOV AX,100*16			;100列
	MUL BX
	MOV DI,AX
	POP DX
	ADD DI,DX
	
	MOV CX,16
	MOV DX,3C5H
	POP AX
	PUSH AX
	MOV AH,AL
BLOCK1:
	MOV AL,0FH
	OUT DX,AL
	
	MOV AL,[DI]
	MOV BYTE PTR [DI],0
	MOV AL,AH
	OUT DX,AL
	MOV BYTE PTR [DI],0FFH	

	ADD DI,100			;100列
LOOP	BLOCK1
	POP CX
	POP DX
	POP DI
	POP AX
	POP DS
	RET
BLOCK	ENDP

;画一个点
;DS图形方式的段地址
;BX行(0--599)
;DX列(0--799)
;CL颜色(0--15)
;受影响的寄存器有:AX,DI
DOT	PROC
	PUSH CX
	PUSH DX
	XOR DX,DX
	MOV AX,100
	MUL BX
	MOV DI,AX
	
	MOV CH,CL		;暂存颜色

	POP DX
	PUSH DX
	MOV AX,DX
	MOV CL,3
	SHR AX,CL
	ADD DI,AX

	MOV AX,DX
	AND AX,07H
	MOV CL,AL		;第几位
	MOV AL,80H
	SHR AL,CL
	MOV AH,AL

	MOV AL,8		;寄存器索引
	MOV DX,3CEH
	OUT DX,AX

	MOV DX,3C4H
	MOV AX,0F02H
	OUT DX,AX

	INC DX
	MOV AL,[DI]		;必须先读
	MOV BYTE PTR [DI],0	;回写黑色
	MOV AL,CH		;取得颜色
	OUT DX,AL		;写颜色
	MOV BYTE PTR [DI],0FFH  ;写内存

	POP DX
	POP CX
	RET
DOT	ENDP


;画一个点,仅供一些过程用来提高画点速度
;DS图形方式的段地址
;DI点所在内存
;AH屏蔽码
;CL颜色(0--15)
;受影响的寄存器有:AL,DX

DOT1	PROC
	PUSH AX
	PUSH DX
	MOV AL,8		;寄存器索引
	MOV DX,3CEH
	OUT DX,AX

	MOV DX,3C4H
	MOV AX,0F02H
	OUT DX,AX

	INC DX
	MOV AL,[DI]		;必须先读
	MOV BYTE PTR [DI],0	;回写黑色
	MOV AL,CL		;取得颜色
	OUT DX,AL		;写颜色
	MOV BYTE PTR [DI],0FFH  ;写内存

	POP DX
	POP AX
	RET
DOT1	ENDP


;显示图片
;ES:SI图片所在内存区域
;(BX,DX)图片左上角的位置
;BP图片的宽度
;CX图片的高度

SHOW_BMP PROC
	PUSH DS
	PUSH DI
	PUSH SI
	PUSH AX
	PUSH BX
	PUSH DX
	PUSH CX
	
	PUSH BP			;暂存宽度
	PUSH CX			;暂存高度

	PUSH DX			;暂存左上角纵坐标

	XOR DX,DX
	MOV AX,BP
	INC AX
	MUL CX
	ADD SI,AX

	MOV AX,GDT_VRAM_SEL
	MOV DS,AX

	XOR DX,DX
	MOV AX,100
	MUL BX
	MOV DI,AX

	POP DX			;取得左上角纵坐标
	MOV AX,DX
	AND AX,0F8H
	ADD DI,AX

	MOV AX,DX
	AND AX,07H
	MOV CL,AL		;第几位
	MOV AL,80H
	SHR AL,CL
	MOV AH,AL
	POP DX			;取得高度
LBL_BMP_LOOP_H:
	POP BX			;取得宽度
	SUB SI,BX
	SUB SI,BX
	PUSH BX

	PUSH DI			;保存显示点的内存偏移地址
	PUSH AX			;保存屏蔽码
LBL_BMP_LOOP_W:
	MOV CL,ES:[SI]
	CALL DOT1
	INC SI
	ROR AH,1
	CMP AH,80H
	JNZ LBL_BMP_1
	INC DI
LBL_BMP_1:
	DEC BX
	JNZ LBL_BMP_LOOP_W
	POP AX			;取得屏蔽码
	POP DI			;取得显示点的内存偏移地址
	ADD DI,100
	DEC DX
	JNZ LBL_BMP_LOOP_H

	POP BP
	POP CX
	POP DX
	POP BX
	POP AX
	POP SI
	POP DI
	POP DS
	RET
SHOW_BMP ENDP

;06H 中断:画一条横/竖线
;(BX,DX)起始位置
;SI 长度
;CL 颜色
;AL =0 横线
;   =1 竖线
LINE	PROC
	PUSH DS
	PUSH BX
	PUSH DX
	PUSH SI
	PUSH DI

	CMP SI,0
	JZ LBL_LINE_END
	CMP AL,0
	MOV AX,GDT_VRAM_SEL
	MOV DS,AX
	JNZ LBL_LINE_V_GOON
LBL_LINE_H_GOON:
	CALL DOT
	INC DX
	DEC SI
	JNZ LBL_LINE_H_GOON
	JMP LBL_LINE_END
LBL_LINE_V_GOON:
	CALL DOT
	INC BX
	DEC SI
	JNZ LBL_LINE_V_GOON
LBL_LINE_END:

	POP DI
	POP SI
	POP DX
	POP BX
	POP DS
	RET
LINE	ENDP


;07H 中断:显示一个矩形框
;(BX,DX)
;SI 宽
;DI 高
;CL 左上颜色 
;CH 右下颜色
RECT_FRAME PROC
	PUSH BP
	PUSH BX
	PUSH CX
	
	MOV AL,0
	CALL LINE

	MOV BP,SI
	MOV SI,DI
	MOV AL,1
	CALL LINE

	MOV CL,CH
	ADD DX,BP
	CALL LINE

	SUB DX,BP
	ADD BX,DI
	MOV SI,BP
	MOV AL,0
	CALL LINE

	POP CX
	POP BX
	POP BP
	RET

RECT_FRAME ENDP

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -