На главную Назад
Добро пожаловать, уважаемый посетитель!

После тогокак сегменты впрограмме определены, ассемблердолжен

узнать,какбудутустановленысегментныерегистрывовремя

выполнения программы. В примере наФиг. 3.9 всего три сегмента, но

болшаяпрограммаможетиметьнамногобольше.Располагая всего

четырьмясегментными регистрами,большая программаможет адресо-

ваться одновременно только к части доступных сегмментов. Ассемблеру

необходимо сообщить, к какимименно сегментам происходит адресация

вовремявыполнения.Этоделаетсяспомощьюоператора ASSUME

которыйописывает дляассемблера установкисегментных регистров.

Программистдолженсвязатькаждыйсегментныйрегистрстем

сегментом, на который тот в данный момент указывает.

Фиг. 3.9 иллюстрирует такие сегментные операции. В этом примере

имеется трисегмента: DATA, BUFFERи CODE. Именадля них выбраны

произвольно. Их выбирает программист, а для ассемблера они не имеют

значения.Например,выможетеназватьсегментименемCODE, а

использовать его только для данных и наооборот. Лучше всего, конеч-

но, называтьсегменты так, чтобыих имена имеликакой-то смысл в

данной программе. В нашем примересегменты DATA и BUFFER оба имеют

внутриячейку данных.Вряд лиреальная программабудет задавать

сегментлишь содной ячейкойпамяти, носейчас этослужит для

примера.Если программаобращаетсякданным вомногих участках

адресуемого в 8088 пространства,то ей требуется много определений

сегментов. Например, программауправления устройствами доступа IBM

PCможетобращатьсякпамятивсистемнойобластиданных,

устанавливать векторы прерываний вначале памяти и выполняться как

программа влюбом другом месте.Каждая из этихобластей является

сегментом и должна быть определена в программе.

Утверждение ASSUME на Фиг. 3.9 предписывает ассемблеру работать

с учетом следующейустановки сегментных регистров:регистр CS со-

держит начальный адрес сегмента CODE, регистр DS указывает на DATA,

а регистрESопределяет сегментBUFFER.УтверждениеASSUME

(полагать,считать -прим. перев.)означает именното, чтооно

предписываетассемблеру.Ассемблеробрабатываетисходныйтекст

программыпредполагая,чтосегментныерегистрыустановлены как

указано в этом утверждении. Установка сегментных регистров, сделан-

ная вэтом утверждении, остаетсяпри ассемблировании всиле пока

другое такое же утверждение не определит новые установки. Ассемблер

обрабатывает этиутверждения последовательно, дажеесли программа

ветвитсяи закручиваетсяв циклы.Утверждение ASSUMEостается в

силе,пока ассемблерне встретитпри последовательномпросмотре

программы следующее.Заметим, что в утвержденииASSUME не обязано

определятьвсе сегментныерегистры. Внашем примерене объявлен

регистр SS.На практике содержимое сегментногоргистра может быть

временамии неизвестновпрограмме.В этихслучаях утверждение

ASSUME должно указывать сегмент NOTHING. Например, утверждение

 

ASSUMEES:NOTHING

 

сообщает ассемблеру, что программане знает, куда указывает допол-

нительный сегментный регистр. Поскольку значение регистра неизвест-

но, ассемблер не должен использовать его в адресных вычислениях.

Важно отметить, что утверждение ASSUME не генерирует команд ма-

шинногоязыка. Этодиректива ассемблеруполагать, что сегментные

регистры установлены в соответствиис указанной в этом утверждении

информацией.Добитьсяправильноеустановкисегментов-забота

программиста. Аналогично, ассемблер не может проверить, что утверж-

дениеASSUMEпривыполнениибудетсоответствоватьсодержимому

сегментныхрегистров. Из-затого,чтопрограмма можетприйти к

любомуконкретномуASSUMEмножествомразныхпутей,заего

корректность отвечает программист.В нашем примере предполагается,

что сегментные регистры устанавливаютсядо выполнения данного кус-

