Предназначение сегментов




Каждый из сегментных регистров имеет свое, отмеченное выше назначение. В некоторых случаях, однако, более удобна связь с данными вне сегмента данных, например, с небольшой областью данных в программе. В большинстве случаев программа работает с данными в той области, на которую указывает регистр DS, но иногда программе требуется ссылка на локальную переменную, находящуюся в кодовом сегменте программы. Чтобы осуществитьэту ссылку, приходится изменять обычное использование сегментов. Фиг.3.8 показывает такую органзацию программы.

Сегмент Программа и локальные данные
CS CS:LOCAL_VALUE
DS DS:Основная область даных

Фиг. 3.8 Переназначение CS на локальные данные.

Вместо изменения значения регистра DS, чтобы он указывал на программный сегмент, команда изменяет ссылку на данные, показывая, что переменная расположена в сегменте кодов (Code Segment).

< CS:LOCAL_VARIABLE INC>

Это делается с помощью префикса "CS:". В машинном языке команда переопределения сегмента выглядит как однобайтовый префикс перед обычной командой машинного языка. 8088 понимает этот префикс переназначения сегмента и изменяет обычный способ вычисления адреса. Вместо регистра DS процессор использует для вычисления физического адреса данных регистр CS. Одного префикса в команде всегда достаточно, таккак 8088 может адресоваться в ней не более чем к одной ячейке памяти. Для нормального обращения к данным команда может использовать любой из четырех сегментных регистров. Регистр DS используется по умолчанию, то есть когда в команде не указан другой сегментный регистр, то используется DS. Помните, что при использовании в адресных вычислениях регистра BP сегментом по умолчанию становится стековый сегмент. Команда может определить и любой из трех других сегментных регистров, указав его в адресном выражении. Некоторые команды, правда,не могут пользоваться переназначением сегментов. Это - команды обработки строк. Строковая команда определяет использование регистров неявным образом, и оно не может быть изменено. В главе 4 мы обсудим строковые команды и их специфическое пользование сегментами.

Оператор Segment

Решить проблему адресации сегментов поможет ассемблер. В одной из своих частей программа на языке ассемблера должна определить составляющие еесегменты. Кроме того специальные команды сообщают ассемблеру, какие сегменты с каким регистром связаны. Благодаря этому ассемблер может, когда требуется, определить какой сегментный префикс нуженв коде команды. Если программист задает ссылку, не связанную с регистром DS, но доступную через другой сегментный регистр, то ассемблер сам сформирует правильный префикс. Это позволяет программисту работать непосредственно с данными и текстом программы, оставив ассемблеру работу по осуществлению адресации. Объявление сегментов позволяет ассемблеру следить за тем, какие сегменты доступны через сегментные регистры и определять возможные ошибки. Например, в программе могут появиться переменные, которые недоступны из-за того, что на сегмент этой переменной не указывает ни один из сегментных регистров. Ассемблер квалифицирует это как ошибку. Она возникает из-за того, что в программе не обеспечена адресуемость.Это ограничение, но лучше обнаружить ошибку при ассемблировании, чем во время работы программы. Оператор SEGMENT определяет все сегменты, давая каждому из них имя. Программа на Фиг. 3.9 демонстрирует определение нескольких сегментов.

Microsoft (R) Macro Assembler Version 5.00 1/1/80 03:53:05Фиг. 3.9 Сегменты Page 1-1 PAGE,132TITLE Фиг. 3.9 Сегменты0000 DATA SEGMENT0000 01 VAR1: DB 1; Переменная в сегменте DATA0001 DATA ENDS0000 BUFFER SEGMENT0000 02 VAR2: DB 2; Переменная в сегменте BUFFER0001 BUFFER ENDS0000 CODE SEGMENT0000 03 VAR3: DB 3; Переменная в сегменте CODE ASSUME CS:CODE, DS:DATA, ES:BUFFER0001 FE 06 0000 R INC VAR1;Переменная из сегмента DATA0005 26: FE 06 0000 R INC VAR2;Переменная из сегмента BUFFER000A 2E: FE 06 0000 R INC VAR3;Переменная из сегмента CODE000F CODE ENDS END Фиг. 3.9 Сегменты

В качестве имени сегмента может использоваться любое допустимое имя переменной. Утверждение SEGMENT сообщает ассемблеру, что все следующие команды и данные во время выполнения программы будут находиться в этом сегменте. Оператор ENDS указывает конец текущего сегмента. В этом утверждении тоже указывается имя сегмента. Каждому утверждению SEGMENT должно соответствовать утверждение ENDS. В противном случае ассемблер запутается и выдаст сообщение об ошибке.

Оператор Assume

После того как сегменты в программе определены, ассемблер должен узнать, как будут установлены сегментные регистры во время выполнения программы. В примере на Фиг. 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. Например, утверждение

ASSUME ES: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 может задавать выравнивание сегмента в памяти, способ его комбинирования с другими сегментами и имя его типа. Для программистов IBM PC особый интерес представляют два вида выравнивания сегментов. Выравнивание по параграфам (тип PARA) размещает начало сегмента с начала параграфа - ячейки памяти, адрес которой в памяти кратен 16-ти. Это означает, что первый байт сегмента будет иметь смещение 0 относительно значения сегментного регистра. Выравнивание по байтам (тип BYTE), наоборот, размещает сегмент в любом месте памяти. В этом случае сегментный регистр может и не указывать на первый байт сегмента. В программе может потребоваться ненулевое смещение для доступа к началу сегмента.

Различные способы связывания сегментов задает параметр типа связи. Особенно это полезно при модульном программировании. Описание PUBLIC приводит к объединению всех сегментов с одинаковыми именами в один большой сегмент. Например, можно объединить все сегменты кодов. Это приведет к соединению разных подпрограмм в их собственных модулях с главной процедурой. Другой полезный тип связи - AT, при указании которого в сочетании с адресным выражением, сегмент располагается по заданному абсолютному адресу. Такое объявление необходимо при работе с данными в фиксированном месте, например, с векторами прерываний в начале памяти. Намного более полное описание описание утверждения SEGMENT можно найтив справочном томе к макроассемблеру IBM PC. Некоторые из возможностей опертора SEGMENT мы будем использовать далее в примерах.

Управляющие рагистры

Для операций управления в процессоре 8088 используются главным образом три 16-битовых регистра. Это указательстека (SP), указатель команды (IP) и регистр флагов. Два регистра-указателя процессор использует для необходимой при выполнении программы адресации в памяти. Регистр флагов содержит коды состояний, которые программа может использовать для управления своим выполнением.



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-02-16 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: