Главная » Просмотр файлов » Ассемблер. Компоновщик. Загрузчик. Макрогенератор

Ассемблер. Компоновщик. Загрузчик. Макрогенератор (1108377), страница 2

Файл №1108377 Ассемблер. Компоновщик. Загрузчик. Макрогенератор (Ассемблер. Компоновщик. Загрузчик. Макрогенератор) 2 страницаАссемблер. Компоновщик. Загрузчик. Макрогенератор (1108377) страница 22019-04-28СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 2)

В поле "начало" указывается начальный адрес сегмента, отсчитанный от начала программы, а в поле "размер" - количество байтов, занимаемых всеми предложениями сегмента. Кроме того, для каждого сегмента указываются значения параметров из директивы SEGMENT, с которой начинается описание данного сегмента; ради простоты из всех этих параметров (выравнивание, объединение и класс) мы далее будем учитывать только параметр "класс".

Отметим, что сам ассемблер не пользуется этой таблицей, а строит ее для компоновщика.

Таблица распределения сегментных регистров (ТРСР).

В этой таблице указывается, какому сегментному регистру какой сегмент программы поставлен в соответствие, например:

сегм.регистр сегмент

--------------------------

CS S3

DS S2

SS S1

ES --

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

1.3 ПЕРВЫЙ ПРОХОД АССЕМБЛЕРА.

Основные действия ассемблера на 1-м проходе.

Цель 1-го прохода - выявить в программе все имена и собрать информацию о них; эта информация записывается в таблицу имен (ТИ) и таблицу сегментов (ТС), которые будут нужны на 2-м проходе. Вначале эти таблицы, а также таблица распределения сегментных регистров (ТРСР) пусты, а затем они заполняются по мере просмотра текста программы.

Примеры обработки директив и команд на 1-м этапе.

Директива EQU: K EQU 3

Это директива определения константы, которая "говорит", что в программе имя K будет обозначать число 3. Эти сведения ассемблер записывает в ТИ: имя - K, тип - number, значение - 3, сегмент - пусто (не играет роли).

Директива SEGMENT: S2 SEGMENT 'DATA'

С этой директивы начинается программный сегмент. Ассемблер записывается в ТС имя сегмента (S2), его начальный адрес, отсчитанный от начала программы (при необходимости ассемблер выравнивает этот адрес до ближайшего адреса, кратного 16), и имя класса (DATA), к которому отнесен сегмент. Ассемблер также обнуляет счетчик размещения (СР), т.к. отсчет смещений начинается заново, и запоминает, что начался сегмент S1.

Директивы DB, DW, DD: X DW Y

Y DB 3 DUP(0)

По первой из этих директив ассемблер заносит в ТИ информацию об имени X: имя - X, тип - word, значение - текущая величина СР, сегмент - имя текущего сегмента (к примеру, S2), после чего СР увеличивается на 2. По второй директиве в ТИ заносится информация об имени Y: имя - Y, тип - byte, значение - текущая величина СР, сегмент - S2, после чего СР увеличивается на 3. Отметим, что на 1-м походе в эти два и три байта ничего (ни адрес Y, ни 0) не записывается, это будет сделано на 2-м проходе; сейчас важно лишь знать, сколько места будет отведено под эти переменные, на сколько надо увеличивать значение СР.

Директива PROC: P PROG FAR

Начинается описание процедуры. В ТИ заносится следующая информация об имени P: тип - far, значение - текущая величина СР, сегмент - имя текущего сегмента. Поскольку эта директива носит чисто информационный характер и по ней ничего не записывается в машинную программу, то СР не меняется.

Директива ASSUME: ASSUME S2:DATA, CS:S3, SS:S1

По этой директиве ассемблер заполняет ТРСР, создавая пары DS и S2, CS и S3, SS и S1. Поскольку эта директива носит чисто информационный характер, то СР не меняется.

Директива ENDS: S2 ENDS

Ассемблер фиксирует, что сегмент S2 закрыт, и в ТС заносит размер этого сегмента, т.е. число байтов, занятых всеми предложениями сегмента. Этот размер определяется очень просто - он равен текущему значению СР. Таким образом, СР используется не только для определения соответствия между именами и адресами, но и для подсчета размеров сегментов.

Обработка команды, например: ADD X,K

На 1-м проходе ассемблер не формирует машинные команды, поэтому сейчас ему безразлично, на какой цифровой КОП надо заменять мнемокод ADD, на какой адрес заменять имя X и т.д. Единственное, что ему сейчас важно знать, - это сколько байтов в памяти займет соответствующая машинная команда, на сколько надо увеличить СР. Это число определяется так.