ка программы. Если они установленыы неверно, то программа будет вы-

полняться неправильно даже если ассемблирование прошло успешно.

Первая команда увеличивает значение VAR1, находящейся в сегмен-

те данных. Ассемблер полагает, что регистр DS указывает на сегмент

DATAв соответствиис утверждениемASSUME. Посколькурегистр DS

предполагается прииспользовании данных по умолчанию,то для этой

команды ассемблер негенерирует сегментный префикс. Сформированная

этой инструкцией 4-байтовая машинная команда не содержит сегментно-

гопрефикса.

Вторая команда определяет переменнуюVAR2, которая находится в

сегментеназванномBUFFER.Программасообщилаассемблеру,что

дополнительный сегментный регистр указываетна сегмент BUFFER. Для

увеличения VAR2 ассемблер генерирует четырехбайтовую команду машин-

ного языка,но ей предшествуеткоманда с однобайтовымпрефиксом,

котораяотменяетиспользованиерегистраDSвэтойкоманде.

Префиксныйбайт 26Hговорит процессоруиспользовать при создании

20-битового адреса памяти регистр ES.В колонке объектных кодов на

листинге ассемблер отмечает префиксную команду двоеточием.

ТретьякомандаизменяетпеременнуюVAR3всегментеCODE.

Утверждение ASSUME связывает этот сегмент с регистром CS. Ассемблер

автоматическигенерируетсоответствующийпрефикспереназначения

сегмента.Вданномслучаепрефикс2EHпредписывает процессору

использоватьпривычислениииспольнительногоадреса регистр CS.

ВначалеутверждениеASSUMEпокажетсяизлишеством.В первое

время принаписании программы естественно забыватьо его примене-

нии. Ассемблер выдаст массу сообщений об ошибках чтобы помочь вам в

вашейзабывчивости. Нопри достаточномопыте, утверждение ASSUME

помогает программисту ассемблера сосредоточиться на структурах дан-

ныхвпрограмме.Программистдолженнезабывать устанавливать

сегментные регистрыдля адресации требуемыхдля программы данных.

Ассемблероблегчитбремязапоминаниядлякаждойкоманды,где

располагаютсяданныеикакойсегментныйрегистрдолженбыть

использован чтобы попасть к ним.

Программа можетиспользовать утверждение SEGMENTдля передачи

информациидругимпрограммам.ОператорSEGMENTможетзадавать

выравнивание сегмента в памяти,способ его комбинирования с други-

мисегментами иимя еготипа. Дляпрограммистов IBMPC особый

интерес представляют двавида выравнивания сегментов. Выравнивание

попараграфам(типPARA)размещаетначалосегментасначала

параграфа -ячейки памяти, адрескоторой в памятикратен 16-ти .

Этоозначает,чтопервыйбайтсегментабудет иметь смещение 0

относительно значения сегментногорегистра. Выравнивание по байтам

(типBYTE), наоборот,размещает сегментв любомместе памяти. В

этом случае сегментный регистр можети не указывать на первый байт

сегмента.В программеможет потребоватьсяненулевое смещение для

доступа к началу сегмента.

Различныеспособысвязываниясегментовзадаетпараметр типа

связи.Особенноэтополезнопримодульномпрограммировании.

Описание PUBLIC приводит к объединению всех сегментов с одинаковыми

именамив одинбольшойсегмент.Например, можнообъединить все

сегменты кодов.Это приведет к соединениюразных подпрограмм в их

собственных модулях с главной процедурой. Другой полезный тип связи

- AT,при указаниикотороговсочетании садресным выражением,

сегментрасполагаетсяпо заданномуабсолютномуадресу.Такое

объявление необходимопри работе с даннымив фиксированном месте,

например, с векторами прерываний в начале памяти.

Намногоболееполноеописаниеописаниеутверждения SEGMENT

можно найтив справочном томе кмакроассемблеру IBM PC. Некоторые

извозможностей опертораSEGMENTмыбудем использоватьдалее в

примерах.


 

Mail.ru