「这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战」。
外中断
**外中断 (硬中断):**由外部设备(比如网卡,或者硬盘 键盘 鼠标)引发的中断,比如当网卡收到数据包的时候,就会发出一个中断
中断屏蔽:
cpu监听到外部中断时,第一步需要先判断IF标志位的值,如果为1则执行,如果为0则屏蔽
为什么还有中断屏蔽这么一说? 因为有些重复的外部中断并不需要响应,或者cpu正在在执行非常重要的一段指令,这些指令不能中断,一旦中途调开可能会造成系统崩溃,那么在这种情况下需要先将IF标志位置为0,屏蔽所有可屏蔽的外部信号,等这段指令执行完后,再讲IF还原回1, 这个IF标志位相当于是一个监听外部信号的开关
为了方便IF标志位的修改,8086提供了相应的指令方面我们使用
cli ;相当于IF=0
sti ;相当于IF=1
键盘中断
当我们按下键盘中的一个键,那么键盘会向cpu发出一个中断信号,cpu接收到信号后判断标志位IF是否为1,如果为1,则执行这个中断
当松开按键时,同样会发出一个中断信号,也就是说点击一个键实际产生了两个中断信号
以上这一系列过程涉及到几个问题:
1. 键盘是一个外部设备,电信号发出时,cpu怎么知道这个信号是来自键盘而不是鼠标的呢?
2. cpu又如何知道你按下的是哪一个键?
解答1:
cpu除了可以对寄存器 和内存进行数据读写之外,还可以读写端口的数据,电脑上一共有65535个端口,每个端口相当于是一个数据通道,当外部键盘借助USB接口接入电脑被驱动识别后,势必有一个端口与其相连进行数据通信, 在8086中这个端口号为60H
那么如何使用汇编读写端口中的数据呢?
in al,60H ; 使用in指令 从60h这个端口读取一个字节到al寄存器中去
out 60h,al ; 使用out指令 al寄存器中的数据写入60H端口
从端口读写数据必须使用ax或者al寄存器进行交互
解答2:
键盘每个键位所对应的字符都有与之对应的扫描码一一映射,不同厂商键盘硬件对应的扫描码可能不一致,它们最终都会转成相应的ascii码
键位扫描码参考表如下:
| key | mark(Hex)按下 | break(Hex)松开 | 描述 | |
|---|---|---|---|---|
| NumLock | 45 | c5 | break = mark + 0x80 | |
| / | e0 35 | e0 b5 | 由 e0 引导出 extend scan code | |
| * | 37 | b7 | break = mark + 0x80 | |
| - | 4a | ca | 同上 | |
| 7/Home | 47 | c7 | 同上 | |
| 8/Up | 48 | c8 | 同上 | |
| 9/PgUp | 49 | c9 | 同上 | |
| 4/Left | 4b | cb | 同上 | |
| 5 | 4c | cc | 同上 | |
| 6/Right | 4d | cd | 同上 | |
| 1/End | 4f | cf | 同上 | |
| 2/Down | 50 | d0 | 同上 | |
| 3/PgDn | 51 | d1 | 同上 | |
| 0/Ins | 52 | d2 | 同上 | |
| ./Del | 53 | d3 | 同上 | |
| + | 4e | ce | 同上 | |
| Enter | e0 1c | e0 9c | ||
| Scroll Lock | 46 | c6 | 同上 | |
| Pause/Break | e1 1d 45 e1 9d c5 | * | 同上 | |
| Insert | e0 52 | e0 d2 | 同上 | |
| Home | e0 47 | e0 c7 | 同上 | |
| Page Up | e0 49 | e0 c9 | 同上 | |
| Delete | e0 53 | e0 d3 | 同上 | |
| End | e0 4f | e0 cf | 同上 | |
| Page Down | e0 51 | e0 d1 | 同上 | |
| left | e0 46 | e0 c6 | 同上 | |
| right | e0 4d | e0 cd | 同上 | |
| up | e0 48 | e0 c8 | 同上 | |
| down | e0 50 | e0 d0 | 同上 | |
| 01 | 81 | scan code | ||
| F1 | 3b | bb | 同上 | |
| F2 | 3c | bc | 同上 | |
| F3 | 3d | bd | 同上 | |
| F4 | 3e | be | 同上 | |
| F5 | 3f | bf | 同上 | |
| F6 | 40 | c0 | 同上 | |
| F7 | 41 | c1 | 同上 | |
| F8 | 42 | c2 | 同上 | |
| F9 | 43 | c3 | 同上 | |
| F10 | 44 | c4 | 同上 | |
| F11 | 57 | d7 | 同上 | |
| F12 | 58 | d8 | 同上 | |
| ~/· | 29 | a9 | ||
| 0f | 8f | |||
| 3a | ba | |||
| 2a | aa | |||
| !/1 | 02 | 82 | ||
| q | 10 | 90 | ||
| a | 1e | 9e | ||
| z | 2c | ac | ||
| @/2 | 03 | 83 | ||
| w | 11 | 91 | ||
| s | 1f | 9f | ||
| x | 2d | ad | ||
| #/3 | 04 | 84 | ||
| e | 12 | 12 | ||
| d | 20 | a0 | ||
| c | 2e | ae | ||
| $/4 | 05 | 85 | ||
| r | 13 | 93 | ||
| f | 21 | a1 | ||
| v | 2f | af | ||
| %/5 | 06 | 86 | ||
| t | 14 | 94 | ||
| g | 22 | a2 | ||
| b | 30 | b0 | ||
| ^/6 | 07 | 87 | ||
| y | 15 | 95 | ||
| h | 23 | a3 | ||
| n | 31 | b1 | ||
| &/7 | 08 | 88 | ||
| u | 16 | 96 | ||
| j | 24 | a4 | ||
| m | 32 | b2 | ||
| */8 | 09 | 89 | ||
| i | 17 | 97 | ||
| k | 25 | a5 | ||
| </, | 33 | b3 | ||
| (/9 | 0a | 8a | ||
| o | 18 | 98 | ||
| l | 26 | a6 | ||
| >/. | 34 | b4 | ||
| )/0 | 0b | 8b | ||
| p | 19 | 99 | ||
| :/; | 27 | a7 | ||
| ?// | 35 | b5 | ||
| _/- | 0c | 8c | ||
| {/[ | 1a | 9a | ||
| "/' | 28 | a8 | ||
| 36 | b6 | |||
| +/= | 0d | 8d | ||
| }/] | 1b | 9b | ||
| 1c | 9c | |||
| 1d | 9d | |||
| |/\ | 2b | ab | ||
| 38 | b8 | |||
| 0e | 8e | |||
| 39 | b9 |
如果是控制键ctrl shift 则将其转变成状态字节, 记录到0040:0017这个内存空间中,也就是说当我们按下控制键 这个位置的数据会发生相应的改变
磁盘读写
- 概念
磁盘构造:
一面=80个磁道
一个磁道=18个扇区
一个扇区=512byte
-
中断
使用13H号中断
;读取磁盘中的数据到0:200H这个内存中 mov ax,0 mov es,ax mov bx,200h mov al,1 ;读取的扇区数 mov ch,0 ;磁道号 mov cl,1 ;扇区号 mov dl,0 ;驱动器号 软驱a, b mov dh,2 ;面号 mov ah,2 ;2表示读取 3表示写入 int 13H ;将0:200H这个内存中数据写入软盘 mov ax,0 mov es,ax mov bx,200h mov al,1 ;读取的扇区数 mov ch,0 ;磁道号 mov cl,1 ;扇区号 mov dl,0 ;驱动器号 软驱a, b mov dh,2 ;面号 mov ah,3 ;写入 int 13H