В.Н. Пильщиков - Программирование на языке ассемблера IBM PC (1110551), страница 11
Текст из файла (страница 11)
Таким образом, обьединение (слияние) нескольких сегментов означает, что эти сегменты будут расположены в пювяги редоьг и, главное, смещения всех имен из этих сегментов будут отсчитываться от начала объединенного сегмента. Это и позволяет один раз установить какой-то сепвентный регистр на начало общего сегмента и далее, не меняя значение регистра, использовать его для доступа ко всем именам общего сегмента. Зиачвиав ЗТАСК Если какие-то сепвенты (из любых модулей) имеют одно и то же иьш, относятся к одному и тому же кдассу и для каждого из них указан тип объединения ЗТАСК, то эти сепвенты обьединяются в один сегмент - так же, как и сепченты типа РОВЕ)С, (Отметиьг, что друг с другом сепченты типов РЮВ1ЛС и ЗТАСК не обьединяются.) Разница между этими двуьш типами проявляется в том, что объединенный сегмент типа БТАСК рассыатривается квк сегмент стека, и именно на него перед выполнением прогрювчы будут установлены регистры ЗЗ и ЗР (на сепвент типа РОВЕ1С никакие регистры автоматически не устанавливаются),.
Если в программе нет ни одного сегмента типа БТАСК, то компоновщик выдаст на экран ПК предупреждегзие об этолг. Если же имеется несколько таких сегментов, то регистры ББ и ЗР устанавливаются на тот из них, который (или часть которого, если он получен слияниеы) последним "попался на глаза" компоновщику. Зиачваив АТ <яаистаатиав выражвнивэ В вырюкении не должно быть ссылок вперед. Значение выражения трактуется как номер некоторого сегмента павити, т. е. квк абсолютный адрес сепвента без Это означает, что теперь сыещения всех имен этого объединенного сегыента будут отсчитываться от начала данного сегмента и именно на эти смещения будут заменяться имена (таким пересчетом и коррекцией команд занимается компоновщик).
Например, имя 2 теперь будет заменяться не на сыещение О, а на смещение 10Ь. Почему на 106 (м16), а не на 3? Здесь надо вспомнить, что сегменты располагаются в лазити с адресов, кратных 16, и это правило действует, даже если сегменты обьединяются. Поэтому сегмент А из М2 подсоединяется к сегменту А из М1, но не впритык, а с ближайшего адреса, кратного 16, и тем самым ыежду переменными У и Е будет оставлено свободными 13 байтов (от этого зазора можно и избавиться - см.
Разд. 12.3.3). Итак, смещение имени 2 равно 100, поэтому в нашей команде имя 2 будет заменено на 10Ь: млогомощоъиыв программы 222 последних четырех битов. Программный сепвент с параметром АТ ни с кем не обьединяется, а располагается в памяти по укюанному адресу. Например, сегмент Зиачвммв СОММОА> Все сегменты, которые имеют одно н то же юи, относятся к одному и тому же классу и в директиве ЗЕОМЕ>ОТ которых указан параметр СОММО)», компоновщик размещает в памяти с одного и того же адреса (с адреса, по которому был размещен первый из этих сегментов), накладывая их содержимое друг на друга. Результирующий сегмент имеет ллину наибольшего из этих сегь>ентов. СОММОКпсегменты используются тогда, когда одни и те же ячейки па>ити желательно именовать по-разному в разных модулях программы. Наприыер, в программе, в состав которой входят следующие модули: ;модуль Мз я яяанвит соннон Ь ОВ 1 вооо а киов ;модуль Нз в вкшамт поше>н х ов з х ов г в хиов на оба сегмента э будет отведено 5 баГпов, причем первый нз этих байтов - это одновременно и бю>т А (с точки зрения модуля М1), и байт Х (с точки зрения модуля М2), вторшг байт - это начало двойного слова В в ьюдуле М1 и переменная У в ыодуле М2, а оставшиеся три байта - продолжение переменной В (для ьюдуля М1).
При этоы, если в приказе ЫГчК модуль М2 был указан после модуля М1, в первом байте результирующего сепвенга окажется число 3, значение второго баГпа будет неопределенным, а остальные три байта будут нулевыми. 12ЗЗ. Параметр ывыравниваннеы Кыг мы уже видели, при обьединенни сегментов типа Р>)ВЫС или ЗТАСК может образоваться зазор ыежду сепнентами. Если для необьединяе>гых сегментов такой пропуск необходим (независимый сегмент должен начинаться с адреса, кратного 16, чтобы на его начало можно было установить сегментный регистр), "дидро>'-мими чхоко вванхия хт Ояааоь он за*во овэгт> тхоко кнов будет расположен с абсолютного адреса ОВ8000Ь и займет 2000 слов (здесь находится вндеопамать, содержимое которой отображается на экран ПК). С помощью АТ-сепвентов обычно вводятса ассемблерные обозначениа для фиксированнмх участков оперативной па>ити (вектора прерываний, видеопамяти и т.
и.). Чтобы не менять содержимое этих участков, в состав АТ-сегментов не должны входить предложения, порозщающие машинный код, т. е. запрещены любые команды, директивы РВ, 1>тГ н Г>1> с операндами, отличными от?, и т. и. Если подобные прелложениа все-таки имеются, тогда компоновщик блокирует запись в лапать их машинного кода. 2ВВ Преграммирсаеиие ие езыее ассемблере ГВЫ РС Например, в программе, содержащей следующие модули: ;модуль и2 А ВВСИЕВТ ВГТЕ РВВЬХС 'Я' х Ов г А ВИОВ гмодуиь И1 А ЯЕСИЕНТ РВВЬХС 'О' хввг тввг Л ЕНОЯ будет образован единый сегмент А: л весиент Х От 2 ТОВ2 х Ов г Л ЕИОВ причем содержиыос сегмента А из модуля М2 будет без пропуска подсоединено к предложениюг сегмента А из модуля М1, поэтому смещение имени 2 будет равно 3, а не 10д, как было в примере из разд. 12.3.2.
Отметим, что если в директиве БЕОМЕ1ЧТ параметр "выравнивание" опущен, то по умолчанию берется значение РАКА. Именно по этой причине у нас до сих пор все сегменты начинались с адресов, кратных 16. то для обьединенных сегментов этот заюр - лишь потеря памяти. Поэтому в ЯА предусмотрено средство, позволяющее. уничтожать тихие зазорм, а точнее - регу- лировать начало размещения сепеентов в памяти. Зтим средспюм является пара- метр "выравнивание" директивы ЗЕОМЮТ: он указьпмет, с адреса какой крат- ности должен начинаться сегмент.
Возьгожные значения данного параметра и соответствующие иы начальные адреса сегментов таковы: ВТТЕ - блииайиий саободиий адрес; ВОВО - биииайивй адрес, кратаий 22 РАВА - бииаайиай адрес, аратиий 16 (ларатрафг; Рлав - биииайиий адрес, кратиий 255 (страиица). Глава 13 ВВОД-ВЫВОД.
ПРЕРЫВАНИЯ Цель данной главы - рассмотреть, как в ПК осуществляется ввод-вывод и как можно реализовать те операции ввода-вывода (цзСН, О()ТВЧТ и т. и.), которыми мы пользовались в предыдущей части книги. чтвввв вв аорта (ввод): 1и Аъ,в влв гл Ах,в запись в порт )завод): оот а,аь ллв оот в,ьх По кома)ше 1Х в регистр АЬ (АХ) переносится солержимое порта с номером л, а команда О()Т реализует обратное действие: в порт с номером и записывается содержиыое регистра А1. (АХ). Номер порта (л) в этих командах может быть задан двояко - либо явным числом От О до 255, либо регистром ПХ, значение которого и трактуется как номер порта.
Например: )Аг, г оорт 97Ь ;порт Взб := АХ 1Н АЬ„97Ь ИОЧ Ох,взб оот пх,ах Первый вариант операнда л используется, когда ноыер порта небольшой и известен заранее, а второй вариант - когла номер порта может быть любым или когла он становится известным только во вреьи счета програьшы. "ДИАЛОГ. МИФИ 13.1, Команды ввода-вывода Все устройства ЭВМ принято делить на внутренние и внешние. Внутренние устройсгва - это центральный процессор (ЦП) и оперативная паьить, а внешниевсе остальные устройства (внешняя память, клавиатура, дисплей, принтер и т. д.). В широком сыысле, под вводом-выводолг понимается Обмен информацией ме)гду ЦП и любым внешниы устройством.
При этом "отсчет" ведется ог ЦП: ввод - это передача данных в ЦП из внешнего устройства, а вывод - передача данных из ЦП во внешнее устройство. В ПК передача информации между ЦП и внешними устройстваыи, как правило, осущестыыется через порты. Порт - зто некоторый регистр рашером в бюп или слово, причем этот регистр находится вне ЦП и не имеет никакого отношения к обычным регистраы типа АХ, 51 и т. и. Вообще-то все порты являются байтовыми, но два соседних порта рассматриваются как порт размером в слово. Порты нумеруются, их номера - От О до ОРРРРЬ. Таким образом, потенциально может быть 65536 портов, однако реально их значительно меньше (несколько десятков).
С каждым внешним устройспюм связан свой порт или несколыго портов, их номера заранее известны. Как ЦП, так и внешнее устройство может записывать инфорлшцию в порт и может считмвать из него. Со стороны ЦП (а точнее, той программы, которую он выполняет) эти операции осуществляются с помощью следующих ыашинных команд: ВЗВ Лрогрвммнроввннв нв ввмкв вссвмбнврв ЮМ рС Сценарий ввода-вывода через порты существенмо зависит от специфики того внешнего устройспю, с которым ведется обмен, но достаточно типичным является следующий сценарий. Часто ЦП связан с внешним устройспкм двумя портамн: через один передастся данные - это порт данных, а через другой пересылается всякого рода управляющая информация - зто порт управлениа.
Когда ЦП (а точнее, программа, которую он выполняет) хочет начать обмен с каким-то внешним устройствгэг, то он записывает в порт управления этого устройства определенную комбинацию битов, которая трактуется как призыв к установлению связи. Если устройство функционирует и не занято, то в ответ оно записывает в этот порт другую комбинацию битов, снпюлизирующую о том, что оно готово к обмену. ЦП же, выждав определенное время, считмвает информацию нз порта и, если там оказался сипел о том, связь установлена, начинает собственно обмен. Пусть ЦП хочет что-то вывести.
Тогда он записывает в порт управления комбинацию символов, трактуемую как команда "выводи", а в порт данных - выводимую величину (например, код символа). Внешнее же устройство, считвв из портов згу информацию, записывает в порт упраалеиия сигнал "зыыго" и начинает собственно вывод (например, печатает символ на бумаге). В это время ЦП либо переходит в состояние ожидания, опрашивая (считывая) в цикле порт управленмя, либо занимается другой работой - до тех пор, пока в порте управления не сменится сипюл "занято". Когда внешнее устройство закончит вывод, то оно записывает в этот порт сигнал об успешном завершении своей работы или сипюл об ошибке (напрнмер, порвалась бумага в принтере).