Размер команды зависит (помимо мнемокода) от двух вещей: от типов операндов и от того, надо или нет перед этой командой ставить префикс сегментного регистра. (Тип операндов - байты это или слова - не влияет на размер команды, просто КОПы будут отличаться одним из битов.)

Типы операндов определяются по ТИ. Ассемблер выделяет из команды первый операнд (имя X), лезет в ТИ и узнает, что это имя переменной размером в слово, т.е. этот операнд имеет тип m16. Затем ассемблер выделяет второй операнд (имя K) и по ТИ узнает, что это имя константы со значением 3; это значение может быть байтом или словом, но поскольку тип 1-го операнда команды равен word, то и этой константе приписывается тип word, т.е. i16. (В общем случае операнды задаются более сложными выражениями, скажем BYTE PTR X или K/2+1, и их типы устанавливаются сложнее, однако, зная по ТИ типы простейших элементов этих выражений, можно установить и тип выражения в целом.) Узнав типы операндов, ассемблер лезет в таблицу мнемокодов и отыскивает в ней строку с нужным мнемокодом и нужными типами операндов, а из этой строки узнает размер соответствующей машинной команды. В нашем случае в строке для мнемокода ADD и типов m16 и i16 сказано, что размер команды равен 6.

Однако это еще не окончательный размер команды, надо еще определить, должен ли в этой команде использоваться префикс или нет. Если бы этот префикс был указан в команде явно (типа DS:X), тогда здесь проблемы не было бы. Но, как правило, в программах на ЯА такой префикс опускается с расчетом, что, если надо, его подставит сам ассемблер. Для этого ассемблер по ТИ узнает, в каком сегменте описано имя X (пусть это сегмент S2), а по ТРСР узнает, какой сегментный регистр поставлен в соответствие этому сегменту (пусть это регистр DS). Тем самым ассемблер устанавливает, что X - это на самом деле сокращение адресной пары DS:X. После этого ассемблер смотрит, не совпадает ли сегментный регистр из этой пары с тем сегментным регистром, который подразумевается в данной команде по умолчанию. Как известно, в команде ADD по умолчанию подразумевается регистр DS. Это значит, что перед нашей машинной командой можно не ставить префикс DS:. Тем самым по данной символьной команде в памяти будет занято 6 байтов, поэтому ассемблер увеличивает СР на 6 и за этом заканчивает обработку данной команды.

Но если бы имя X было описано в сегменте, на начало которого (согласно ТРСР) установлен иной регистр, скажем ES, который не совпадает с префиксом, подразумеваемым по умолчанию, тогда опускать префикс ES: перед машинной командой уже нельзя, поэтому всего символьная команда займет 6+1=7 байтов (префиксы DS:, ES: и т.п. - это самостоятельные однобайтовые машинные команды) и поэтому ассемблер увеличит СР на 7.

Директива END

По этой директиве ассемблер узнает, что текст программы закончился, поэтому он завершает свой 1-й проход. Цель этого прохода - построение ТИ и ТС - достигнута.

Особые случаи на первом проходе.

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

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

Первый случай. Пусть в программе имеется такой фрагмент:

Y DB K DB DUP(0)

X DW Y

K EQU 3

Когда ассемблер встретит первую из этих директив, то он еще не будет знать, что означает имя K. Конечно, по смыслу можно предположить, что K - это имя константы, но вот чему равно ее значение - предположить нельзя. А знать это значение очень важно уже на 1-м проходе, т.к. от этого зависит, на сколько надо увеличивать значение СР при обработке директивы DB, от этого зависит адрес имени X. Таким образом, не зная значения K, ассемблер не может правильно продолжить свою работу.

Что делает ассемблер? Поскольку в данной ситуации никаких разумных действий (кроме забегания по тексту вперед, которое требует массы времени) он предпринять не может, то он фиксирует ошибку "ссылка вперед здесь недопустима". Учитывая этот и другие подобные случаи, авторы ЯА ввели в язык ограничение: в константных выражениях нельзя использовать ссылки вперед.

Второй случай. Рассмотрим такой фрагмент программы:

CALL P

L: ...

...

P PROC FAR

