Для чего используются инструкции IN & OUT в x86? - PullRequest
50 голосов
/ 09 июля 2010

Я принял это к инструкциям IN & OUT, читая книгу «Понимание ядра Linux» Я посмотрел справочное руководство.

5.1.9 Инструкции ввода / вывода

Эти инструкции перемещают данные между порты ввода-вывода процессора и регистр или память.

IN    Read from a port
OUT   Write to a port
INS/INSB  Input string from port/Input byte string from port 
INS/INSW  Input string from port/Input word string from port 
INS/INSD  Input string from port/Input doubleword string from port
OUTS/OUTSB    Output string to port/Output byte string to port 
OUTS/OUTSW    Output string to port/Output word string to port 
OUTS/OUTSD    Output string to port/Output doubleword string to port

Я не получил несколько вещей:

  1. "порты ввода / вывода процессора". Кто они такие? Почему мы хотим читать и записывать «строки» в и из этих портов?
  2. Я никогда не думал о сценарии, где мне нужно использовать эти инструкции. Когда мне это понадобится?
  3. Приведите несколько практических примеров.

Ответы [ 7 ]

81 голосов
/ 09 июля 2010

Вы знаете, как работает адресация памяти?Там есть адресная шина, шина данных и несколько линий управления.Процессор помещает адрес байта (или начального байта) памяти в адресную шину, затем выдает сигнал READ, и, возможно, некоторая микросхема ОЗУ возвращает содержимое памяти по этому адресу, повышая или понижая отдельные строки (соответствующие битам).в байт (ы)) на шине данных.Это работает как для ОЗУ, так и для ПЗУ.

Но есть и устройства ввода-вывода: последовательный и параллельный порты, драйвер для крошечного внутреннего динамика ПК, контроллеры дисков, звуковые чипы и так далее.И эти устройства также читаются и записываются.К ним также необходимо обращаться, чтобы ЦП обращался к правильному устройству и (обычно) к правильному расположению данных в данном устройстве.

Для некоторых моделей ЦП, в том числе серии xxx86, которые можно найти на большинстве «современных» ПК, яУстройства ввода / вывода делят адресное пространство с памятью.Устройства RAM / ROM и IO подключены к одному и тому же адресу, линиям передачи данных и управления.Например, последовательный порт для COM1 адресуется начиная с (hex) 03F8.Но почти наверняка есть память с тем же адресом.

Вот очень простая диаграмма:

