9

我有时会在某些平台上看到以下 C 或 C++ 代码的声明:

int* ptr;
*ptr = 0;

ptr如果碰巧存储了该端口映射到的地址,则可能导致写入硬件输入-输出端口。通常它们被称为“嵌入式平台”。

这些平台的真实例子是什么?

4

8 回答 8

12

根据我的经验,大多数系统都使用内存映射 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对象。

要访问使用非内存映射 I/O 端口(如 x86 的 I/O 地址空间)的设备,编译器通常会提供一个扩展,允许您读取或写入该地址空间。如果没有这样的扩展,您需要调用汇编语言函数来执行 I/O。

于 2010-12-02T19:05:30.303 回答
2

这称为内存映射 I/O,一个很好的起点是Wikipedia 文章

除非您正在编写驱动程序,否则现代操作系统通常会保护您免受这种情况的影响,但这种技术甚至在 PC 架构上也很重要。还记得 DOS 640Kb 的限制吗?这是因为为 I/O 分配了从 640K 到 1Mb 的内存地址。

于 2010-12-02T10:27:24.730 回答
1

游戏机。这就是我们如何直接优化访问系统的低级图形(和其他)功能的方式。

于 2010-12-02T10:26:01.553 回答
1

Windows 上的 NDIS驱动程序就是一个示例。这称为内存映射 I/O,这样做的好处是性能。

于 2010-12-02T10:28:50.447 回答
1

有关使用内存映射 I/O 的设备示例,请参阅嵌入式系统,例如路由器、adsl 调制解调器、微控制器等。

于 2010-12-02T10:31:30.393 回答
1

它主要用于编写驱动程序,因为大多数外围设备通过内存映射寄存器与主 CPU 通信。

于 2010-12-02T10:37:18.930 回答
0

摩托罗拉 68k 系列和 PowerPC 是其中的佼佼者。

于 2010-12-02T10:28:55.167 回答
-2

您可以在现代 Windows 中执行此操作(我很确定 Linux 也提供了它)。它被称为内存映射文件。您可以在 Windows 上将文件加载到内存中,然后仅通过操作指针来写入/更改它。

于 2010-12-02T19:17:51.870 回答