Форум программистов, компьютерный форум, киберфорум
Assembler, MASM, TASM
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.63/2256: Рейтинг темы: голосов - 2256, средняя оценка - 4.63
Ушел с форума
Автор FAQ
 Аватар для Mikl___
16374 / 7686 / 1080
Регистрация: 11.11.2010
Сообщений: 13,761
18.12.2013, 14:18  [ТС]
ГЛАВА 20
РАБОТА С ПОРТАМИ ВВОДА/ВЫВОДА
Напишем программу длиной всего 9 байт, которая (если у вас BIOS AWARD) будет сбрасывать пароль и настройки SETUP’а. Теперь сбросить пароль в BIOS’е также легко, как его поставить.
Assembler
1
2
3
4
5
6
7
8
9
.model tiny
.code
org 100h
start: mov al,5Eh
out 70h,al
mov al,0
out 71h,al
ret
end start
Запускаем получившийся com-файл в реальном режиме, перезагружаемся и получаем при загрузке сообщение «CMOS checksum error — Defaults loaded”. Команда MOV AL,5Eh — заносит число 5Eh в регистр AL.
Дальше команда OUT 70h,AL выводит в порт с номером 70h число из регистра AL. Порт — это как бы канал связи микропроцессора с внешним миром. Через порт микропроцессор получает сигналы от устройств ввода, либо посылает сигналы на устройства вывода. Теоретически микропроцессор управляет 65536 портами, начиная с нулевого порта. Для управления вводом-выводом непосредственно на уровне порта используются команды IN и OUT. Каждое устройство (винчестер, видео-, звуковая карта и т.д.) имеет несколько портов, через которые осуществляется управление.
Порты 70h и 71h соответствуют CMOS’у. Чтобы программировать CMOS, надо сначала вывести в порт 70h то, что вы хотите изменить в CMOS’е (дата, время, настройки винчестера, пароль), а затем ввести в порт 71h новое значение (дату, время, параметры винчестера и так далее). Сначала выводим в порт 70h число 5Eh, которое означает, что мы будем изменять настройку пароля ON/OFF. Затем выводим в порт 71h ноль, что соответствует отключению пароля (чтобы пароль включить, надо вывести единицу).
Кроме CMOS'а, напрямую через порты ввода/вывода можно управлять клавиатурой, системным динамиком, винчестером, флоппиком, видеоадаптером, таймерами, принтером, сканером, а также микропроцессорами для управления потоком данных. Микропроцессор IA32/64 имеет два различных физических адресных пространства: ПАМЯТЬ и ВВОД/ВЫВОД. Обычно, внешние устройства помещаются в пространстве ВВОДА/ВЫВОДА, хотя микропроцессор IA32/64 также поддерживает внешние устройства распределения памяти. Объем пространства ВВОД/ВЫВОД 64Кбайт и может быть разделен на 64К 8-разрядных портов, 32К 16-разрядных портов, 16К 32-разрядных портов или другую комбинацию устройств, которые в сумме не превышают 64 Кбайт. 64К-адресное пространство ВВОД/ВЫВОДА относится к физической памяти, а не к линейному адресу, поскольку команды ввода/вывода не проходят через устройства, выполняющие сегментацию или разбиение на страницы. Для работы памяти ВВОДА/ВЫВОДА задействована дополнительная адресная линия https://www.cyberforum.ru/cgi-bin/latex.cgi?\bar{M}/IO, позволяющая определить, к какому адресному пространству в настоящее имеет доступ микропроцессор. Доступ к портам ВВОДА/ВЫВОДА можно получить через команды: IN (операнд) или OUT (операнд), где операнд содержит адрес порта в виде непосредственного операнда (если не превышает 256) или находится в регистре DX. Все 8 и 16 бит адреса порта
имеют нулевое расширение (то есть не расширяются) на верхних адресных линиях. Команды ввода/вывода вызывают цикл ожидания, так как работают гораздо медленнее микропроцессора.
Адреса портов ВВОД/ВЫВОДА от 0000h до 00FFh зарезервированы для внутреннего использования фирмой Intel. Цифровые сопроцессоры также постоянно хранятся в данном пространстве ВВОДА/ВЫВОДА в ячейках: 8000000F8h-800000FCh.
Использование адресного пространства системного ввода/вывода
Диапазон адресов Устройство
000h-01Fh Контроллер 1 ПДП
020h-03Fh Ведущий контроллер прерываний
040h-05Fh Таймер
040h Канал 0 (генерирует IRQ0)
041h Канал 1 (поддержка обновления памяти)
042h Канал 2 (управление динамиком)
043h Управляющий регистр первого таймера
044h-047h Второй таймер компьютеров с шиной Microchannel
048h-04Bh Второй таймер компьютеров с шиной EISA
060h-06Fh Контроллер клавиатуры
070h-07Fh Устройство часов реального времени, триггер маски NMI
080h Порт для записи контрольной точки диагностики. Также соответствует одному из регистров записи/чтения в регистре страниц ПДП
081h-09Fh Регистр страниц ПДП
0A0h-0BFh Ведомый контроллер прерываний
0C0h-0DFh Контроллер 2 ПДП
0F0h Сброс занятости сопроцессора
0F1h Сброс сопроцессора
080h-09Fh Сопроцессор
100h-3FFh Адреса в этом диапазоне принадлежат устройствам канала ввода/ вывода
1F0h-1F8h Контроллер винчестера
200h-20Fh Игровой порт
220h-22Fh Sound Blaster
278h-27Fh Порт параллельного принтера 2
2F8h-2FFh Последовательный порт 2
378h-37Fh Порт параллельного принтера 1
3C0h-3DFh Порты графического адаптера
3F0h-3F7h Контроллер флоппи-дисковода
3F8h-3FFh Последовательный порт 1
Прямой доступ к портам ввода-вывода доступен из среды MS-DOS и частично под Windows 95/98. В Windows NT/2k/XP любая попытка обращения к портам ввода-вывода через команды IN/OUT приведет к возникновению исключения по недопустимому коду операции. С точки зрения
операционной системы Windows NT/2k/XP, порты являются критически важным разделяемым ресурсом, и механизмы защиты операционной системы не могут допустить их монополизацию каким-либо приложением. Если программе удастся получить уровень привилегий ядра (такой уровень имеют драйвера устройств), то в этом случае можно беспрепятственно использовать команды IN/OUT. Существуют специальные программы, позволяющие получить доступ к портам ввода-вывода из программы пользователя, исключая необходимость написания драйверов.
Команда IN
(Ввод операнда из порта = “INPUT operand from port”)
Синтаксис команды:
IN <аккумулятор>,<номер порта>
Семантика команды: ввод значения из порта ввода-вывода.
Алгоритм работы: передает байт, слово, двойное слово из порта ввода-вывода в один из регистров AL/AX/EAX.
Возможные варианты команды:
in eax/ax/al,dx
in eax/ax/al,imm

