我有时会看到这样的说法,在某些平台上,以下 C 或 C++ 代码:
int* ptr;
*ptr = 0;
如果ptr
恰好存储了映射到硬件输入输出端口的地址,则可能导致向该端口写入数据。通常它们被称为“嵌入式平台”。
有哪些实际的这样的平台示例?
我有时会看到这样的说法,在某些平台上,以下 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地址空间的大小(虽然他们确实添加了一次性移动32位数据块的能力)。当x86进入64位领域时,I/O地址空间仍保持在64KB,并且他们甚至没有添加以64位单位移动数据的能力......
此外,请注意,现代桌面和服务器平台(或其他使用虚拟内存的系统)通常不允许应用程序访问I/O端口,无论它们是否是内存映射的。这种访问受到设备驱动程序的限制,即使是设备驱动程序也会有一些操作系统接口来处理物理地址的虚拟内存映射和/或设置DMA访问。
在像嵌入式系统这样的小型系统中,I/O地址通常被应用程序直接访问。对于使用内存映射地址的系统,通常只需设置指向设备I/O端口的物理地址的指针,并像任何其他指针一样使用该指针。然而,为确保访问发生并按正确顺序进行,必须将指针声明为指向volatile
对象。
为了访问使用非内存映射I/O端口(例如x86的I/O地址空间)的设备,编译器通常会提供允许您读取或写入该地址空间的扩展。如果没有这样的扩展,您需要调用汇编语言函数来执行I/O操作。
PlayStation。这就是我们如何获得对系统低级图形(和其他)功能的一些直接优化访问。
它主要用于编写驱动程序,因为大多数外围设备通过内存映射寄存器与主 CPU 通信。
摩托罗拉68k系列和PowerPC是其中的佼佼者。