扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
pc 系统的接口卡和主板上,装有各种接口芯片。这些外设接口芯片内部有若干寄存器,cpu将这些寄存器当作端口来访问。
我们提供的服务有:成都网站设计、网站制作、外贸营销网站建设、微信公众号开发、网站优化、网站认证、呼图壁ssl等。为1000+企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的呼图壁网站制作公司cpu通过端口和外部设备进行联系。
15.2 外中断信息来自外部的中断信息
外部中断原有两类:
第一类:可屏蔽中断源cpu是否响应中断要看标志寄存器。if=1的话,执行完当前指令后去响应中断。if=0的话,不响应中断。
内中断的过程:
(1)取中断类型码n
(2)标志寄存器入栈,if=0,tf=0
(3)cs、ip入栈
(4)(ip)=(n*4),(cs)=(n*4+2)
if=0就是为了屏蔽其他的可屏蔽中断
指令:
sti ;if=1
cli ;if=0
第二类:不可屏蔽中断cpu必须响应。
8086cpu不可屏蔽终端类型码固定为2,所以屏蔽过程中不需要取中断类型码。
过程:
(1)标志寄存器入栈,if=0,tf=0
(2)cs ip入栈
(3)(ip)=(8),(cs)=(0ah)
15.3pc键盘的处理过程键盘中每个按键相当于一个开关,键盘中有一个芯片对键盘上的每一个键的开关状态进行扫描。
按下一个键时,开关接通,芯片会产生一个扫描码,扫描码说明了按下的键在键盘上的位置。扫描码被送入主板上的相关接口芯片的寄存器中,该寄存器的端口地址为60h
松开按下的键时,也会产生一个扫描码,扫描码说明了松开的键在键盘上的位置,松开按键时产生的扫描码也会被送入60h端口中。
一般按下键盘时的扫描码被叫做通码,松开时的扫描码叫做断码。扫描码长度为一个字节,通码第7位为0,断码第七位为1
就是:
断码=通码+80h
键盘的输入到达60h端口时,相关的芯片就会向cpu发出中断类型码为9的可屏蔽中断信息。
cpu检测到该中断信息后,如果if=1,则响应中断,引发中断过程,转去执行int9中断例程
(BIOS)系统板的ROM(只读内存)中放有一套程序,称为BIOS(基本输出输入系统)
BIOS提供了int9 的中断例程,用来进行键盘的读取和输出。
:(1)读出60h端口中的扫描码
(2)如果是字符键的扫描码,将该扫描码和它所对应的字符码(ascll)送入内存(一个字节加一个字节=一个字),=中的BIOS键盘缓冲区,如果是控制键的扫描码,则将其转化成状态字节(用二进制记录控制键和切换键状态字节)写入内存中储存状态字节的单元(内存单元)。
(3)对键盘系统进行相关的控制,比如像向芯片发出应答信息
BIOS键盘换缓冲区是系统启动后,BIOS用于存放int9 中断例程所接受的键盘输入的内存区。该内存区可以存储15个键盘输入(15个字型数据),因为int9 中断例程除了接收扫描码外还要产生扫描码对应的字符码,所以在BIOS键盘缓冲区中,一个键盘输入用一个字单元存放,高位存放扫描码,低位存放字符码(ascll)。
assume cs:code,ds:data,ss:stack
data segment
db 128 dup(0)
data ends
stack segment stack
db 128 dup(0)
stack ends
code segment
start: mov ax,stack
mov ss,ax
mov sp,128
call init_reg
call show_keywordstatus
mov ax,4C00h
int 21h
;===============================
init_reg: mov bx,0B800h
mov es,bx
mov bx,40h
mov ds,bx
ret
;====================================
show_status: push cx
push dx
push ds
push es
push si
push di
mov cx,8
showstatus: mov dx,0
shl al,1
adc dx,30h
mov es:[di],dl
add di,2
loop showstatus
pop di
pop si
pop es
pop ds
pop dx
pop cx
ret
;===========================
show_keywordstatus:
mov si,17h
testA:
mov di,160*10+40*2
mov al,ds:[si]
call show_status
jmp testA
ret
code ends
end start
15.4 编写int9中断例程键盘的输入处理过程:
键盘产生扫描码
扫描码送入60h端口
引发9号中断
cpu执行int9中断例程处理键盘输入
编程:在屏幕中依次显示'a'~'z' esc后改变颜色。
由于cpu执行速度太快,所以要在每一次输入后都进行好多次循环来延迟时间。
assume cs:code
stack segment
db 128 dup (0)
stack ends
code segment
start:mov ax,stack
mov ss,ax
mov sp,128
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,4c00h
int 21h
delay:push ax
push dx
mov dx,10h
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
code ends
end start
改变颜色
那个咱就是说代码一定不要放到vscode的安装目录中
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] ;将原来的int9中断例程,的入口保存在ds:0、ds:2中
cli
mov word ptr es:[9*4],offset int9
mov es:[9*4+2],cs ;在中断向量表中设置新的int9 中断例程的入口地址
sti
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] ;将中断向量表中int9中断例程的入口恢复为原来的地址
mov ax,4c00h
int 21h
delay: push ax
push dx
mov dx,10h
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
;======================================
int9: push ax
push bx
push es
in al,60h ;从端口60h读取键盘的输入数据
;原来的int调用是(取中断码类型)->(标志寄存器入栈)->(if=0,tf=0)->(cs、ip入栈)->(ip=n*4,cs=n*4+2)
;我们将地址放到ds中,所以第一步可省,那么就剩(标志寄存器入栈)->(if=0,tf=0)->(cs、ip入栈)->(ip=n*4,cs=n*4+2)
;(cs、ip入栈)->(ip=n*4,cs=n*4+2)==call dword ptr ds:[0]
;那么就剩(标志寄存器入栈)->(if=0,tf=0)->call dword ptr ds:[0]三步
;
;
pushf ;标志寄存器入栈
; pushf
; pop bx
; and bh,11111100b ;标志寄存器if=tf=0
; push bx
; popf
call dword ptr ds:[0] ;模拟int指令,调用原来的int9中断例程
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
15.5安装新的int9中断例程序按下F1后屏幕颜色改变
大概思路就是先将自己写好的int9机器码复制粘贴到0:204
需要先将老int9的csip存到0:200
然后改变中断信息表int9为新的int9的csip
新的int9中会使用call调用老的int9
然后进行判断如果是某个键就进行啥啥
其实就是在原来的int9前边加了一点东西
assume cs:code
stack segment stack
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
实验15 安装新的int9中断例程按下“A”后除非不松开,只要松开就出现满屏的"A"
直接根据前边那个改的
先将老int9挪到一边,在新得int9中用call调用老int9
新的int9可以在调用之后加一些功能
assume cs:code
stack segment stack
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,1eh+80h
jne int9ret
mov ax,0b800h
mov es,ax
mov bx,0
mov cx,2000
s: mov byte ptr es:[bx],'A'
add bx,2
loop s
int9ret:pop es
pop cx
pop bx
pop ax
iret
int9end:nop
code ends
end start
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流