Сегментация памяти процессора 8086 и сегментные регистры
Основной предпосылкой сегментации является следующее: процессор 8086 может адресоваться к 1 мегабайт)" памяти. Для адресации ко всем ячейкам адресного пространства в 1 мегабайт необходимы 20-разрядные сегментные регистры. Однако процессор 8086 использует только 16-разрядные указатели на ячейки памяти. Вспомним, например, что для ссылки на память используется 16-разрядный регистр ВХ. Как же тогда согласовать 16-разрядные указатели процессора 8086 и 20-разрядные адреса?
Ответ состоит в том, что процессор 8086 использует двухступенчатую схему адресации. Да, используются 16-разрядные указатели, но эта форма представляет собой только часть полной схемы адресации. Каждый 16-разрядный указатель памяти или смешение комбинируется с содержимым 16-разрядного сегментного регистра для формирования 20-разрядного адреса памяти.
Рисунок 1. 20-разрядные адреса памяти
Сегменты и смешения комбинируются следующим образом: значение сегмента сдвигается влево на 4 разряда (то есть умножается на 16). а затем складывается со смешением, как показано на рисунке 1.
Рассмотрим, например, следующий фрагмент программы:
mov ax,1000h
mov ds,ax
mov si,201h
mov dl,[si]
Здесь для сегментного регистра DS устанавливается значение l000h, SI устанавливается в значение 20Ш. Мы можем представить их в виде "сегмент: смещение" - 1000:201h. Адрес, из которого загружаются данные в DL. представляет собой:
((DS * 16) + SI) или ((l000h * 16) + 201h)
Итак, программа получает доступ к полном>" адресному пространству в 1 мегабайт с помощью использования только пары "сегмент: смешение". Все инструкции и режимы адресации процессора 8086 по умолчанию работают относительно того или иного сегментного регистра, хотя в некоторых инструкциях можно явно указать, что нужно использовать желаемый сегментный регистр. Обычно редко требуется загружать значение непосредственно в сегментный регистр, а вместо этого сегментные регистры в программе имеют символические имена сегментов, которые в ходе ассемблирования, компоновки и выполнения превращаются в числа. Это необходимо, поскольку нет способа сказать заранее, где в памяти будет находиться данный сегмент: это зависит отверсии DOS, числа и размера резидентных в памяти программ, а также потребности в памяти остальной части программы. Использование имен сегментов позволяет Турбо Ассемблеру и операционной системе DOS выполнять подобные вычисления.
Наиболее общим именем сегмента для размещения данных является @Data. которое в упрощенных директивах определения сегментов используется для ссылки на используемый по умолчанию сегмент данных. Например:
dosseg
.model small
.data
varl dw 0
.code
mov ax, @ data
mov ds,ax
end
Здесь регистр DS загружается таким образом, что он будет указывать на используемый по умолчанию сегмент данных, в котором находится Varl.
Так как 64К - это максимальный объем памяти, к которой можно адресоваться с помощью 16-битового смещения, то при работе с большим (более 64К) объемом памяти значение сегментного регистра и смешение придется часто изменять.
Сегментные регистры не могут использоваться в качестве источников или приемников в арифметических и логических инструкциях и единственная операция, которую можно выполнять с сегментными регистрами, состоит в копировании значений между сегментными регистрами и другими общими регистрами или памятью. Например, чтобы добавить значение 100 к регистру ES, потребуется следующее:
mov ax,es
add ах. 100
mov es.ax
Из всего этого можно сделать заключение, что процессор 8086 лучше подходит для работы с памятью в блоках, не превышающих 64К.
Ещё одна особенность использования сегментов состоит в том, что каждая ячейка памяти адресуется через многие возможные сочетания "сегмент: смешение". Например, адрес памяти 100h адресуется с помощью следующих значений "сегмент: смешение": 0:100h, l:F0h, 2:E0h и т.д., так как при вычислении всех этих пар "сегмент: смешение" получается значение адреса 100h.
Аналогично регистрам общего назначения каждый сегментный регистр играет свою, конкретную роль. Регистр CS указывает на код программы, DS указывает на данные, SS - на стек, сегмент (сегментный регистр) ES – это "трафаретный" (дополнительный) сегмент, который может использоваться так, как это необходимо.
Регистр CS указывает на начало блока памяти объемом 64К, или сегмент кода, в котором находится следуюшая выполняемая инструкция. Следуюшая инструкция, которую нужно выполнить, находится по смешению, определяемому в сегменте кода регистром IP. то есть на нее указывает адрес (в форме "сегмент:смещение") CS: IP. Никакие другие режимы адресации или указатели памяти, отличные от IP, не могут нормально работать относительно регистра CS.
Регистр DS указывает на начало сегмента данных, которые представляет собой блок памяти объемом 64К, в котором находится большинство размешенных в памяти операндов. Обычно для ссылки на адреса памяти используются смещения, предполагающие использование регистров ВХ, SI или DI.
Регистр ES указывает на начало блока памяти объемом 64К, который называется дополнительным сегментом. Как и подразумевает его название, дополнительный сегмент не служит для какой-то конкретной цели, но доступен тогда, когда в нем возникает необходимость. Иногда дополнительный сегмент используется для выделения дополнительного блока памяти объемом 64К для данных. Однако доступ к памяти в дополнительном сегменте менее эффективен, чем доступ к памяти в сегменте данных. Особенно полезен дополнительный сегмент, когда используются строковые инструкции. Все строковые инструкции, которые выполняют запись в память, используют в качестве адреса памяти, в которую нужно выполнить запись, пару регистров ES:DI. Это означает, что регистр ES особенно полезен при использовании его в качестве целевого сегмента при копировании блоков, сравнении строк, просмотре памяти и очистке блоков памяти.
Регистр SS указывает на начало сегмента стека, которые представляет собой блок памяти объемом 64К. в котором находится стек. Все инструкции, которые неявно используют регистр SP (включая занесение в стек, извлечение из стека, вызовы и возвраты управления), работают с сегментом стека, так как только регистр SP может использоваться для адресации памяти в сегменте стека. Как мы обсуждали ранее, регистр BP также работает относительно сегмента стека. Это позволяет использовать регистр BP для доступа к параметрам и переменным, которые хранятся в стеке.
Итак, чтобы на практике просмотреть все выше описанные примеры использования регистров и средств управления оперативной памятью, наиболее удобно воспользоваться программой-отладчиком DEBUG.
Лекция 31
Дата добавления: 2016-07-05; просмотров: 3967;