Большинство систем в моем опыте используют отображение ввода-вывода с отображением в памяти. Платформа x86 имеет отдельное, не отображаемое в памяти адресное пространство ввода / вывода (которое использует семейство процессорных операционных кодов in
/ out
), но архитектура ПК также широко использует стандартное адресное пространство памяти для устройства Ввод / вывод, который имеет большее адресное пространство, более быстрый доступ (как правило) и более простое программирование (в целом).
Я думаю, что отдельное адресное пространство ввода-вывода использовалось изначально, потому что адресное пространство памяти процессоров иногда было довольно ограниченным, и не имело смысла использовать его часть для доступа к устройству. Как только адресное пространство памяти было открыто до мегабайт или более, причина отделения адресов ввода-вывода от адресов памяти стала менее важной.
Я не уверен, сколько процессоров предоставляют отдельное адресное пространство ввода / вывода, как в x86. В качестве указания на то, как раздельное адресное пространство ввода / вывода вышло из строя, когда архитектура x86 перешла в 32-разрядную область, ничего не было сделано для увеличения адресного пространства ввода / вывода с 64 КБ (хотя они добавили возможность переместить 32-битные порции данных в одну инструкцию). Когда x86 перешел в 64-разрядную область, адресное пространство ввода-вывода осталось на уровне 64 КБ, и они даже не добавили возможность перемещать данные в 64-разрядных единицах ...
Также обратите внимание, что современные настольные и серверные платформы (или другие системы, использующие виртуальную память), как правило, не позволяют приложению получать доступ к портам ввода-вывода, независимо от того, сопоставлены они с памятью или нет. Этот доступ ограничен драйверами устройств, и даже драйверы устройств будут иметь некоторый интерфейс ОС для работы с отображениями виртуальной памяти физического адреса и / или для настройки доступа DMA.
В небольших системах, таких как встроенные системы, адреса ввода-вывода часто доступны непосредственно приложению. Для систем, которые используют адреса, отображаемые в памяти, это обычно делается путем установки указателя с физическим адресом порта ввода-вывода устройства и использования этого указателя, как и любого другого. Однако, чтобы гарантировать, что доступ происходит и происходит в правильном порядке, указатель должен быть объявлен как указывающий на объект volatile
.
Чтобы получить доступ к устройству, которое использует что-то иное, чем порт ввода-вывода с отображением в памяти (например, адресное пространство ввода-вывода x86), компилятор обычно предоставляет расширение, которое позволяет вам читать или записывать в это адресное пространство. В отсутствие такого расширения для выполнения операций ввода-вывода вам потребуется вызвать функцию на языке ассемблера.