我只想确定我没弄错
当我在x86中使用IN和OUT指令时。
CPU将端口地址发送到正确的I/O控制器,它如何知道哪一个是正确的?它通过查找I/O地址空间来知道,I/O地址空间基本上包含与I/O控制器对应的端口地址范围。
假设端口地址0x 1000 - 0x 2000用于“磁盘控制器”
和端口地址0x 3000 - 0x 4000表示“网络控制器”
如果我发送端口地址0x 1003,那么CPU将发送端口地址到“磁盘控制器”。
则I/O控制器接收该端口地址,然后在其存储器中查找其内部Map表,以确定I/O设备的哪个寄存器(也可以是存储器)与该端口地址相关联。
则它请求对这些I/O设备寄存器之一进行读或写(取决于指令)。
1条答案
按热度按时间igsr9ssn1#
如果我发送端口地址0x1003,那么CPU将发送端口地址到“磁盘控制器”。
您对
in
和out
工作原理的理解并不完全正确:我不了解现代CPU,但使用更简单的CPU(如80386),
in
和out
是mov
指令访问不同地址的变体:如果您将
M/IO
引脚视为额外的地址线,则地址是33位值,而不是32位值。指令
out dx, al
与mov [edx], al
的功能完全相同,只有一点不同:out dx, al
写入到(33位)地址[0x100000000+dx]
,而mov [edx], al
写入到地址[edx]
。在这种情况下,CPU会做什么?
CPU使用33根线(地址总线)发送地址,8根线(数据总线)发送
al
的值,并使用额外的线发送正在写入某个8位值的信息。CPU外部有一些电路,用于检查哪个地址是哪个设备:
此电路“知道”地址
0...0x9FFFF
是RAM,当您写入其中一个地址时(例如,您使用mov [0x1234],al
写入地址0x1234
),电路向RAM发送电信号。如果您写入地址
0x100001234
(例如,将out dx, al
与dx=0x1234
一起使用),电路会向磁盘控制器发送一些信号(在您的示例中)。假设磁盘控制器仅使用地址
0x1000...0x10FF
(实际上:x1米20英寸1x)。在这种情况下,磁盘控制器通常只使用地址的低8位,而忽略其他地址位。因此,如果您写入地址
dx=0x11FF
,这与写入地址dx=0x10FF
具有相同的效果。在这种情况下,保持来自CPU的地址的33个信号中只有8个需要连接到盘控制器。
磁盘控制器接收以下信号:
al
值的8个信号(来自CPU)