Применение: команда применяется для прямого управления оборудованием компьютера посредством портов. Номер порта задается вторым операндом в виде непосредственного значения или значения в регистре DX. Непосредственным значением можно задать порт с номером в диапазоне 0-255.
При использовании порта с большим номером используется регистр DX.
Размер данных определяется размерностью первого операнда и может быть байтом, словом, двойным словом. В качестве примера применения рассмотрим фрагмент обработчика прерывания от клавиатуры INT 9. Это прерывание вызывается всякий раз при нажатии любой клавиши на клавиатуре. Обработчик этого прерывания должен прочитать скан-код клавиши, подтвердить микропроцессору клавиатуры факт приема скан-кода, преобразовать этот код в соответствии с клавишами-переключателями и поместить преобразованный код в буфер клавиатуры, находящийся в области BIOS. Действия чтения и подтверждения приема скан-кода могут выглядеть, к примеру, так:
Assembler
1
2
3
4
5
6
7
IN AL,60h ;читаем скан-код в порт 60h
PUSH AX ;сохраним его на время
IN AL,61h ;читаем порт 61h
OR AL,80h ;старший бит байта из порта 61h в 1
OUT 61h,AL ;подтверждаем факт приема скан-кода
POP AX
OUT 61h,AL ;восстановили байт в порту 61h
Команда OUT
(Вывод операнда в порт = “OUTPUT operand to port”)
Синтаксис команды:
OUT <номер порта>,<аккумулятор>
Семантика команды: вывод значения в порт ввода-вывода.
Алгоритм работы: передать байт, слово, двойное слово из регистра AL/AX/EAX в порт, номер которого определяется первым операндом.
Возможные варианты команды:
out dx,eax/ax/al
out imm,eax/ax/al

