汇编第十五节-外中断

第15节:外中断

CPU在计算机系统中,除了能够执行指令运算外,
还应该对外部设备进行控制,接受它们的输入,向它们进行输出。
I/O需解决2个问题:
1.外设的输入随时可能发生,CPU如何得知?
2.CPU从何处得到外设的输入?

1.接口芯片和端口:

外设的输入不直接送入内存和CPU,而是送入相关的接口芯片和芯片的端口中。
CPU向外设的输出也不是直接接入外设,而是先送入端口中,再由相关的芯片送到外设。
CPU<–>端口<–>外设

2.外中断信息:

外设的输入随时可能发生,CPU如何得知并进行处理?—>中断机制
外中断源分类:
a.可屏蔽中断
CPU可以不响应的外中断。CPU是否响应可屏蔽中断,要看标志寄存器IF位的设置。
当CPU检测到可屏蔽中断信息时,如果IF=1,则CPU在执行完当前指令后响应中断,引发中断过程。
IF=0,则不响应可屏蔽中断。

1.标志寄存器入栈,IF=0,TF=02.CS,IP入栈
3.(IP)=(n*4),(CS)=(n*4+2)

将IF置0的原因就是,在进入中断处理程序后,禁止其他的可屏蔽中断。

if在中断处理程序中需要处理可屏蔽中断,可以用指令将IF置1。8086CPU提供的指令是:
sti,设置IF=1
cli,设置IF=0

b.不可屏蔽中断
CPU必须响应的外中断。当CPU检测到不可屏蔽中断信息时,则在执行完当前指令后,立即响应,引发中断过程。
8086中不可屏蔽中断类型码固定为2,所以中断过程,不需要取中断类型码

1.标志寄存器入栈,IF=0,TF=0;
2.CS,IP入栈
3.(IP)=(8),(CS)=(0AH)

(几乎所有由外设引发的外中断,都是可屏蔽中断。)

3.PC机键盘的处理过程:

a.键盘输入:
键盘键(开关)——>按下键(通码)——>产生扫描码(松开的键在键盘的位置)——>松开(断码)——>产生的扫描码也送入60h端口中
扫描码长度为1个字节,通码的第7位为0,断码的第7位为1
断码=通码+80h
eg:g键的通码为22h,断码为a2h
b.引发9号中断:
到达60h端口——>芯片向CPU发出中断类型码为9的可屏蔽中断信息——>IF=1,则响应中断——>转去执行int9中断例程
c.执行int9中断例程:
BIOS提供了int9中断例程,用来进行基本的键盘输入处理

1.读出60h端口中的扫描码
2.字符键扫描码——>扫描码和对应的ASCII送入BIOS键盘缓冲区
      控制键(ctrl..)和切换键(Capslock..)扫描码——>状态字节写入内存中存储状态字节单元
3.对键盘系统进行相关的控制,eg向相关芯片发出应答信息

BIOS键盘缓冲区是系统启动后,BIOS用于存放int 9中断例程所接收的键盘输入的内存区。
该内存区可以存储15个键盘输入,一个键盘输入用一个字单元存放,高位字节存放扫描码,低位字节存放字符码。

0040:17单元存储键盘状态字节,
该字节记录了控制键和切换键的状态。键盘状态字节各位信息的如下:

0: 右shift状态,置1表示按下右shift键;
1: 左shift状态,置1表示按下左shift键;
2: Ctrl状态,置1表示按下ctrl键;
3: Alt状态,置1表示按下alt键;
4: Scrollock状态,置1表示scroll指示灯亮;
5: NumLock状态,置1表示小键盘输入的是数字;
6: CapsLock状态,置1表示输入大写字母;
7: Insert状态,置1表示处于删除状态;

4.编写int 9中断例程:

键盘输入的处理过程:

a.键盘产生扫描码 
b.扫描码送入60h端口
c.引发9号中断 
d.CPU执行int 9中断例程处理键盘输入

a,b,c都是由硬件系统完成的。我们只能改变的只有int 9中断例程处理程序。

编程:在屏幕中间依次显示‘a’~’z’,并可以让人看清。在显示的过程中,按下Esc键后,改变显示的颜色

assume cs:code
stack segment
    db 128 dup(0)
stack ends

data segment
    dw 0,0
data ends

code segment
start:  mov ax,stack
        mov ss,ax
        mov sp,128

        mov ax,data
        mov ds,ax

        mov ax,0
        mov es,ax

        push es:[9*4]
        pop ds:[0]
        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   ;在中断向量表中设置新的int9中断例程的入口地址

        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]      ;将中断向量表中int 9中断例程的入口恢复到原来的地址

        mov ax,4c00h
        int 21h

  delay:push ax
        push dx
        mov dx,1000h
        mov ax,0
    s1: sub ax,1
        sbb dx,0
        cmp ax,0
        jne s1
        cmp dx,0
        jne s1
        pop dx
        pop ax
        ret
;-----------以下为新的int 9中断例程----------------
  int9: push ax
        push bx
        push es

        in al,60h

        pushf
        pushf
        pop bx
        add bh,11111100b
        push bx
        popf
        call dword ptr ds:[0]       ;对int指令进行模拟,调用原来的int 9中断例程

        cmp al,1
        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

code ends
end start

5.安装新的int 9中断例程:

任务:安装一个新的int9中断例程
功能:在dos下,按f1键后改变当前屏幕的显示颜色,其他的键照常处理
1.改变屏幕的显示颜色:
2.其他键照常处理
3.原int9中断例程入口地址的保存
4.新int9中断例程安装
将int9中断例程安装在0:204处

assume cs:code
stack segment
    db 128 dup(0)
stack ends
code segment
 start: mov ax,stack
        mov ss,ax
        mov sp,128

        push cs
        pop ds

        mov ax,0
        mov es,ax

        mov si,offset int9
        mov di,204h
        mov cx,offset int9end-offset int9
        cld
        rep movsb

        push es:[9*4]
        pop es:[200h]
        push es:[9*4+2]
        pop es:[202h]

        cli
        mov word ptr es:[9*4],204h
        mov word ptr es:[9*4+2],0
        sti

        mov ax,4c00h
        int 21h

  int9: push ax
        push bx
        push cx
        push es

        in al,60h

        pushf
        call dword ptr cs:[200h]

        cmp al,3bh
        jne int9ret

        mov ax,0b800h
        mov es,ax
        mov bx,1
        mov cx,2000
    s: inc byte ptr es:[bx]
        add bx,2
        loop s
int9ret:pop es
        pop cx
        pop bx
        pop ax
        iret
int9end:nop

code ends
end start

指令系统总结:

1.数据传送指令
mov push pop pushf popf xchg //实现寄存器和内存,寄存器和寄存器之间的单个数据传送
2.算术运算指令
add sub adc sbb inc dec cmp imul idiv aaa//实现寄存器和内存中数据的算数运算。
执行结果影响标志寄存器sf,zf,of,cf,pf,af位
3.逻辑指令
and or not xor test shl shr sal rol ror rcl rcr //除了not指令外,执行结果都影响标志寄存器的相关标志位
4.转移指令
jmp jcxz je jb ja jnb jna loop call ret retf int iret 
5.处理机控制指令
cld std cli sti nop clc cmc stc hlt wait esc lock//指令对标志寄存器或其他处理机状态进行设置
6.串处理指令
movsb movsw cmps scas lods stos //对内存中批量数据进行处理,若要使用这些指令方便进行批量数据的处理,则需要和rep repe repne等前缀指令配合使用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值