文章摘要
端口映射I/O是计算机与外部设备(如键盘、打印机)通信的方式,通过为设备分配独立“端口号”(类似快递柜编号或电话分机号),CPU用专门指令(如IN/OUT)访问特定端口实现数据交换。与内存映射I/O不同,端口号独立于内存地址,避免混淆。其核心是“设备靠门牌号区分,CPU按号码通信”,流程简单高效。口诀总结:“设备通信靠门牌,端口编号来分开”。
一、什么是端口映射I/O?
端口映射I/O,也叫端口输入输出,是计算机和外部设备(比如键盘、鼠标、打印机等)之间通信的一种方式。
它的核心思想是:用“门牌号”来区分不同的设备,CPU通过“门牌号”来和设备打交道。
二、生活中的形象比喻
1. 小区快递柜的故事
想象你住在一个大小区,小区门口有一排快递柜,每个柜子都有一个编号(比如101、102、103……)。
快递员送快递时,会把不同的包裹放进不同编号的柜子里。你要取快递时,只需要输入柜子的编号,柜门就会打开,你就能拿到自己的包裹。
- 快递柜编号 = 端口号
- 快递员/你 = CPU
- 包裹 = 数据
- 快递柜 = 外部设备
你只需要知道柜子的编号(端口号),就能和不同的柜子(设备)打交道。
2. 电话分机号
公司有总机,下面有很多分机,每个分机有自己的号码。
你要找某个同事,只需要拨打他的分机号,电话就会接到他那里。
- 分机号 = 端口号
- 同事 = 外部设备
- 你 = CPU
你通过分机号(端口号)和不同的同事(设备)通信。
三、端口映射I/O的工作原理
-
每个设备有自己的端口号
比如,键盘是端口号0x60,打印机是0x378。 -
CPU通过端口号和设备通信
- 想读键盘数据,CPU就“访问”0x60端口。
- 想给打印机发数据,CPU就“写”到0x378端口。
-
端口和内存地址分开
- 端口号就像快递柜的编号,和你家门牌号(内存地址)不一样。
- 这样不会混淆,数据不会送错地方。
-
专门的指令
- CPU有专门的指令(比如x86的IN、OUT),用来读写端口。
四、和“内存映射I/O”的区别
- 端口映射I/O:
设备有独立的“门牌号”(端口号),和内存地址分开。 - 内存映射I/O:
设备直接用一段内存地址,CPU像访问内存一样访问设备。
比喻:
- 端口映射I/O:快递柜有独立编号,和你家门牌号不冲突。
- 内存映射I/O:快递直接送到你家门口(用你家的门牌号)。
五、口诀总结
设备通信靠门牌,
端口编号来分开;
CPU找谁看号码,
数据收发不混淆!
六、简要流程图
- CPU想和设备通信
- 查设备的端口号
- 用IN/OUT指令访问端口
- 设备收到数据或返回数据
下面我用x86汇编为例,给你展示端口I/O的具体指令和操作,并配上形象解释。
一、x86汇编中的端口I/O指令
x86体系结构中,最常用的端口I/O指令是:
IN
:从端口读数据到CPUOUT
:从CPU写数据到端口
指令格式
IN AL, DX
:从端口号为DX的端口读取一个字节到AL寄存器OUT DX, AL
:把AL寄存器里的一个字节写到端口号为DX的端口
二、具体例子
例1:从键盘端口读取数据
假设键盘的端口号是0x60
(十六进制),我们要读取一个字节的数据:
mov dx, 0x60 ; 把端口号0x60放到DX寄存器
in al, dx ; 从端口0x60读取一个字节到AL寄存器
形象解释:
就像你拿着钥匙(端口号0x60),打开快递柜(键盘),取出里面的包裹(数据),放到你的口袋(AL寄存器)里。
例2:向打印机端口发送数据
假设打印机的端口号是0x378
,我们要发送一个字节的数据:
mov dx, 0x378 ; 把端口号0x378放到DX寄存器
mov al, 'A' ; 把字符'A'放到AL寄存器
out dx, al ; 把AL里的数据写到端口0x378
形象解释:
你把要打印的内容(‘A’)装进包裹(AL),走到快递柜0x378(打印机),把包裹放进去(写数据)。
例3:直接用端口号(常数)
有时候端口号很小,可以直接写在指令里:
in al, 0x60 ; 直接从端口0x60读数据到AL
out 0x378, al ; 直接把AL的数据写到端口0x378
三、常见端口号举例
设备 | 端口号(十六进制) |
---|---|
键盘数据端口 | 0x60 |
打印机端口 | 0x378 |
串口COM1 | 0x3F8 |
串口COM2 | 0x2F8 |
四、注意事项
- 端口I/O只能用专门的指令(IN/OUT),不能用普通的内存读写指令。
- 端口号范围通常是0~65535(16位),但大多数设备只用低的几千个端口号。
- 只有特权级高的程序(比如操作系统内核、驱动)才能直接操作端口。
五、口诀总结
端口通信用IN/OUT,
DX寄存器记门号;
AL寄存器装数据,
设备收发全靠它!