Применение: команда применяется для прямого управления оборудованием компьютера посредством портов. Номер порта задается первым операндом в виде непосредственного значения или значения в регистре DX. Непосредственным значением можно задать порт с номером в диапазоне 0...255. Для указания порта с большим номером используется регистр DX.
Размер данных определяется размерностью второго операнда и может быть байтом, словом или двойным словом.
Assembler
1
OUT 64h,AL; вывод в порт 64h содержимого регистра AL
Команды INSB/INSW/INSD
(Ввод строк байтов/слов/двойных слов из порта =
INPUT String Byte/Word/Double word operands”)
Синтаксис команд:
INS <операнд>,<порт>
INSB
INSW
INSD

Семантика команды: ввод из порта в память последовательности байт, слов, двойных слов.
Возможные варианты команды:
ins(b/w/d)
rep ins(b/w/d)

Алгоритм работы:
  • передать данные из порта ввода-вывода, номер которого загружен в регистр DX, в память по адресу ES:RDI/EDI/DI;
  • в зависимости от состояния флага DF изменить значение регистров RDI/EDI/DI:
    • если DF=0, то увеличить содержимое этих регистров на длину структурного элемента последовательности;
    • если DF=1, то уменьшить содержимое этих регистров на длину структурного элемента последовательности;
  • при наличии префикса выполнить определяемые им действия (см. команду REP).
Применение: команда вводит данные из порта ввода-вывода, номер которого загружен в регистр DX в память по адресу ES:RDI/EDI/DI. Сегментная составляющая адреса должна быть обязательно в регистре ES. Замена сегментного регистра недопустима. Непосредственное задание порта в команде также недопустимо — для этого используется регистр DX. Размеры вводимых элементов зависят от применяемой команды. Команда INS может работать с элементами размером в байт, слово, двойное слово. В качестве операндов в команде указывается символическое имя ячейки памяти,
в которую вводятся элементы из порта ввода-вывода. Реально это символическое имя используется лишь для получения типа элемента последовательности, а его адрес должен быть предварительно загружен в пару регистров ES:RDI/EDI/DI.
Assembler
1
2
3
4
5
6
; получить 10 байт из порта 300h (номер порта взят условно)
; в память по адресу ES:STR_10
STR_10 DB 10 DUP(0)
MOV DI,OFFSET STR_10
MOV DX,300h
REP INSB
Для того чтобы эти команды можно было использовать для ввода последовательности элементов, имеющих размерность байт, слово, двойное слово, необходимо использовать префикс REP. Префикс REP заставляет циклически выполняться команду ввода до тех пор, пока содержимое регистра ECX/CX не станет равным нулю.
Команды OUTSB/OUTSW/OUTSD
(Вывод строки байтов/слов/двойных слов в порт =
“OUTPUT Byte/Word/Double word String to port”)
Синтаксис команд: OUTS порт,операнд
OUTSB
OUTSW
OUTSD

Семантика команды: вывод в порт из памяти последовательности байт, слов, двойных слов.
Возможные варианты команды:
outs(b/w/d)
rep outs(b/w/d)

Алгоритм работы:
  • передать данные в порт ввода-вывода, номер которого загружен в регистр DX, из ячейки памяти по адресу DS:RDI/ESI/SI;
  • в зависимости от состояния флага DF изменить значение регистров ESI/SI:
    • если DF=0, то увеличить содержимое этих регистров на длину структурного элемента последовательности;
    • если DF=1, то уменьшить содержимое этих регистров на длину структурного элемента последовательности;
  • при наличии префикса выполнить определяемые им действия (см. команду REP/REPE/REPZ/REPNE/REPNZ)
