Сегментные регистры по умолчанию




Согласно описанной схеме сегментирования адресов, замену абсолют­ных адресов на адресные пары надо производить во всех командах, имею­щих операнд-адрес. Однако разработчики ПК придумали способ, позволяю­щий избежать выписывания таких пар в большинстве команд. Суть его в том, что заранее договариваются о том, какой сегментный регистр на ка-

кой сегмент памяти будет указывать, и что в командах задается только смещение: не указанный явно сегментный регистр автоматически восста­навливается согласно этой договоренности. И только при необходимости нарушить эту договоренность надо полностью указывать адресную пару.

Что это за договоренность?

Считается, что регистр CS всегда указывает на начало области памя­ти, в которой размещены команды программы (эта область называется сег­ментом команд или сегментом кодов), и потому при ссылках на ячейки этой области регистр CS можно не указывать явно, он подразумевается по умолчанию. (Отметим попутно, что абсолютный адрес очередной команды, подлежащей выполнению, всегда задается парой CS:IP: в счетчике команд IP всегда находится смещение этой команды относительно адреса из реги­стра CS.) Аналогично предполагается, что регистр DS указывает на сег­мент данных (область памяти с константами, переменными и другими вели­чинами программы), и потому во всех ссылках на этот сегмент регистр DS можно явно не указывать, т.к. он подразумевается по умолчанию. Регистр SS, считается, указывает на стек - область памяти, доступ к которой осуществляется по принципу "последним записан - первым считан" (см. 1.7), и потому все ссылки на стек, в которых явно не указан сегментный регистр, по умолчанию сегментируются по регистру SS. Регистр ES счита­ется свободным, он не привязан ни к какому сегменту памяти и его можно использовать по своему усмотрению; чаще всего он применяется для дос­тупа к данным, которые не поместились или сознательно не были размеще­ны в сегменте данных.

С учетом такого распределения ролей сегментных регистров машинные программы обычно строятся так: все команды программы размещаются в од­ном сегменте памяти, начало которого заносится в регистр CS, а все данные размещаются в другом сегменте, начало которого заносится в ре­гистр DS; если нужен стек, то под него отводится третий сегмент памя­ти, начало которого записывается в регистр SS. После этого практически во всех командах можно указывать не полные адресные пары, а лишь сме­щения, т.к. сегментные регистры в этих парах будут восстанавливаться автоматически.

Здесь, правда, возникает такой вопрос: как по смещению определить, на какой сегмент памяти оно указывает? Точный ответ приведен ниже (см. 1.4.3), а в общих чертах он такой: ссылки на сегмент команд могут быть только в командах перехода, а ссылки практически во всех других коман­дах (кроме строковых и стековых) - это ссылки на сегмент данных. Нап­ример, в команде пересылки

MOV AX,X

имя X воспринимается как ссылка на данное, а потому автоматически вос­станавливается до адресной пары DS:X. В команде же безусловного пере­хода по адресу, находящемуся в регистре BX,

JMP BX

абсолютный адрес перехода определяется парой CS:[BX].

Итак, если в ссылке на какую-то ячейку памяти не указан явно сег­ментный регистр, то этот регистр берется по умолчанию. Явно же сегмен­тные регистры надо указывать, только если по каким-то причинам регистр по умолчанию не подходит. Если, например, в команде пересылки нам надо сослаться на стек (скажем, надо записать в регистр AH байт стека, по­меченный именем X), тогда нас уже не будет устраивать договоренность о том, что по умолчанию операнд команды MOV сегментируется по регистру DS, и потому мы обязаны явно указать иной регистр - в нашем случае ре­гистр SS, т.к. именно он указывает на стек:

MOV AH,SS:X

Однако такие случаи встречаются редко и потому в командах, как прави­ло, указываются только смещения.

Отметим, что в MASM сегментный регистр записывается в самой коман­де непосредственно перед смещением (именем переменной, меткой и т.п.), однако на уровне машинного языка ситуация несколько иная. Имеется 4 специальные однобайтовые команды, называемые префиксами замены сегмен­та (обозначаемые как CS:, DS:, SS: и ES:). Они ставятся перед коман­дой, операнд-адрес которой должен быть просегментирован по регистру, отличному от регистра, подразумеваемому по умолчанию. Например, приве­денная выше символическая команда пересылки - это на самом деле две машинные команды:

SS:

MOV AH,X

1.4.3 Сегментирование, базирование и индексирование адресов Поскольку сегментирование адресов - это разновидность модификации

адресов, то в ПК адрес, указываемый в команде, в общем случае модифи­цируется по трех регистрам - сегментному, базовому и индексному. В це­лом, модификация адреса производится в два этапа. Сначала учитываются только базовый и индексный регистры (если они, конечно, указаны в ко­манде), причем вычисление здесь происходит в области 16-битовых адре­сов; полученный в результате 16-битовый адрес называется исполнитель­ным (эффективным) адресом. Если в команде не предусмотрено обращение к памяти (например, она загружает адрес в регистр), то на этом модифика­ция адреса заканчивается и используется именно исполнительный адрес (он загружается в регистр). Если же нужен доступ к памяти, тогда на втором этапе исполнительный адрес рассматривается как смещение и к не­му прибавляется (умноженное на 16) содержимое сегментного регистра, указанного явно или взятого по умолчанию, в результате чего получается абсолютный (физический) 20-битовый адрес, по которому реально и проис­ходит обращение к памяти.

Отметим, что сегментный регистр учитывается только в "последний" момент, непосредственно перед обращением к памяти, а до этого работа ведется только с 16-битовыми адресами. Если учесть к тому же, что сег­ментные регистры, как правило, не указываются в командах, то можно в общем-то считать, что ПК работает с 16-битовыми адресами.

Как уже сказано, если в ссылке на ячейку памяти не указан сегмент­ный регистр, то он определяется по умолчанию. Это делается по следую­щим правилам.

1) В командах перехода адрес перехода сегментируется по регистру CS и только по нему, т.к. абсолютный адрес команды, которая должна быть выполнена следующей, всегда определяется парой CS:IP (попытка из­менить в таких командах сегментный регистр будет безуспешной).

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

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

JMP X

имя X сегментируется по регистру DS, а вот адрес перехода, взятый из ячейки X, уже сегментируется по регистру CS.

2) Адреса во всех других командах, кроме строковых (STOS, MOVS, SCAS и CMPS), по умолчанию сегментируются:

- по регистру DS, если среди указанных регистров-модификаторов нет регистра BP;

- по регистру SS, если один из модификаторов - регистр BP.

Таким образом, адреса вида A, A[BX], A[SI], A[DI], A[BX][SI] и A[BX][DI] сегментируются по регистру DS, а адреса A[BP], A[BP][SI] и A[BP][DI] - по регистру SS, т.е. адреса трех последних видов использу­ются для доступа к ячейкам стека.

3) В строковых командах STOS, MOVS, SCAS и CMPS, имеющих два опе­ранда-адреса, на которые указывают индексные регистры SI и DI, один из операндов (на который указывает SI) сегментируется по регистру DS, а другой (на него указывает DI) - по регистру ES.



Поделиться:




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

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


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