(2011.11.07) 汇编_王爽_第15章_学习小结

  

(2011.11.07) 汇编_王爽_第15章_学习小结

本章内容:

1. 外中断的概念及应用

2. PC机对键盘的处理过程。

 

|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

 

一。什么是外中断

1. PC向外设的输出也不是直接送入外设,而是先送入端口中,再由相关芯片送到外设。

  即:CPU通过端口和外部设备进行联系。

2. 外中断信息,来源于CPU外部,当CPU外部有需要处理的事情发生时,CPU处理完当前的指令后,可以检测到发送过来的中断信息,引发中断过程,处理外设的输入。

3. 外中断源,分为两种:

第一种是:可屏蔽中断,当IF = 0时不响应可屏蔽中断,IF = 1 则执行完当前指令后响应。

第二种是:不可屏蔽中断,CPU执行完当前指令后必须立即响应。

 

二。 PC机对键盘的处理.

1. 每按下一个键,芯片会产生一个送到主板寄存器端口为60h的扫描码。

2. 通码:按下键时,产生的扫描码。

3. 断码:松开键时,产生的扫描码。

4. 断码 = 通码 + 80h

5. 键盘输入到达60h端口时,CPU会从相关芯片中接到断类型码为9的可屏蔽中断信息。

6. 系统启动后,BIOS键盘缓冲区中,一个字单元存放一个键盘输入,高字节:扫描码,低字节:字符码。

 

三。 CPU对键盘输入的处理过程:

  1. 键盘产生扫描码

2. 扫描码送入60h端口

3. 引发9号中断

4. CPU执行int9中断例程处理键盘输入

 

|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

 

; 程序名称:1504_编写调用BIOS的int 9例程_响应输入的程序.asm
; 程序功能:当输出时遇到Esc的扫描码时,改变显示的颜色后返回

; ------------------------------------------------------------------------------------------------ the whole program start---
assume cs:code

;  -------------------------------------------------------------------------------------------statement start ---
; 段名:ss:stack
; 功能: 用于临时保存各个寄存器的数据
; 大小:共占用了128个字节,即64个字
; ---------statement end------------------------

stack segment
	db 128 dup (0)
stack ends
;-------------------------------------------------------------------------------------------- program end---

; -------------------------------------------------------------------------------------------statement start ---
; 段名: ds:data
; 功能:用于保存int9中断例程的入口地址
; 大小:共占用两个字,即四个字节
; ---------- statement end --------------------------------
data segment
	dw 0, 0
data ends
; ------------------------------------------------------------------------------------------- program end ---

code segment
start:
	mov ax, stack			; 先设置好堆栈的地址
	mov ss, ax			; 让ss:sp指向stack段的末端
	mov sp, 128

	mov ax, data			; 然后设置ds的地址,让其指向data段
	mov ds, ax			; 目的是存放原中断向量表的地址

	mov ax, 0				; 之后是设置es的地址,令es作为段地址可以指向中断向量表
	mov es, ax

	push es:[9*4]			; 将中断向量表中int9的地址放入堆栈中
	pop ds:[0]			; 再将地址取出放入data段中
	push es:[9*4+2]
	pop ds:[2]			; 将原来的int 9中断例程的入口地址保存在ds:0, ds:2单元中

	mov word ptr es:[9*4], offset int9
	mov es:[9*4+2], cs		; 在中断向量表中设置新的int 9中断例程的入口地址

	mov ax, 0b800h		; 将es指向显示缓存区的地址
	mov es, ax
	mov ah, 'a'

s:	
	mov es:[160*12+40*2], ah	; 将设定的字母移到显示缓存区中
	call delay				;  其中调用了delay子程序,目的是让显示延迟
	inc ah
	cmp ah, 'z'
	jna s					; s段的作用是显示字母a~z

	mov ax, 0				; 再次将es设为段地址0,目的是设置中断向量表中的地址
	mov es, ax

	push ds:[0]
	pop es:[9*4]
	push ds:[2]
	pop es:[9*4+2]	; 将中断向量表中int 9中断例程的入口恢复为原来的地址

	mov ax, 4c00h		; 程序返回,程序结束
	int 21h

; --------------------------------------------------------------------------------------------statement start ---
; 子程序名称:delay
; 子程序的功能:不断地执行空循环,目的是时间延迟
; ---------------------statement end ---
delay: 
	push ax
	push dx
	mov dx, 0				   ; 循环次数2X次。
	mov ax, 0

s1:
	inc dx
	add ax, dx
	cmp ax, 1000H			; 此处设置重复的X次
	jne s1
s2:
	dec dx
	cmp dx, 0
	jne s2
	pop dx
	pop ax
	ret
; -----------------------------------------------------------------------------------------------program end ----


; --------------------------------------------------------------------------------------------statement start ---
; 子程序名称:新int 9中断例程段
; 子程序功能:设置新的int9例程,并模拟中断过程。
; 子程序分析:子程序一共分为四大步骤
;			  1. 标志寄存器入栈  2. IF = 0, TF = 0  3. CS、IP入栈 
;			  4. (IP) = ((ds)*16+0), (CS) = ((ds)*16 +2)
; -------------statement end ---------------------------------

int9:	
	push ax
	push bx
	push es

	in al, 60h				; 此处为了引发9号中断
						; 当键盘的输入到达60h端口时
						; 相关的芯片就会向CPU发出中断类型码为9的可屏蔽中断信息
						; 如果IF = 1, 则响应中断,转去执行int9中断例程
	
	pushf				; 此步模拟第1步,标志寄存器入栈
	pushf				; 此处开始第2步,将IF及TF置零
	pop bx				; 将flag寄存器中的数据从堆栈中取出,并且下面进行修改
	and bh, 11111100b		; 将IF和TF置0
	push bx				; 第2 步结。修改以后再将flag寄存器中的数据放回堆栈中
	popf					; 第1步结.
	call dword ptr ds:[0]	; 第3步,CS:IP入栈.对int指令进行模拟,调用原来的int 9中断指令

	cmp al, 1				; 扫描al的值是否为“ESC“的扫描码
	jne int9ret

	mov ax, 0b800h
	mov es, ax
	inc byte ptr es:[160*12+40*2+1]	; 将属性值加1, 改变颜色

int9ret:
	pop es
	pop bx
	pop ax
	iret
; ----------------------------------------------------------------------------------------------------program end ----------------

code ends
end start

; ------------------------------------------------------------------------------------- the whole program end ----------------


 

你可能感兴趣的:(c,汇编,byte,delay)