Применение: команда выводит данные в порт ввода-вывода, номер которого загружен в регистр DX, из ячейки памяти по адресу DS:RDI/ESI/SI (допускается замена сегмента). Недопустимо задание номера порта в команде в виде непосредственного операнда — для этого используется регистр DX.
Размеры вводимых элементов зависят от применяемой команды. Команда OUTS может работать с элементами размером в байт, слово или двойное слово. В качестве операнда в команде указывается символическое имя ячейки памяти, из которой элемент выводится в порт ввода-вывода. Реально символическое имя используется лишь для получения типа элемента последовательности, а ее адрес должен быть предварительно загружен в пару регистров DS:RDI/ESI/SI.
Для того чтобы эти команды можно было использовать для вывода в порт последовательности элементов, имеющих размерность байт, слово или двойное слово, необходимо использовать префикс REP. Он заставляет циклически выполняться команду вывода в порт до тех пор, пока содержимое регистра ECX/CX не станет равным нулю.
Пример использования команд IN, OUT, OUTS
При помощи команд IN и OUT можно управлять, например, встроенным динамиком. Динамик включается и выключается при выводе специального значения в порт управления динамиком с номером 61h, связанный с микросхемой программируемого контроллера периферийного интерфейса Intel 8255. Для включения динамика нужно прочитать байт из порта 61h, установить в единицу его два младших бита (бит 0 разрешает работу канала таймера, а бит 1 включает динамик), а затем записать полученное значение в тот же порт. Чтобы отключить динамик, нужно сбросить значение двух младших битов порта 61h.
Все управление таймером осуществляется путем вывода байта в порт 43h. Назначение битов порта 43h приведены в таблице.
Номер бита Назначение
Если 7-6 биты не равны 11 — байт посылаемый в порт 43h команда программирования канала
7-6
Номер канала:
00 — 0-й канал
01 — 1-й канал
10 — 2-й канал
5-4
00 — зафиксировать текущее значение счетчика для чтения (в этом случае биты 3-0 не используются)
01 — чтение/запись только младшего байта
10 — чтение/запись только старшего байта
11 — чтение/запись сначала младшего, а потом старшего байта
3-1Режим работы канала:
000 — прерывание IRQ0 при достижении нуля
001 — ждущий мультивибратор
010 — генератор импульсов
011 — генератор прямоугольных импульсов (основной режим)
100 — программно-запускаемый одновибратор
101 — аппаратно-запускаемый одновибратор
0Формат счетчика:
0 — двоичное 16-разрядное число (0-0FFFFh )
1 — двоично-десятичное число (0000-9999)
Если 7-6 биты равны 11 — байт посылаемый в порт 43h — это команда чтения счетчиков
7-6 11 (команда чтения счетчиков)
5-400 — сначала состояние канала, потом значение счетчиков
01 — значение счетчиков
10 — состояние канала
3-1 Команда относится к каналам 3-1
Частота генерируемого звука задается с помощью микросхемы программируемого интервального таймера Intel 8253. Этот контроллер в числе прочего определяет, сколько импульсов в секунду следует послать на системный динамик. Таймер вырабатывает базовую частоту 1,19 МГц. Первоначальное значение делителя частоты установлено в (1)0000h, что эквивалентно 65536. Для этого числа частота прерываний таймера равна 1190000/65536 =18,157958984375 Гц, что ниже граничной частоты восприятия звука человеком. Мы можем посылать Intel 8253 другое число для деления базовой частоты 1,19 МГц. Для установки таймера в правильный рабочий режим посылаем число 0B6h в порт 43h. После этого можно использовать порт 42h для передачи делителя. Если отправить в порт 42h число 5000, то получим частоту следования импульсов 1190000/5000=238 Гц, чуть ниже ноты си третьей октавы (для третьей октавы значение частоты из таблицы 1 делят на 2, а для пятой октавы — умножают на 2). Так как делитель является 16-разрядным числом, поэтому передаем его двумя частями. Сначала отправляем младший байт, а затем старший байт.
Таблица 20.5.1
Ноты четвертой октавы
Нота Частота (Гц) Делитель = 1190000/частота
до диез 277,23 10C5h
ре 293,66 0FD4h
ре диез 311,13 0EF1h
ми 329,63 0E1Ah
фа 349,23 0D50h
фа диез 370 0C90h
соль 392 0BDCh
соль диез 415,3 0B31h
ля 440 0A91h
ля диез 466,16 9F9h
си 493,88 969h
до 523,25 8E2h
играем спикером цирковой марш, выводя в порт 42h цепочку байт
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
in al,61h; получаем текущее состояние порта 61h в AL
or al,00000011b; установим 0-й и 1-й биты в 1
out 61h,al; теперь динамик включен
mov al,0B6h; канал 2, режим 3
out 43h,al;отправляем в командный регистр
mov esi,offset melody; указываем на данные
mov ecx,size_melody ; устанавливаем счетчик
mov dx,42h;будем посылать байты во 2-й канал
a15: push edx
mov ah,0; получаем задержку через DOS, а можно через
int 1Ah ; API- функцию Sleep или через rdtsc
mov bx,dx
@@: int 1Ah; крутимся до тех пор пока не получится
cmp bx,dx; задержка в 55 мСек
jnz @b
pop edx; команда outs выводит данные в порт ввода-вывода,
outsb ; номер которого загружен в регистр DX,
loop a15 ; из ячейки памяти по адресу DS:ESI
in al,61h; получаем текущее состояние порта 61h в AL
and al,11111100b; обнуляем два младших бита
out 61h,al; теперь динамик выключен
.data; мелодия циркового марша
melody dw 354h,354h,2,2,387h,387h,2,2,3BDh,3BDh,387h,387h
dw 3BDh,3BDh,3F5h,3F5h,432h,432h,2,2,472h,472h,2,2,4 dup(4B5h)
dw 4 dup(472h),3F5h,3F5h,2,2,432h,432h,2,2,472h,472h,432h
dw 432h,472h,472h,4B5h,4B5h,4FDh,4FDh,2,2,549h,549h,2,2
dw 4 dup(599h),4 dup(549h),472h,472h,2,2,2 dup(5EEh,2)
dw 4 dup(649h),4 dup(5EEh),472h,472h,2,2,2 dup(5EEh,2)
dw 4 dup(649h),4 dup(5EEh),70Eh,70Eh,6A8h,6A8h,649h,649h,5EEh
dw 5EEh,599h,599h,549h,549h,4FDh,4FDh,4B5h,4B5h,472h,472h,2
dw 2,432h,432h,2,2,3F5h,3F5h,2,2,387h,387h,2,2,8 dup(354h),2
size_melody = $ - melody; длина мелодии
Кодировка команд ввода/вывода
Команды IN и OUT имеют длинный и короткий форматы. Первым операндом в команде IN, то есть операндом получателем, должен быть регистр AL/AX/EAX. Если второй операнд в команде IN – непосредственное значение числа, то команда имеет длину 2 байта и адрес занимает второй байт. Когда вторым операндом указан регистр DX, команда оказывается однобайтовой (Рис. 20.6.1). В отличии от адресации памяти содержимое DX не модифицируется никаким сегментным регистром. В длинном формате команд IN и OUT адрес порта должен находится в диапазоне от 0 до 255, а в коротком формате в диапазоне от 0 до 65535.
Кодировка команд IN/OUT/INS/OUTS
Миниатюры
Электронный учебник   Электронный учебник   Электронный учебник  

