Адреса памяти

{toc_noshowall}Язык ассемблера позволяет нам присваивать символические имена адресам памяти и затем использовать эти имена в командах в качестве операндов. Задачу преобразования символических имен в истинные адреса решает ассемблер. Но во-первых, существуют задачи, при рассмотрении которых программам приходится производить вычисление машинных адресов, а во-вторых, в некоторых программах необходимо непосредственное указание адресов в качестве операндов. Таким образом, изучение машинной адресации, с одной стороны, увеличит наши возможности как программистов, а с другой стороны, позволит лучше понять принципы работы ЭВМ.

На первый взгляд проблема присваивания истинных адресов символическим именам легко разрешима. Для вычисления адресов хранимой информации относительно начала программы можно использовать счетчик, такой, например, как счетчик размещения. Если команде с символическим именем LOOP соответствует значение счетчика, равное 70, то адрес 70 можно сопоставить имени LOOP. Если в программе встретится команда

В LOOP

то машинный эквивалент данной команды в поле операндов будет содержать число 70. Но так происходит только в небольших вычислительных машинах. Числовой, или абсолютный, машинный адрес, соответствующий некоторому символическому имени, помещается в адресном поле машинной команды, содержащей данное имя в качестве операнда.

Использование абсолютных адресов в значительной степени снижает гибкость работы с памятью. В приведенном выше примере для успешной работы программы необходимо, чтобы адрес ее первого байта был равен 0. Если же программа вместо этого занесена в память, начиная, например, с байта 200, то команда LOOP будет иметь истинный адрес 270. Команда перехода вызовет передачу управления по адресу 70, т. е. даже вне пределов исходной программы, в результате чего будет иметь место действие, не имеющее ничего общего с желаемым. Вся проблема, в самом деле, заключается в том, что вопрос о размещении программ в памяти решается и программистом и ассемблером. Другими словами, адреса команд и данных обычно не совпадают с абсолютными адресами программы на машинном языке.

Эта проблема становится еще более острой, если мы хотим хранить в памяти одновременно несколько программ. Мы можем внести модификацию в общий порядок работы, с тем чтобы первый байт обрабатываемой программы помещался по адресу, отличному от 0. Мы могли бы использовать, например, такую команду ассемблеру: «Добавить 200 к счетчику размещения для получения истинных адресов». Если мы сделаем так, что программа из нашего примера будет выполняться нормально, если ее первый байт будет запомнен по адресу 200, так как, например, LOOP будет соответствовать адресу 270. Но предположим теперь, то имеется программа, требующая использования других программ или подпрограмм в процессе ее работы. В этом случае сначала необходимо спланировать ассемблирование для того, чтобы обеспечить размещение требуемых адресов в командах на местах операндов. При этом необходимо заранее знать длину каждой из программ во избежание их наложения в памяти. Кроме того, в командах передачи управления к подпрограммам необходимо указывать абсолютные адреса.

В современных мультипрограммных системах, где в памяти хранятся одновременно несколько программ, принадлежащих различным пользователям, вопросы их размещения решает операционная система. Программист не имеет возможности сам определять местонахождение своей программы в памяти. Адреса в командах машинного языка должны указываться так, чтобы обеспечить перемещаемость программ. Перемещаемой является программа, которая выполняется нормально независимо от ее расположения в памяти. Это означает, что действительные адреса операндов должны вычисляться не ассемблером и не программистом, а самой машиной на этапе выполнения программы.

Если не использовать абсолютные адреса, то как же добиться правильной результирующей адресации? Приведенный выше пример поможет нам понять это. Независимо от того, где на самом деле находится команда с именем LOOP в памяти, она всегда отстоит на 70 байтов от начала программы. Аналогично, если в эту программу включено предложение

WDS DS 2F

и имени WDS соответствует значение счетчика размещения, равное 150, то в любом случае первый байт области WDS будет 150-м от начала программы (рис. 8.1). Мы говорим в этом случае, что адрес WDS относительно начала программы равен 150. Можно представить себе адрес некоторой области А относительно другой области В как расстояние в байтах между А и В. Иначе говоря,

адрес А относительно В = адрес А — адрес В

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

 

Рис 8.1. Относительная адресация в программе

Если бы таким образом проходил процесс адресации в Системе 360, то поле адреса команды

В LOOP

содержало бы отвечающее LOOP значение, т. е. 70. Предположим, что программа помещена в память, начиная с адреса 50000. В этом случае при выполнении команды перехода загрузочный адрес 50000 будет добавлен к числу, содержащемуся в поле операндов этой команды, полученное же значение 50070 является адресом, по которому хранится команда LOOP.

В Системах 360 и 370 для обеспечения перемещаемости программ используется некоторое обобщение описанного принципа.

 