[https://qph.ec.quoracdn.net/main-qimg-e510d81162f562d8f671d5900da84d68-c?convert_to_webp=true]

Очевидно, что ЦПУ необходимо общаться либо с памятью, либо сУстройство ввода-вывода, никогда не оба.Чтобы провести различие между ними, одна из линий управления, называемая «M / # IO», устанавливает, хочет ли ЦП общаться с памятью (строка = высокая) или устройством ввода / вывода (линия = низкая).

Инструкция IN читает с устройства ввода / вывода, OUT пишет.Когда вы используете инструкции IN или OUT, M / # IO не утверждается (удерживается на низком уровне), поэтому память не отвечает, а микросхема ввода / вывода -.Для инструкций, ориентированных на память, M / # IO утверждается, так что CPU взаимодействует с RAM, а устройства IO остаются вне связи.

При определенных условиях устройства IO могут управлять линиями передачи данных, а RAM -читать их одновременно.И наоборот.Он называется DMA.

Традиционно последовательные порты и порты принтера, а также клавиатура, мышь, датчики температуры и т. Д. Были устройствами ввода-вывода.Диски были как бы посередине;Передача данных будет инициироваться командами ввода / вывода, но контроллер диска обычно напрямую помещает свои данные в системную память.

В современных операционных системах, таких как Windows или Linux, доступ к портам ввода / вывода скрыт от«обычные» пользовательские программы, и есть уровни программного обеспечения, привилегированных инструкций и драйверов для работы с оборудованием.Поэтому в этом веке большинство программистов не имеют дело с этими инструкциями.

22 голосов
/ 11 июля 2010

Начните с чего-то вроде этого:

http://www.cpu -world.com / Информация / Распиновка / 8088.html

Вы изучаете инструкции для очень старого технологического чипа / архитектуры. Назад, когда все, кроме ядра процессора было вне чипа. Видите адресные строки и строки данных, и есть строка чтения RD и строка записи WR и строка ввода / вывода?

Существовали два типа команд на основе памяти и ввода-вывода, поскольку имелись адресуемые пространства, которые легко декодировались с помощью ввода-вывода или памяти.

Помните, что у вас была клейкая логика 74LSxx, много проводов и много микросхем для подключения памяти к процессору. И память была только той памятью, большими дорогими чипами. Если у вас было периферийное устройство, которое должно было сделать что-то полезное, у вас также были управляющие регистры, память могла бы быть пиксельными данными, но где-то вам нужно было установить пределы тактового сканирования по горизонтали и вертикали, это могли бы быть отдельные защелки 74LSxx, а НЕ памяти, имеющие I Отображение ввода / вывода, сохраненное в связующей логике и имеющее большой смысл с точки зрения программиста, также позволило избежать изменения ваших сегментных регистров для ориентации окна памяти размером 64 КБ и т. Д. Адресное пространство памяти было священным ресурсом, особенно когда вы хотел ограничить декодирование вашего адреса несколькими битами, потому что каждые несколько битов стоили вам несколько микросхем и проводов.

Подобно вводу-выводу с большим и меньшим порядком байтов памяти против ввода-вывода, I / O был религиозной войной. И некоторые ответы, которые вы увидите на свой вопрос, будут отражать сильные мнения, которые все еще существуют сегодня у людей, которые жили этим. Реальность такова, что у каждого чипа на рынке сегодня есть множество возможностей для разных вещей, вы не вешаете свои часы реального времени на шину памяти ddr с помощью декодера адресов. У некоторых все еще даже есть совершенно отдельные инструкции и шины данных. В некотором смысле Intel выиграла войну за концепцию отдельных адресных пространств для разных классов вещей, хотя термин порт ввода / вывода является злым и плохим, и его не следует произносить, скажем, еще 20-30 лет. Вам нужны люди моего возраста, которые жили, чтобы уйти в отставку или уйти до того, как война действительно закончится. Даже термин «ввод-вывод с отображением в память» остался в прошлом.

Это действительно все, что когда-либо было: один бит декодирования адреса на внешней стороне чипа Intel, который контролировался с помощью специальных инструкций. Используйте один набор инструкций, которые были включены в бит, используйте один набор инструкций, которые были отключены. Хотите увидеть что-то интересное, посмотрите на набор инструкций для процессоров xmos xcore, у них есть множество вещей, которые являются инструкциями вместо регистров с отображением в памяти, это выводит этот ввод-вывод на совершенно новый уровень.

Где это было использовано, как я описал выше, вы бы поместили вещи, которые имели смысл, и вы могли бы позволить себе сжечь адресное пространство памяти, например, пиксели видео, память сетевых пакетов (возможно), память звуковой карты (ну, не то, что тоже, но вы могли бы иметь) и т. д. И управляющие регистры, адресное пространство относительно данных было очень маленьким, может быть, только несколько регистров, были декодированы и использованы в пространстве ввода / вывода. очевидными являются / были последовательные порты и параллельные порты, у которых было мало, если вообще было хранилища, у вас могло бы быть небольшое пятно на последовательном порту, если что-нибудь.

Поскольку адресное пространство было недостаточным, оно нередко встречалось и сегодня все еще считается, что память скрыта за двумя регистрами - регистром адресов и регистром данных, эта память доступна только через эти два регистра, она не отображается на память. таким образом, вы записываете смещение в эту скрытую память в регистре адресов и читаете или записываете регистр данных, чтобы получить доступ к содержимому памяти. Теперь, потому что у intel была инструкция rep, и вы могли бы объединить ее с insb / w outsb / w, аппаратный декодер (если бы у вас с вами работали приятные / дружелюбные специалисты по аппаратному обеспечению) автоматически вводил адрес всякий раз, когда вы выполняли цикл ввода-вывода. Таким образом, вы можете записать начальный адрес в регистр адресов и выполнить повторную передачу и без записи тактов выборки и декодирования в процессоре и на шине памяти, вы можете довольно быстро перемещать данные в периферийное устройство или из него. Подобные вещи теперь считаются недостатком дизайна благодаря современным суперскалярным процессорам с выборками, основанными на предсказании ветвлений, ваше оборудование может в любое время выполнять чтение, не имеющее ничего общего с выполнением кода, в результате вы НИКОГДА не должны автоматически увеличивать адрес или очистить биты в регистре состояния или изменить что-либо в результате чтения по адресу.

Механизмы защиты, встроенные в 386 и до настоящего времени, фактически упрощают доступ к входам / выходам из пространства пользователя. В зависимости от того, что вы зарабатываете на жизнь, что производит ваша компания и т. Д. Вы можете наиболее определенно использовать семейство инструкций in и out из пользовательского пространства (прикладные программы в Windows и Linux и т. Д.) Или из пространства ядра / драйвера, это ваше выбор. Вы также можете делать забавные вещи, такие как использование виртуальной машины и использование инструкций ввода / вывода для общения с драйверами, но это, вероятно, разозлит людей, как в Windows, так и в мире Linux, что драйвер / приложение не сделают это очень далеко. Другие постеры верны в том, что вам, вероятно, никогда не понадобится использовать эти инструкции, если вы не пишете драйверы, и вы, вероятно, никогда не собираетесь писать драйверы для устройств, использующих I / O, сопоставленные с I / O, потому что вы знаете ... драйверы для этих устаревших устройств уже написаны. Современные конструкции, безусловно, имеют ввод / вывод, но все они отображены в памяти (с точки зрения программистов) и используют инструкции памяти, а не инструкции ввода / вывода. Теперь другая сторона, если это DOS, определенно не мертва, в зависимости от того, где вы, возможно, строите машины для голосования, газовые насосы или кассовые аппараты или длинный список оборудования на основе DOS. На самом деле, если вы работаете где-то, производя ПК или периферийные устройства или материнские платы для ПК, инструменты на основе DOS по-прежнему широко используются для тестирования и распространения обновлений BIOS и других подобных вещей. Я все еще сталкиваюсь с ситуациями, когда мне приходится брать код из текущей программы тестирования DOS, чтобы написать драйвер для Linux. Точно так же, как не все, кто может бросать или ловить футбол, играют в НФЛ, очень немногие занимаются программным обеспечением, которое включает подобные вещи. Поэтому все еще можно с уверенностью сказать, что эти инструкции, которые вы нашли, скорее всего, не будут для вас чем-то большим, чем урок истории.

12 голосов

Приведите несколько практических примеров.

Сначала научитесь:

  • создать минимальную ОС загрузчика и запустить ее на QEMU и реальном оборудовании, как я.Мы объяснили здесь: https://stackoverflow.com/a/32483545/895245
  • сделать несколько вызовов BIOS, чтобы выполнить быстрый и грязный ввод-вывод

Затем:

  1. Контроллер PS / 2 : получить идентификатор кода сканирования последнего введенного на клавиатуре символа в al:

    in $0x60, %al
    

    Минимальный пример

  2. Часы реального времени (RTC) : получить время на стене с определением секунд:

    .equ RTCaddress, 0x70
    .equ RTCdata, 0x71
    
    /* al contains seconds. */
    mov $0, %al
    out %al, $RTCaddress
    in $RTCdata, %al
    
    /* al contains minutes. */
    mov $0x02, %al
    out %al, $RTCaddress
    in $RTCdata, %al
    
    /* al contains hour. */
    mov $0x04, %al
    out %al, $RTCaddress
    

    Минимальный пример

  3. Программируемый интервальный таймер (PIT) : генерировать одно число прерываний 8 каждые 0x1234 / 1193181 секунды:

    mov $0b00110100, %al
    outb %al, $0x43
    mov $0xFF, %al
    out %al, $0x34
    out %al, $0x12
    

    Минимальный пример

    A Использование ядра Linux 4.2 .Есть и другие.

Проверено на: QEMU 2.0.0 Ubuntu 14.04 и реальном оборудовании Lenovo ThinkPad T400.

Как найти номера портов: Есть лиспецификация назначения портов ввода-вывода x86?

https://github.com/torvalds/linux/blob/v4.2/arch/x86/kernel/setup.c#L646 содержит список многих портов, используемых ядром Linux.

Другие архитектуры

Не во всех архитектурах есть такие специальные инструкции ввода-вывода.

Например, в ARM ввод-вывод выполняется просто путем записи в волшебные аппаратные адреса памяти.

Я думаю, что эточто https://stackoverflow.com/a/3221839/895245 означает «ввод-вывод с отображением памяти против ввода-вывода с отображением ввода-вывода».

С точки зрения программиста, я предпочитаю способ ARM, поскольку инструкции ввода-вывода уже нуждаются в магииадреса для работы, и у нас есть огромные неиспользуемые адресные пространства в 64-битной адресации.

См. https://stackoverflow.com/a/40063032/895245 для конкретного примера ARM.

4 голосов
/ 10 июля 2010

На аппаратном уровне большинство микропроцессоров имеют небольшую встроенную возможность ввода-вывода или не имеют ее. У нескольких процессоров есть один или несколько выводов, которые можно включать и выключать с помощью специальных инструкций, и / или один или несколько выводов, которые могут бытьпроверено с помощью специальных веток инструкции, но такие функции встречаются редко.Вместо этого ввод / вывод обычно обрабатывается путем подключения системы, так что доступ к диапазону адресов памяти будет вызывать некоторый эффект, или путем включения инструкций «in» и «out», которые ведут себя как операции загрузки / сохранения памяти, за исключением специального сигналавыводится сообщение «Это операция ввода-вывода вместо операции с памятью».Во времена 16-битных процессоров имелись некоторые реальные преимущества специализированных инструкций ввода / вывода.В настоящее время такие преимущества в значительной степени спорны, так как можно просто выделить большой кусок своего адресного пространства для ввода-вывода и при этом еще достаточно места для памяти.

Поскольку программа может нанести значительный ущерб системе из-за ненадлежащего выполнения IИнструкции / O (например, такие инструкции могут выполнять произвольный доступ к диску), все современные операционные системы запрещают использование таких инструкций в коде пользовательского уровня.Некоторые системы могут позволять виртуализировать такие инструкции;например, если пользовательский код пытается выполнить запись в порты ввода / вывода 0x3D4 и 0x3D5, операционная система может интерпретировать это как попытку установить некоторые регистры управления видео для перемещения мигающего курсора.Каждый раз, когда пользовательская программа выполняла инструкцию OUT, операционная система вступала во владение, видела, что пользовательская программа пыталась сделать, и действовала соответствующим образом.

В подавляющем большинстве случаев, даже если операционная системапереведите инструкцию IN или OUT в нечто подходящее, было бы более эффективно запрашивать соответствующее действие непосредственно у операционной системы.

3 голосов
/ 09 июля 2010

Если вы не пишете операционную систему, то вы никогда не будете использовать эти инструкции.

Машины на базе x86 имеют два независимых адресных пространства - знакомое вам пространство памяти, а затемАдресное пространство ввода / вывода.Адреса портов ввода / вывода имеют ширину всего 16 бит, и они ссылаются на низкоуровневые регистры и другие низкоуровневые виджеты, которые являются частью устройства ввода / вывода - например, последовательный или параллельный порт, контроллер диска и т. Д.

Практических примеров нет, потому что они используются только драйверами устройств и операционными системами.

2 голосов
/ 27 апреля 2017

Есть немного больше хитрости, чем это. Он не просто мультиплексирует отдельное адресное пространство 64 КБ на те же провода с «дополнительной адресной шиной / контактом выбора микросхемы». Intel 8086 и 8088 и их клоны также мультиплексируют шину данных и шину адреса; все очень необычные вещи в процессорах. Таблицы полны «минимального / максимального» конфигурационного материала и всех регистров защелки, которые вам нужно подключить, чтобы он работал «нормально». С другой стороны, при декодировании адресов он загружает и gates, и 'or' gates, и 64 КБ должно быть «достаточно портов ввода / вывода для всех»: P.

Кроме того, для всех тех, кто занимается разработкой драйверов, обратите внимание: кроме людей, использующих совместимые с Intel чипы на другом оборудовании, а не только на ПК (в действительности они никогда не предназначались для использования в IBM PC - IBM просто взяла на себя Кроме того, поскольку они были дешевыми и уже появились на рынке), Intel также продает микроконтроллеры с тем же набором инструкций (Intel Quark), и есть множество «систем на чипе» от других поставщиков с таким же набором инструкций. Я не думаю, что вам удастся втиснуть что-нибудь с отдельными «пользовательским пространством», «ядром» и «драйверами» в 32 КБ :). Для большинства вещей такие сложные «операционные системы» не являются ни оптимальными, ни желаемыми. Знаете, для формирования некоторых пакетов UDP в ОЗУ, а затем их помещения в кольцевой буфер и запуска некоторых ретрансляторов щелчок одним щелчком мыши не требует ядра 30 МБ и времени загрузки 10 секунд. По сути, это лучший выбор, если PIC-микроконтроллера недостаточно, но вам не нужен целый промышленный ПК. Таким образом, инструкции по вводу / выводу порта часто используются не только «разработчиками драйверов» для более крупных операционных систем.

0 голосов
/ 09 июля 2010

CPU подключен к некоторым внешним контроллерам через порты io.на старых компьютерах x86 я работаю с дисководом гибких дисков, используя порты ввода / вывода.если вы знаете, какие команды принимают контроллер устройства, вы можете запрограммировать его через его порты.

В современном мире вы никогда не будете использовать инструкции портов.Исключение, если вы (или будете) разработчиком драйвера.

есть более подробная информация о портах ввода / вывода http://webster.cs.ucr.edu/AoA/DOS/ch03/CH03-6.html#HEADING6-1

...