Здесь обращение к процедуре P встретилось раньше ее описания, и это ставит перед ассемблером следующую проблему на 1-м проходе. Если P - имя близкой процедуры, тогда машинная команда, соответствующая символьной команде CALL, займет 3 байта памяти (она имеет вид КОП ofs, где ofs - смещение имени P), и потому ассемблер должен увеличивать СР на 3. Но если P является именем дальней процедуры, тогда соответствующая машинная команда займет 5 байтов (она имеет вид КОП ofs seg), и потому СР должен быть увеличен на 5. Так на сколько же надо увеличивать СР - на 3 или 5? А это важно знать, от этого зависит адрес метки L и всех последующих меток.

Как видно, и здесь из-за ссылки вперед ассемблер не знает, что ему делать уже на 1-м проходе. Однако фиксировать в данной ситуации ошибку неразумно, т.к. в реальных программах такие ситуации встречаются очень часто и этих ошибок было бы слишком много. Кроме того, в данной ситуации можно сделать вполне разумное предположение относительно имени P, а именно предположить, что это имя близкой процедуры (так чаще всего и бывает в реальных программах). Учитывая все это, ассемблер в данной ситуации не фиксирует ошибку, а делает предположение, что P - это имя близкой процедуры, и далее уже действует согласно этому предположению, т.е. считает, что данная команда CALL будет транслироваться в машинную команду близкого вызова, и потому увеличивает СР на 3. Но если затем окажется, что это предположение ошибочно (как в нашем примере), тогда ассемблер уже зафиксирует ошибку.

Третий случай. Предположим, в программе переменная X описана в конце сегмента команд. Тогда имя X будет использовано в команде ADD до своего описания:

ADD X,K

...

X DW Y

Встретив команду ADD, ассемблер еще не будет знать, что обозначает имя X (переменную или что-то иное), и не будет знать, в каком сегменте описано имя X, а потому не будет знать, по какому сегментному регистру должно сегментироваться это имя, надо или нет перед этой командой ставить префикс. А от всего этого зависит, сколько байтов в памяти займет соответствующая машинная команда - 6 или 7.

И здесь ассемблер не фиксирует ошибку, а предполагает, что имя X обозначает переменную (а не константу или что-то иное) и что в данной команде не должен использоваться префикс, т.е. что переменная X будет описана в сегменте, на начало которого показывает регистр, подразумеваемый по умолчанию в данной команде. Сделав такое предположение, далее ассемблер действует уже согласно ему, а именно определяет, что эта команда в целом займет в памяти 6 байтов. И опять же, если это предположение окажется ошибочным (например, у нас имя X описано в сегменте команд и потому должно сегментироваться по регистру CS), то затем будет зафиксирована ошибка.

Таковы основные случаи, когда из-за ссылок вперед ассемблер уже на 1-м проходе не знает в точности, что ему делать. Как видно, реакция ассемблера на эти случаи может быть двоякой. Если он не может сделать никаких разумных предположений относительно ссылки вперед (как в случае с константами), то он фиксирует ошибку; при этом в ЯА вводятся соответствующие ограничения. Но если можно сделать какое-то разумное предположение относительно ссылки вперед, то ассемблер делает такое предположение и далее действует согласно ему. Отметим, что эти предположения берутся не "с потолка": из всех возможных интерпретаций ссылки вперед в качестве предположения берется вариант, который наиболее часто встречается в реальных программах. Например, процедуры чаще всего бывают близкими, и именно этот вариант выбирается в команде CALL.

1.4 ВТОРОЙ ПРОХОД АССЕМБЛЕРА.

Теперь рассмотрим действия ассемблера на 2-м проходе. К этому моменту в ТИ и ТС уже собрана вся информация об именах программы. Ассемблер заново просматривает строчка за строчкой текст программы и, используя информацию из ТИ, уже переводит программу с ЯА на машинный язык.

Формируемые машинные команды ассемблер записывает в последовательные ячейки памяти начиная с некоторого адреса, кратного 16. Какой это конкретно адрес - не важно. Дело в том, что машинная программа, сформированная ассемблером, не будет тут же выполняться, а будет лишь записана во внешнюю память, поэтому ее можно формировать в любом месте памяти. Учитывая это, мы будем указывать адрес первой свободной ячейки, отсчитанный от начала этого места, и будем обозначать этот адрес как АДР. В начале АДР=0.

Примеры обработки директив и команд на 2-м проходе.

Директивы EQU и PROG игнорируются, т.к. вся информация из них уже извлечена на 1-м проходе.

Характеристики

Тип файла
Документ
Размер
224 Kb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6451
Авторов
на СтудИзбе
305
Средний доход
с одного платного файла
Обучение Подробнее