IBM PC

т.е. из неравенства код('0')<=код(c)<=код('9') следует, что c - цифра;

IBM PC

Информация

Компьютеры, программирование

Другие материалы по предмету

Компьютеры, программирование

Сдать работу со 100% гаранией
потому все ссылки на стек, в которых явно не указан сегментный

регистр, по умолчанию сегментируются по регистру 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.

1.4.4 Программные сегменты. Директива ASSUME

Рассмотрим, как сегментирование проявляется в программах на MASM.

Для того чтобы указать, что некоторая группа предложений программы

на MASM образуют единый сегмент памяти, они оформляются как программ-

ный сегмент: перед ними ставится директива SEGMENT, после них - дирек-

тива ENDS, причем в начале обеих этих директив должно быть указано од-

но и то же имя, играющее роль имени сегмента. Программа же в целом

представляет собой последовательность таких программных сегментов, в

конце которой указывается директива конца программы END, например:

DT1 SEGMENT ;программный сегмент с именем DT1

A DB 0

B DW ?

DT1 ENDS

;

DT2 SEGMENT ;программный сегмент DT2

C DB 'hello'

DT2 ENDS

;

CODE SEGMENT ;программный сегмент CODE

ASSUME CS:CODE, DS:DT1, ES:DT2

BEG: MOV AX,DT2

MOV DS,AX

MOV BH,C

...

CODE ENDS

END BEG ;конец текста программы

Предложения программного сегмента ассемблер размещает в одном сег-

менте памяти (в совокупности они не должны занимать более 64Кб) начи-

ная с ближайшего свободного адреса, кратного 16. Номер (первые 16 би-

тов начального адреса) этого сегмента становится значением имени сег-

мента. В MASM это имя относится к константным выражениям, а не адрес-

ным, в связи с чем в команде

MOV AX,DT2

второй операнд является непосредственным, поэтому в регистр AX будет

записано начало (номер) сегмента DT2, а не содержимое начальной ячейки

этого сегмента.

Имена же переменных (A, B, C) и метки (BEG) относятся к адресным

выражениям, и им ставится в соответствие адрес их ячейки относительно

"своего" сегмента: имени A соответствует адрес 0, имени B - адрес 1,

имени C - адрес 0, а метке BEG - адрес 0.

Все ссылки на предложения одного программного сегмента ассемблер

сегментирует по умолчанию по одному и тому же сегментному регистру. По

какому именно - устанавливается специальной директивой ASSUME. В нашем

примере эта директива определяет, что все ссылки на сегмент CODE долж-

ны, если явно не указан сегментный регистр, сегментироваться по регис-

тру CS, все ссылки на DT1 - по регистру DS, а все ссылки на DT2 - по

регистру ES.

Встретив в тексте программы ссылку на какое-либо имя (например, на

имя C в команде MOV AX,C), ассемблер определяет, в каком программном

сегменте оно описано (у нас - в DT2), затем по информации из директивы

ASSUME узнает, какой сегментный регистр поставлен в соответствие этому

сегменту (у нас - это ES), и далее образует адресную пару иэ данного

регистра и смещения имени (у нас - ES:0), которую и записывает в фор-

мируемую машинную команд

Лучшие

Похожие работы

<< < 2 3 4 5 6 7 8 9 10 > >>