В приведенных выше примерах для вычисления относительных адресов использовался счетчик размещения. Окончательные значения адресов представляли собой сумму значений счетчика и загрузочного адреса. Однако для вычисления относительных адресов совершенно не обязательно использовать счетчики размещения. Адрес любой области в программе по отношению к адресу другой области есть константа независимо от местонахождения программы в памяти. Таким образом, любое значение адреса в программе может быть использовано в качестве базового, по отношению к которому и вычисляются все остальные адреса.

Смеи^ение для любой области — это ее адрес по отношению к выбранному базовому значению. Единственным ограничением на выбор базового значения является требование использовать лишь положительные значения смещений, не превышающие 409610

Возвращаясь к предыдущему примеру, в котором именам LOOP и WDS отвечали соответственно адреса 70 и 150, предположим, что в качестве базового значения выбрано 60. В этом случае смещение для LOOP равно 10, а для WDS — F0.

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

действительный адрес=базовый адрес+смещение

Пусть в нашем примере базовый адрес равен 50060. Действительный адрес, соответствующий имени LOOP, определяется выражением

адрес LOOP=50060+10 = 50070 а адрес WDS — выражением

адрес WDS=50060+F0=50150

Рис. 8.2. Применение базы и смещения для вычисления адресов памяти.

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

На рис. 8.2 представлены другие примеры адресации с помощью базы и смещения.

 

Значения смещений, соответствующие символическим именам, вносятся ассемблером в поле операндов команд машинного языка. При выполнении команды работы с памятью значение смещения добавляется к базовому адресу для получения конечных действительных адресов. Этот процесс формирования адреса выполняется каждый раз, когда встречается операнд, расположенный в памяти. Как же базовый адрес становится известным ЭВМ?

Логично было бы для хранения столь часто используемого значения использовать регистр, и именно такое решение реализовано в действительности. Любой регистр общего назначения, кроме регистра 0, может быть использован в качестве базового. Номер базового регистра входит составной частью в поле операнда команды машинного языка. Когда ЭВМ встречает поле адреса команды, действительный адрес определяется как сумма значения смещения и содержимого базового регистра:

действительный адрес = смещение + (базовый регистр)

Таким образом, если базовый адрес находится в базовом регистре, то все операнды адресуются должным образом.

До сих пор мы обозначали операнды, хранящиеся в памяти, как S2, говоря, что S2 представляет собой символическое имя или выражение, значением которого является адрес памяти. Это определение можно уточнить: S2 может быть любым перемещаемым символом или выражением. Перемещаемыми же программами являются те, которые могут быть перезагружены из одной части памяти в другую с сохранением возможности их выполнения. В Системах 360 и 370 перемещаемость программ достигается использованием перемещаемых имен, которым отвечают определенный базовый регистр и смещение в программе на машинном языке. Снова отметим, что именно на ассемблер возлагается задача адресации, обеспечивающей свойство перемещаемости.

Программист несет определенную ответственность за правильное задание и применение базовых регистров. Он должен выбрать базовое значение, регистр для использования в качестве базового, а также предусмотреть в программе команду загрузки в этот регистр базового адреса. Эти действия могут быть выполнены с помощью макро INITIAL; по этой команде регистр 13 устанавливается в качестве базового, и в него помещается базовый адрес. Работа с макро INITIAL подробно описана в гл. 13.

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

 

Теперь рассмотрим форму представления перемещаемого адреса, состоящего из номера базового регистра и смещения, в машинном языке. Мы уже говорили, что команды этого языка состоят из двух полей: поля операции и поля операндов. Поле операндов подразделяется на два подполя, по одному на операнд; в случае команд формата RR в обоих подполях записаны номера регистров. В случае команд работы с памятью соответствующие подполя хранят информацию о базовом регистре и значении смещения. Такие подполя мы будем называтьадресными полями S-типа, так как они используются для представления перемещаемых адресов памяти (Storage).

Смещение в машинном языке определяется как 12-битовое целое без знака. Таким образом, минимальным смещением является 000, а максимальным FFF (числа даны в шестнадцатеричной системе). В десятичном представлении это 0 и 4095 соответственно.

Номер базового регистра задается в виде 4-разрядного двоичного целого от 00012 до 11112. что соответствует шестнадцатеричным числам от 1 до F.

Адресное поле S-типа имеет длину два байта. Первые четыре разряда определяют регистр, остальные — смещение. Символически базовый регистр изображается буквой В, а смещение — D. Эти буквы обычно дополняются числами, указывающими номер операнда, к которому данный перемещаемый адрес относится. Например, В1 — это базовый регистр, соответствующий первому операнду, a D2 — смещение для второго. В этих обозначениях

действительный адрес=0+(В)

Структура же адресного поля S-типа в машинном языке такова:

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

Предположим, что 12-й регистр используется в качестве базового, а значение смещения для имени LOOP равно 38. Тогда адресное поле S-типа, отвечающее операнду LOOP, будет содержать

