Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ASM_lectures.doc
Скачиваний:
37
Добавлен:
28.04.2019
Размер:
992.77 Кб
Скачать

Директива assume. Инициализация сегментных регистров и замена сегментов.

В программе с помощью assume устанавливается соответствие сегмента команд text сегментному регистру CS и сегмента данных data1-сегментному регистру DS:

Assume CS:text, DS:data1

Директивы assume, которых в программе может быть любое количество, в принципе могут располагаться в любом месте программы, однако, обязательно до тех программных строк, в которых выполняется обращение описываемым в конкретной директиве сегментам, поэтому

assume CS:text

должен стоять в программе до любых программных строк и даже до объявления процедур. Что касается регистра DS , то, если это соответствие не описано в первой директиве assume, оно может быть описано позже, например:

assume DS:data1

fill: mov raw[BX],DL

Поскольку к моменту трансляции указанной выше команды mov, транслятор уже знает из директивы assume, что сегмент data1 сопоставляется с регистром DS, а имя raw описано именно в сегменте data1, команда транслируется в такой код, что процессор при его выполнении обратится к ячейке памяти с относительным адресом raw[BX], взяв сегментный адрес из регистра DS. Транслятор выполняет (не слишком строгую) проверку правильности ссылок на данные, так что если бы ячейка raw входила в другой сегмент, была бы зафиксирована ошибка. Т.о. описание в директиве assume соответствия сегментного регистра DS сегменту данных позволяет в какой то степени контролировать правильность написания программы и, главное, избавляет нас от необходимости указывать в каждой строке, содержащей ссылку на имя данных, в каком сегментном регистре находится сегментный адрес этих данных. По умолчанию подразумеваться регистр DS.

Однако из сказанного совершенно не следует, что к моменту выполнения команды mov в регистре DS будет в действительности находиться сегментный адрес соответствующего сегмента. Более того, его там и не будет, если мы об этом специально не позаботимся. Строки

mov AX,data1

mov DS,AX

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

Несколько по иному обстоит дело с дополнительными сегментами данных, к которым мы будем обращаться через сегментный регистр ES. Поскольку в программе регистр ES в директиве не описан, его следует указывать в явной форме во всех предложениях программы, где выполняется адресация к дополнительному сегменту данных data2:

mov ES:oddbit[DI],DL

….

Parity: mov ES:evenbit[SI],DL

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

mov AX,data2

mov ES,AX

Директива assume создать умолчание и для регистра ES. Однако, для этого необходимо, чтобы дополнительный сегмент данных data2 был описан в программе до сегмента команд:

data2 segment

data2 ends

text segment ‘code’

. assume CS:text, DS:data1,ES:data2

.

. mov oddbit[DI],DL ;по умолчанию берется регистр ES , т.к.

;oddbit находится в data2

В этом случае директива assume ES:data2 избавляет нас от необходимости указывать в явной форме регистр ES во всех командах с обращением к данным из сегмента data2. Если таких строк много, то это несколько упрощает процесс написания программы. Некоторого улучшения можно достигнуть, заменив адресацию со смещением на чисто регистрово-базовую, индексную или базово-регистровую.

mov BX,offset raw;

fill: mov [BX],DL

mov SI, offset evenbit

mov DI, offset oddbit

pros: mov DL,[BX]

mov ES:[DI],DL

parity: mov ES:[SI],DL

Во всех 3-х массивах теперь пересчитываются не индексы внутри массивов, а смещение блоков массивов относительно начал соответствующих сегментов. Директива позволяет в некоторых случаях не указывать в командах программы сегментные регистры, однако она не запрещает это делать в случае необходимости. Часто к одному сегменту приходится обращаться то через один, то через другой сегментный регистр. Такая ситуация типична при выполнении команд обработки строк.

Источник ES:DI

Приёмник DS:SI

И потом источник и приёмник меняются местами

Здесь как бы не было объявлено соответствие сегментных регистров, придётся воспользоваться префиксом замены сегмента.

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

; Сегмент данных

data segment

mem1 DW ?

mem2 DW ?

data ends

;ПРОГРАММНЫЕ СТРОКИ В СЕГМЕНТЕ КОМАНД

assume DS:data

mov AX,mem1 ;команда будет выполняться

mov BX,mem2 ; как AX,DS:mem1

assume DS:nothing

assume ES:data ;команда будет выполняться

mov AX,mem1 ; как AX,ES:mem1

mov BX,mem2

Директива assume DS:nothing (ничего) снимает закрепление за сегментом data регистра DS и позволяет закрепить за сегментом другой регистр assume ES:data.

Очевидно, что независимо от директивы assume, перед первым участком необходимо настроить на сегмент data регистр DS, а перед вторым-ES.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]