MyVar MyStruc < >. MySegment SEGMENT
MyVar MyStruc < > Для ссылки на поля структуры используется следующий синтаксис: < имя_структуры>. < имя_поля>
Например, в команде MOV MyVar. Z, 0 происходит запись 0 в поле Z переменной MyVar. Определение структуры можно располагать в любом месте программы, но до определения переменной, использующей имя структуры. Обычно определения структур располагают вне программных сегментов для повышения читабельности текста программы. Директива EQU предназначена для определения констант, которые затем можно использовать в программе. Синтаксис директивы: < имя_константы> EQU < значение_константы>
Пример: MyConst EQU 2394
Значение константы может быть любым числовым выражением. Директива EQU может использоваться в любом месте программы, но константы должны быть определены до их первого использования в программе. Все предложения из одного программного сегмента размещаются в одном физическом сегменте памяти. Это означает, что при обращении к ячейкам памяти, заданным в программном сегменте, можно использовать один определенный сегментный регистр. Какой именно сегментный регистр будет использоваться и определяет директива ASSUME. Использование этой директивы позволяет каждый раз при обращении к данным или меткам не ставить префикс замены сегмента – это сделает транслятор, используя те данные, которые указаны в директиве ASSUME. Формат директивы: ASSUME < пара>, < пара>, …
где < пара> это < сегментный_регистр>: < имя_сегмента> Имя сегмента определяет тот программный сегмент, в котором для обращения к ячейкам памяти или меткам будет использоваться сегментный регистр, указываемый перед именем сегмента. Если сегментный регистр, который указан в директиве ASSUME, не совпадает с сегментным регистром, используемым по умолчанию в какой-либо команде, транслятор ассемблера автоматически подставит префикс замены сегмента, который в тексте программы можно не указывать. Для программных сегментов, в которых используются команды условных или безусловных переходов, а также команды вызова процедур, находящихся в этом же сегменте, для регистра CS в директиве ASSUME обязательно нужно указать имя этого программного сегмента.
Директива ASSUME не загружает значения в указанные сегментные регистры, а лишь использует их для формирования префиксов замены сегментов. Поэтому перед обращением к данным программисту необходимо записать необходимые значения в используемые для обращения к данным сегментные регистры, указанные в команде ASSUME. Для регистра CS этого делать не нужно, так как перед выполнением программы он автоматически настраивается операционной системой. Директиву ASSUME один или несколько раз можно указывать в любом месте программы. Если в нескольких директивах ASSUME указан один и тот же сегментный регистр, то действие последующей директивы ASSUME отменяет действие предыдущей. Как правило, директива ASSUME размещается в начале программного сегмента, в котором находятся команды. Это связано с тем, что директива необходима для трансляции команд, поэтому должна быть размещена перед ними. Для программных сегментов, в которых находятся только данные директиву ASSUME указывать не нужно. Пример использования директивы ASSUME в программном сегменте, содержащем команды и данные: MySegment SEGMENT ASSUME CS: MySegment, DS: MySegment < команда> . . . < команда> < вызов_функции_завершения_программы> < данные> . . . < данные> MySegment ENDS
Если в директиве ASSUME указано несколько сегментных регистров, ссылающихся на один и тот же программный сегмент, как в предыдущем примере, то транслятор ассемблера будет стараться использовать при трансляции команд тот сегментный регистр, который в какой-либо команде используется по умолчанию. Например, при обращении к данным по умолчанию будет использоваться регистр DS, если он указан в директиве ASSUME.
Если для программного сегмента, содержащего команды обращения к данным, не указать сегментный регистр, который будет использоваться при обращении к данным, транслятор ассемблера зафиксирует ошибку. Пример использования директивы ASSUME для обращения к данным в другом программном сегменте: MySegment SEGMENT ASSUME CS: MySegment, DS: DataSegment < команда> . . . < команда> MySegment ENDS
DataSegment SEGMENT < данные> . . . < данные> DataSegment ENDS
Когда в команде указывается имя ячейки памяти или метки, описанной позднее (так называемая ссылка вперед), то транслятор, не смотря на данные директивы ASSUME, использует в этой команде сегментный регистр, подразумеваемый в ней по умолчанию. Как только транслятор встречает описанное имя, он смотрит, если на него не ссылается сегментный регистр, используемый в команде по умолчанию, транслятор фиксирует ошибку. Это связано с тем, что команда уже была оттранслирована и не может быть изменена по новым данным. Если бы в предыдущем примере вместо регистра DS в директиве ASSUME стоял регистр ES, то при обращении к данным сегмента DataSegment транслятор зафиксировал бы ошибку. Этого можно избежать, если разместить программный сегмент DataSegment перед программным сегментом MySegment. Несколько подряд идущих директив ASSUME можно объединить в одну, Например последовательность директив ASSUME ES: A ASSUME DS: B, CS: C можно объединить в одну директиву
Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|