Отметим, что заполняться должно все поле смещения, даже если оно не все требуется для записи действительного значения. В машинном языке не может быть «пробелов».

Регистр 0 запрещается использовать как базовый. Запись числа 0 в поле базового регистра указывает на отсутствие необходимости его использования; в качестве действительного адреса в этом случае выступает смещение. Таким образом, в Системе 360 возможна и абсолютная адресация, однако максимальный адрес, который можно указать таким образом, равен 4095, или FFF.

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

Действительные адреса вычисляются специально предназначенной для этого схемой. Машинный адрес в конечном виде представляет собой 24-разрядное двоичное целое без знака, помещаемое в регистр адреса памяти (MAR). На шаге выборки операндов значение смещения посылается в регистр адреса памяти. Затем производится исследование подполя базового регистра S-поля. Если оно содержит 0, то содержимое регистра MAR остается неизменным, значение, хранящееся в нем, и является 24-разрядным действительным адресом. Если же в поле базового регистра не 0, то содержимое указанного регистра добавляется к значению, находящемуся в MAR. Результирующее содержимое регистра MAR определяет адрес, по которому будет произведена либо выборка операнда, либо запись.

 

В командах типа RX можно производить модификацию действительного адреса, указав некоторый регистр в качестве индексного. Операнд, хранящийся в памяти, символически обозначается

S2(X2)

где значение выражения S2 определяется через базовый регистр и смещение; Х2 представляет собой индекс-регистр, посредством указания которого можно провести модификацию перемещаемого адреса S2.

Действительный адрес, соответствующий S2(X2), определяется формулой

действительный адрес=52+(Х2)

Но нам уже известно, что

S2=D2+(B2)

Учитывая это, получим окончательно

действительный адрес=02+(В2)+(Х2)

Для выполнения необходимой модификации содержимое S2 добавляется к S-адресу.

Пусть, например, смещение для имени NMBRS равно 200. Если регистр 12 — базовый и содержит 00060000 (базовый адрес), а регистр 6 содержит 00000008, то по команде

ST 2,NMBRS(6)

значение (2) будет записано по адресу

200+(12)+(6)=200+ 00060000+ 00000008 = 060208

Индексированный адрес — это есть не что иное, как модифицированный S-адрес. В адресном поле Х-типа перед S-полем указывается номер соответствующего индекс-регистра. Адрес Х-типа имеет следующий вид:

Адресное поле рассмотренной выше команды

ST 2,NMBRS(6)

имеет вид

Так же, как и в случае с базовым регистром, наличие числа 0 в Х-по- ле эквивалентно указанию об отсутствии индексирования. При этом действительный адрес вычисляется просто как D2+(B2).

Возвращаясь к вычислению действительных машинных адресов, нужно сказать, что порядок вычисления S-части адреса, задаваемого Х-адресным полем, совпадаете уже описанным. После этого исследуется индексная часть поля. Если она содержит 0, то содержимоеMAR не меняется. Если не 0, то значение, хранящееся в регистре MAR, складывается с содержимым индексного регистра для получения действительного адреса.

 

Перед выполнением обращения к памяти содержимое MAR проверяется для возможной фиксации ошибок, которые бывают двух типов. Ошибка первого типа фиксируется, если адреса, оказавшегося в MAR, вообще не существуют в системе, в которой выполняется программа. Крайне редко Системы 360 и 370 обеспечиваются полным набором блоков памяти, содержащим 16 777 216 байтов. Обычно объем памяти примерно равен миллиону байтов. Следовательно, в принципе возможна ситуация, когда в MAR содержится недопустимый адрес, так как максимальное значение, которое может храниться в 24-разряд- ном регистре MAR, превышает 16 миллионов. Когда окончательное значение MAR представляет адрес, не существующий в конкретной системе, фиксируется особый случай адресации и происходит прерывание выполнения программы.

Ошибка второго типа отмечается тогда, когда адрес в MAR, вообще говоря, существует в системе, но не должен быть доступен данной программе. Для программы, выполняющейся на определенном шаге задания, при подготовке этого шага к выполнению определяется область памяти, или зона, которой она может распоряжаться. В большинстве систем запись информации вне отведенной области запрещена. В некоторых системах запрещена даже выборка информации, хранящейся вне заданной зоны. Первое из этих ограничений называется защитой памяти от записи, второе — защитой памяти от записи и выборки. Эти ограничения введены для защиты операционной системы и программ пользователей от случайного или преднамеренного непредусмотренного влияния. При попытке обращения к не принадлежащей программе памяти фиксируется особый случай защиты и происходит прерывание выполнения программы.

Ошибки первого или второго типа обычно происходят вследствие неверного использования базового или индексного регистров.

 
Статьи раздела