外中断。
cpu在计算机系统中,除了能够进行执行指令,进行运算外,还能对外部设备进行控制。当然cpu要进行及时的处理外设的输入,要必然的去解决两个问题: 外设输入随时都可能发生,cpu如何得知?
cpu从何处得到输入响应?
接口芯片和端口。
我们知道了在接口卡和主板上装有各种接口芯片。在这些芯片的内部也会有相当多的寄存器,cpu就是将这些寄存器当做端口来进行访问的。
外中断信息。
cpu通过提供中断机制来进行处理中断信息,以前我们了解了内部中断信息如何进行处理,其实也有一种中断信息来自cpu外部,也能引发cpu的中断。外部中断有两种类型:
可屏蔽中断和非可屏蔽中断,可屏蔽中断就是cpu可以不响应的中断(发生了也相当于每发生↖(^非可屏蔽中断就是cpu不得不去处理的中断了。其实cpu是否去处理中断信息取决于标志寄存器if的设置,当cpu检测到中断信息的时候,如果if=1,那么cpu在执行完当前的指令后就会响应中断,引发中断过程,如果if=0,那么cpu就不会响应中断。
好吧那么还记得内中断的过程么?
住中断类型码 n
标志寄存器入栈 if=0,tf=0
cs ip入栈。
cs ip取得中断类型码入口地址。
这样cpu就去处理中断程序了。
可屏蔽中断的引发过程除了第一步和内中断的引发不一样外,基本上和内中断差不多,主要是不可屏蔽中断的信息来自cpu外部。中断类型码是通过数据总线送入到cpu的,这样我们就可以理解在cpu处理中断过程中会将if=0了,这样cpu在进入处理中断程序的时候就不会再去响应其他的中断信息了,这样就屏蔽了其他的中断了,当然我们可以通过指令来控制if的信息来让cpu随时随地都响应我们想要的可屏蔽中断信息,sti 用于设置if=1 cli用于设置if=0
当cpu遇到不可屏蔽中断的时候,执行完当前的指令后会立即去处理中断信息。对于x86cpu不可屏蔽中断的中断类型码固定为2,所以不可屏蔽中断不需要进行取中断类型码。
其实几乎多有的有外设引发的终端都是可屏蔽中断,不可屏蔽中断是在系统中又必须处理的紧急情况发生的时候用来通知cpu的中断信息。
pc机的键盘处理过程。
键盘上的每一个键都相当于一个开关,当我们把它按下去的时候,开关就相当于接通了,这时会产生一个扫描码,扫描码说明了按下间的位置,伺候扫描码就被送入了主板上的相关接口芯片上的寄存器中了,该类寄存器的端口地址位60h,当键松开的时候,会产生一个扫描码此时是断码,也将会送到相应的寄存器里边去,端口同样是60h,扫描码长度为一个字节,通码的第7位是0.断码的第7位是1,所以。
断码=通码+80h
键盘的输入到达60h号端口的时候,相关的芯片回想cpu发出中断类型为9的可屏蔽中断,cpu管不管响应就要看if的标志了,要是if=1那么cpu就去执行int 9中断例程。
int9中断例程。
bios提供的,用来执行基本的输入输出处理,工作原理:
读出60h的扫描码。
如果是字符扫描码那么,该扫描码和对应的字符码(asc11码)就被送入键盘输入缓冲区,该区可以存放15个键盘输入。当然要是是状态扫描码例如(crtl键等)就将扫描码转换成对应的状态字节。
在键盘缓冲区一个键盘输入有一个字单元存放,高位字节存放扫描码,低位字节存放字符码。
编写int 9中断例程。
基本上键盘的处理过程如下:
键盘产生扫描码。
扫描码送入60h号端口。
引发int9中断。
cpu响应中断,进行处理。
在上面的处理过程中,头三步是由硬件系统完成的,我们能控制的就是第四步--改写int9程序例程。我们可以按照自己的意图来进行处理键盘的输入,编程题如下。
在屏幕中间依次显示a--z子u,并可以看清,显示过程中按下esc键后,改变现实的颜色。
这个题目我们会分开几步去做。
首先我们清楚现在cpu处理速度是相当快的,所以若是我们仅仅进行字符显示,那么屏幕的显示速度远远超过了我们眼睛的分辨率,所以我们会在程序中加入一段空循环,来隔开字符的显示,降低分辨率:
assume cs:code ,ss:stack
stack segment
db 128 dup(?)
stack ends
code segment
start: mov ax,0b800h
mov es,ax
mov ah,'a'
s: mov es:[160*12+40*2],ah
inc ah
call delay
cmp ah,'z'
jna smov ax,4c00h
int 21h
delay: push ax
push dx
mov ax,0ffffh
mov dx,0f000h
ok: sub ax,1
sbb dx,1
cmp ax,0
je return
jmp short ok
return: pop dx
pop ax
ret code ends
end start
接下来我们就要进行按键时改变颜色了。
cpu首先从60h端口读出键盘的输入;
调用bios的int中断例程处理其他硬件细节。
进行判断是不是esc键如果是那么就进行改变自己节颜色。
首先从端口60h读出键盘的输入。
接下来进行bios的int9中断例程的调用。
额弱弱地说又要改变中断向量表了,还是那么做首先要将 0*4和0*4+2两个字单元的内容改写成我们想要安装的地址,不过。
将中断向量表改写之后那么以后的新的中断程序调用int9时就不执行原来正常的功能了。所以我们要将0*4和0*4+2的内容保存到一个地方,当我们程序结束之前要进行将原来的内容再次保存到原来的地方。我们可以在数据段中敌营两个字单元来存放中断向量信息,接下来我们就要考虑将 if和tf置0我们可以利用and指令将相应的位改变。
程序段如下。
pushf
psuhf
pop ax
and ah,11111100b;我们清楚if和tf分别是标志寄存器的第8和9位。
push ax
popf这样我们就将if和tf置零了。
好吧最后一步--进行设置按下esc键后改变显示颜色。
首先我们要了解所说的屏幕中间就是第12行40列显存中的偏移地址:160*12+40*2就是字符的asc11码要送入这个地址,我们更要知道 0b800h:160*12+40*2+1处是字符的属性我们要改变此处的数据就行了。
好吧完整的程序如下。
assume cs:code
stack segment
db 128 dup(?)
stack ends
data segment
dw 2 dup(?)
data ends
code segment
start: mov ax,stack
mov ss,ax
mov sp,128
mov ax,data
mov ds,ax
将中断例程地址保存到数据段字单元中。
push es:[9*4]
pop ds:[0]
push es:[9*4+2]
pop ds:[2]
将新的int9例程入口地址写入中断向量表。
mov word ptr es:[9*4],offset int9
mov word ptr es:[9*4+2],cs
字符显示程序。
mov ax,0b800h
mov es,ax
mov ah,'a'
s: mov es:[160*12+40*2],ah
call delay
inc ah
cmp ah,'z'
jna s显示完毕后要将原来的而中断向量写入原来的地址。
mov ax,0
mov es,ax
push ds:[0]
pop es:[9*4]
push ds:[2]
pop es:[9*4+2]
mov ax,4c00h
int 21h
延时程序。delay: push ax
push dx
mov ax,0ffffh
mov dx,0ffffh
ok: sub ax,1
sbb dx,1
cmp ax,0
jne ok
cmp dx,0
jne ok
pop dx
pop ax
ret新的int9中断例程。
int9: push ax
push bx
push es
检测检测键盘输入。
in al,60h
pushfpushf
pop bx
and bh,11111100b
push bx
popfcall word ptr ds:[0]
cmp al,1
jne int9ret
mov ax,0b800h
mov es,ax
inc byte ptr es:[160*12+40*2+1]
int9ret:pop es
pop bx
pop ax
iret code ends
end start
额的神来。。程序就是这样了不过弱弱地说是不是cpu处理速度太快,导致一运行程序立马就在屏幕上显示'z'其他的基本上看不到,更不用去试试按下esc键了。希望技术大牛们帮助检测一下,,谢谢咯。。。
朋友的**,注册下哈。。
c语言学习笔记
一元二次方程详解。不管我们写什么样的程序,首先要建起构架。c语言的构架是 include intmain void 我们首先需要把三个系数保存到电脑里面,怎么保存呢?我们会以变量的形式保存到电脑里面。比如说 inta 1 intb 2 intc 3 这个 的意思是赋值的意思,不是相等的意思。什么叫变...
C语言学习笔记
a.1.需要成对敲入的符号。2.文件名不要出现。号,否则无法生成。c或。cpp文件,所以不能编译和运行。3.分号 代表一个语句,只有一个 的语句是空语句,所以下面的 不会报错,但表示若条件成立只执行空语句,并且条件语句结束 if a b 等价于 if a b 空语句。4.格式化输出中,建议用 x输出...
C语言学习笔记
求余 求mod 运算符。变量命名规则 只能以字母数字下划线三种字符组成,且第一个字符必须为字母或下划线。scanf d a prindf d a c语言中,变量名是区分大小写的。int 范围 32768 32768 float的指数部分有8bit 2 8 由于是有符号型,所以得到对应的指数范围 12...