端口的读写
端口地址范围 0~~65535
命令in out
in al,60h ;从60端口号读入一个字节到al
out 20h,al ;将20h端口的字节输出到al中
端口读写只能使用 al,ax
0~255端口可以直接用立即数访问 256~~~65535端口读写时,端口号放在dx中
mov dx,3f8h
in al,dx
out dx,al
shl 逻辑左移
将一个寄存器或内存单元左移,将最后移出的一位写入CF中,最低位用0补充
如果移动位数大于1 ,必须将移动位数放在cl中
外中断
cpu和外设之间的通信是通过端口传输,cpu通过端口和外部设备进行联系。
外中断源:
1.可屏蔽中断
cpu是否相应可屏蔽中断看标志寄存器IF位的设置。当cpu检测到可屏蔽中断信息时,如果IF=1
则cpu在执行完当前执行后引发中断,如果IF=0 则不响应可屏蔽中断。
2.不可屏蔽中断
在8086中 不可屏蔽中断类型码固定为2 所以不需要取中断类型码。。
不可屏蔽的中断过程为:
1.标志寄存器入栈 if=0 tf=0
2.cs ip 入栈
3.ip=8 cs=0ah
pc机键盘的处理过程
1.键盘输入
2.键盘的输入数据到达60h端口,相关芯片向cpu发出中断类型码为9的可屏蔽中断信息。
如果IF=1则相应中断
3.cpu引发中断
4.执行int9中断例程
编写int9中断例程
;在屏幕中间一次显示'a'~~'z',并且可以让人看清。在显示的过程中,按下esc键后,改变显示的颜色是
assume cs:code
stack segment
db 123 dup(0)
stack ends
data segment
data ends
dw 0,0
code segment
start:
;set the stack
mov ax,stack
mov ss,ax
mov sp,128
;set ds
mov ax,data
mov ds,ax
;set es
mov ax,0
mov es,ax
;将原来的int9中断例程的入口地址存储在ds:0和2中
push es:[9*4]
pop ds:[0]
push es:[9*4+2]
pop ds:[2]
;设置新的中断向量表的入口地址
mov word ptr es:[9*4],offset int9
mov es:[9*4+2],cs
;show the string
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 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
;---------new int9---------------------------
int9:
push ax
push bx
push es
in al,60h
;对int指令进行模拟 调用原来的int9中断例程
pushf ;save the flag0
pushf ;flag1 for the int
pop bx ;to change the flag1
and bh,11111100b ;IF=0 TF=0
push bx ;change the flag1
popf ;restore the flag0
call dword ptr ds:[0] ;use the int
cmp al,1 ;is 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
code ends
end start
;这本书里面的键盘程序要在windows 2000的dos方式下运行实现。
;蛋疼