Изображения
 
2
Закрытая тема Создать тему
Новые блоги и статьи
GitDOS: Когда я решил скрестить MS-DOS, GitHub и Claude
MaGz GoLd 08.07.2026
Привет, Киберфорум! Хочу поделиться своим проектом, который, надеюсь, вас заинтересует. GitDOS — это веб-приложение, которое позволяет запускать DOS в браузере с тремя крутыми фичами: диски живут в. . .
Учебный мини "цифровой двойник" = (Сервер = Java + Flask_питон )+(3D = Гугловскаая 4T nvideo + google colab) +( WMS = Odoo на Docker)
anaschu 07.07.2026
Увидел в требованиях к вакансии создателя имитационных моделей связку (REst + Api + WMS + Anylogic + питон + 3D Nvideo), и решил посмотреть, что это такое. Из этого всего я работал более менее. . .
Море в объективе
kumehtar 06.07.2026
Хотел написать много проникновенных слов, но передумал. Оно само - говорит. Кто слышит тот слышит.
Doom для терминала без стрельбы и монстров. 3D Raycasting на ascii.
dcc0 05.07.2026
Попросил нейронную сеть deepai. org написать рейкастинг 3D с библиотекой ncurses для Linux. Чтобы можно было ходить на стрелочки. Чтобы стены были отрисованы символами. Справилась. Первый вариант. . .
Установка статуса документа по условию
Maks 05.07.2026
Алгоритм из решения ниже реализован на нетиповом документе "НарядПутевка" разработанного в КА2. Задача: в табличной части "Материалы" документа при записи автоматически устанавливать статус. . .
Сезонность и суточность закисления почв
anaschu 04.07.2026
200 часов это все равно моловато. Есть ситуации, но нестандартные, когда смена происходит за 5 лет. Но обычно это 50 лет и более. Наверное, закисление почвы происходит сезонно в средней. . .
В чем ценность человеческого опыта в глобальном смысле?
kumehtar 03.07.2026
Возможно, ценность человека не в том, что он однажды достигает мудрости, а в том, что он становится носителем карты пути. Он знает не только истину, но и последовательность внутренних изменений,. . .
интеграция AnyLogic с самописным REST API и переход на Odoo
anaschu 03.07.2026
Успешная интеграция AnyLogic с самописным REST API и переход на промышленную Odoo WMS Сегодня проделал огромный путь от простой симуляции физических процессов до построения полноценной. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru