我有时会在某些平台上看到以下 C 或 C++ 代码的语句:
int* ptr;
*ptr = 0;
可能会导致写入硬件输入输出端口,如果ptr
恰好存储了该端口映射到的地址。通常它们被称为“嵌入式平台”。
此类平台的真实例子有哪些?
根据我的经验,大多数系统都使用内存映射 I/O。 x86 平台有一个独立的、非内存映射的 I/O 地址空间(使用in
/out
处理器操作码系列),但 PC 架构还广泛使用设备 I/O 的标准内存地址空间,它具有更大的地址空间、更快的访问(通常)和更容易的编程(通常)。
我认为最初使用单独的 I/O 地址空间是因为处理器的内存地址空间有时非常有限,使用其中的一部分进行设备访问没有什么意义。一旦内存地址空间开放到兆字节或更多,将 I/O 地址与内存地址分开的原因就变得不那么重要了。
我不确定有多少处理器像 x86 那样提供单独的 I/O 地址空间。作为单独 I/O 地址空间如何失宠的一个迹象,当 x86 架构进入 32 位领域时,没有采取任何措施将 I/O 地址空间从 64KB 增加(尽管他们确实增加了能力)在一条指令中移动 32 位数据块)。当 x86 进入 64 位领域时,I/O 地址空间仍为 64KB,甚至没有添加以 64 位单元移动数据的能力……
另请注意,现代桌面和服务器平台(或使用虚拟内存的其他系统)通常不允许应用程序访问 I/O 端口,无论它们是否是内存映射的。该访问仅限于设备驱动程序,甚至设备驱动程序也会有一些操作系统接口来处理物理地址的虚拟内存映射和/或设置 DMA 访问。
在较小的系统(如嵌入式系统)上,I/O 地址通常由应用程序直接访问。对于使用内存映射地址的系统,通常只需使用设备 I/O 端口的物理地址设置一个指针,然后像使用其他指针一样使用该指针即可完成此操作。但是,为了确保访问发生并且以正确的顺序发生,必须将指针声明为指向volatile
object.
要访问使用内存映射 I/O 端口以外的设备(例如 x86 的 I/O 地址空间),编译器通常会提供一个扩展,允许您读取或写入该地址空间。如果没有这样的扩展,您需要调用汇编语言函数来执行 I/O。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)