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

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

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

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

Здесь OMi.OBJ - объектные файлы, которые надо объединять, а M.EXE - файл для размещения объединенной машинной программы.

2.1 Основные задачи компоновщика.

Начав работу, компоновщик считывает из внешней памяти указанные ОМ, объединяет их в единую машинную программу, которую записывает во внешнюю память, в указанный файл. Эту программу принято называть исполняемой или выполняемой программой, но чаще используется название загрузочный модуль (ЗМ), которым далее и будет пользоваться.

Более точно, задачи, которые должен решить компоновщик, следующие:

1) Объединение модулей. Компоновщик должен определить, в каком порядке в окончательной программе должны располагаться сегменты, входящие в модули, и должен в этом порядке собрать машинные коды (тела) этих сегментов, чтобы получить единый машинный код всей программы. (Замечание: компоновщик должен также осуществлять слияние некоторых сегментов из разных модулей в единые сегменты, однако для простоты эта функция компоновщика не рассматривается.)

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

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

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

Рассмотрим, как компоновщик решает каждую из указанных задач.

2.2 Объединение модулей.

Свою работу компоновщик начинает с того, что считывает в оперативную память заголовки всех ОМ, указанных в приказе LINK. Далее он определяет, в каком порядке будут располагаться в окончательной программе сегменты из ее модулей и фиксирует эту информацию в общей таблице сегментов (ОТС).

Эта таблица строится на основе таблиц сегментов (ТС) из модулей. Пусть, к примеру, в программе имеются два модуля М1 и М2 с такими ТС:

модуль М1: модуль М1:

сегмент нач.адрес размер класс сегмент нач.адрес размер класс

(в модуле) (в модуле)

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

S1 0 1000 STACK Q1 0 22 DATA

S2 1000 8 DATA Q2 30 103 CODE

S3 1010 625 CODE

Тогда ОТС будет иметь следующий вид:

сегмент модуль начальный адрес размер класс

в модуле в пр-ме

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

S1 M1 0 0 1000 STACK

S2 M1 1000 1000 8 DATA

Q1 M2 0 1010 22 DATA

S3 M1 1010 1040 625 CODE

Q2 M2 30 1670 103 CODE

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

длина программы: 1670 + 103 = 1773

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

Первое, что должен сделать компоновщик, - это так расположить сегменты, чтобы сегменты одного класса оказались рядом. Решается эта задача следующим образом. Из заголовка ОМ, указанного в приказе LINK первым (у нас это M1), берется ТС и информация из нее переносится в ОТС (колонка "нач. адрес в программе" пока пуста). Затем берется ТС из ОМ, указанного в приказе LINK вторым (у нас - из M2), и последовательно рассматриваются перечисленные в ней сегменты. Первым идет сегмент Q1; смотрится, какого он класса и нет ли уже в ОТС сегмента того же класса. Есть, это S2. Значит, S2 и Q1 должны располагаться рядом. Поэтому строка с S3 сдвигается вниз, а после S2 записывается информация о Q1. Берется следующий сегмент Q2; он того же класса, что и сегмент S3; значит, S3 и Q2 должны быть расположены рядом. Однако в данном случае ничего в ОТС сдвигать не надо и информация о Q2 записывается в конец ОТС. Поскольку больше модулей и сегментов нет, то получившееся расположение сегментов является окончательным, именно так они и будут расположены в объединенной программе.

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

Далее компоновщик пересчитывает начальные адреса сегментов. Дело в том, что в ТС модулей указаны адреса сегментов относительно начала модулей, а теперь нужны адреса сегментов относительно начала всей программы. Такой пересчет делается просто. Первый сегмент S1, естественно, получает смещение 0. Поскольку он занимает 1000h байтов, то адрес первой свободной ячейки за ним равен 1000h. Это адрес кратен 16, поэтому с него можно начинать размещать следующий сегмент, поэтому этот адрес становится начальным адресом сегмента S2. Этот сегмент занимает 8 байтов, поэтому первый свободный адрес за ним - 1008h, но этот адрес не кратен 16 и с него нельзя начинать сегмент. Компоновщик берет ближайший адрес, кратный 16 (у нас это 1010h), и именно его делает начальным адресом следующего сегмента Q1. Аналогично по адресу и длине сегмента Q1 определяется начальный адрес для сегмента S3 (это 1040h), а по адресу и длине сегмента S3 определяется начальный адрес сегмента Q2 (это 1670h). Тем самым адреса всех сегментов относительно начала программы установлены.

Отметим попутно, что если сложить начальный адрес последнего сегмента (1670h) и длину этого сегмента (103h), то мы получим размер всей программы (1773h). Это число запоминается, оно еще пригодится.

Составив ОТС и тем самым определив, как внутри программы должны располагаться сегменты, компоновщик далее считывает с диска машинные коды (тела) ОМ в оперативную память и размещает их сегменты согласно указанному в ОТС порядку. Делается это так. В какое-то свободное место ОП считываются весь машинный код модуля M1, а затем сегменты этого модуля переносятся в соответствующие места той части ОП, где формируется машинный код всей программы (сколько переписывать, откуда и куда - все это определяется по ОТС). В нашем случае первые 1000h байтов из M1 переписываются в программу по адресу 0, затем 8 байтов из M1 начиная с его адреса 1000h переписываются в программу по адресу 1000h и, наконец, переписываются 625h байтов из M1 начиная с его адреса 1010h переписываются в программу по адресу 1040h. Затем аналогично поступают с сегментами из модуля M2:

M1 M M2

0 ┌────┐ 0 ┌────┐ 0 ┌────┐

│ S1 │ ────> │ S1 │ ┌────── │ Q1 │

1000 │────│ 1000 │────│ │ 30 │────│

│ S2 │ ────> │ S2 │ │ ┌──── │ Q2 │

1010 │────│ 1010 │────│ │ │ └────┘

│ S3 │ ─┐ │ Q1 │ <─┘ │

└────┘ │ 1040 │────│ │

└──> │ S3 │ │

1670 │────│ │

│ Q2 │ <───┘

└────┘

Собранные таким образом машинные коды сегментов и образуют машинный код единой программы. На этом этап объединения модулей завершен. После некоторой корректировки этот код станет телом ЗМ.

2.3 Редактирование межмодульных связей

Такая корректировка заключается в замене внешних имен, использовавшихся в модулях, на соответствующие адреса. Делается это так.

Напомним, что в заголовке каждого ОМ есть таблица общих имен (ТОБ), в которой для каждого общего имени данного модуля указано само имя и его адрес внутри модуля. Компоновщик выделяет из заголовков эти таблицы и объединяет их в общую таблицу общих имен (ОТОБ). Например, если в программе имеется два модуля М1 и М2 с такими ТОБ:

модуль М1: модуль М1:

общее имя адрес общее имя адрес

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

B S2:2 X Q1:20

P Q2:0

тогда ОТОБ будет выглядеть так:

Общая ТОБ: общее имя адрес

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

B S2:2

X Q1:20

P Q2:0

Теперь вспомним, что общее имя одного модуля - это внешнее имя другого модуля. Значит, ОТОБ - это одновременно и таблица всех внешних имен с указанием их адресов. Поэтому компоновщик теперь может сделать то, что в свое время не удалось сделать ассемблеру, - заменить все внешние ссылки во всех модулях на соответствующие им адреса.

Для этого компоновщик использует таблицы вхождений внешних имен (ТВН) из объектных модулей. Напомним, что в такой таблице указаны сведения о каждом вхождении в модуль каждого внешнего имени, а именно: само имя, адрес ячейки, в которую надо записать адрес имени, и то, какую часть адреса имени надо использовать. Компоновщик проходится по всем этим таблицам и делает замены.

Пусть, к примеру, в модуле М1 была такая ТВН:

внеш.имя адрес вхождения тип вхождения

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

X S2:0 ofs

X S2:2 seg

P S2:6 segofs

Первая ее строка указывает, что смещение имени X надо записать в ячейку с адресом S2:0, т.е. в 0-ю ячейку сегмента S2. Смещение имени X компоновщик узнает по ОТОБ, оно равно 20h, а начальный адрес сегмента узнает по ОТС, он равен 1000h, поэтому число 20h он заносит в ячейку с адресом 1000h+0=1000h, отсчитанным от начала программы.

Следующая строка таблицы указывает, что в ячейку с адресом S2:2 надо записать номер сегмента (начальный адрес без последнего 0), в котором находится ячейка с именем X. По ОТОБ компоновщик узнает, что сегментом имени X является Q1. Однако компоновщик не знает настоящий начальный адрес этого сегмента: он знает только его адрес относительно начала программы, а настоящий же адрес зависит от того, с какого места памяти будет расположена вся программа при счете, а это пока неизвестно. Что делать компоновщику? Напомним, что с такой же проблемой сталкивается и ассемблер. Как поступает ассемблер? Он ничего не записывает в соответствующую ячейку, но в таблице перемещаемых адресов (ТПА) запоминает, что затем в эту ячейку надо будет записать номер этого сегмента. Аналогично поступает и компоновщик: он строит свою (новую) ТПА, где запоминает, в какие ячейки он должен был бы записать номера каких сегментов, но не смог этого сделать. У нас в этой ТПА появится первая из следующих строк:

имя сегмента адрес вхождения

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

Q1 S2:2

Q2 S2:8

...

Третья строка ТВН из модуля M1 указывает, что в ячейку S2:6 надо записать и смещение, и номер сегмента имени P, т.е. здесь объединены два уже рассмотренных нами случая. Узнав по ОТОБ, что смещение имени P равно 0, компоновщик записывает 0 в ячейку S2:6. Из ОТОБ компоновщик узнает, что имя P - из сегмента Q2, однако записать номер этого сегмента во вторую половину данной ячейки (в S2:8) не может, поэтому он добавляет в свою ТПА новый элемент - вторую из указанных выше строк.

Далее компоновщик просматривает ТВН из следующих модулей и поступает с ними аналогично.

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

2.4 Построение заголовка загрузочного модуля.

Но на этом работа компоновщика не заканчивается, он еще должен построить заголовок ЗМ, включив в него информацию, по которой затем можно будет дотранслировать программу до конца и запустить ее на счет.

В упрощенном виде заголовок ЗМ состоит из следующих разделов: 1) длина программы; 2) точка входа; 3) начало и длина сегмента стека; 4) таблица перемещаемых адресов.

Прежде чем рассмотреть, как компоновщик заполняет эти разделы, отметим следующее. До сих пор адреса каких-то мест в ЗМ были представлены в условной форме - с указанием имен сегментов (типа S2:8). Однако в дальнейшем имена сегментов никому не нужны, а нужны только адреса сегментов, поэтому компоновщик должен заменить имя сегмента (S2) на его начальный адрес. Но этот адрес компоновщик не знает, т.к. он зависит от того, с какого места в памяти будет размещена программа во время счета, а это станет известным только позже. Что делать?

Отметим, что абсолютный, адрес (Aабс) любой точки программы можно представить в виде суммы Aабс=Aнач+Aотн, где Aнач - начальный адрес программы, а Aотн - относительный адрес этой точки, т.е. адрес, отсчитанный от начала программы:

0 ┌─────┐

│ │

Aнач │─────│ ┐ <-- начало программы

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

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

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

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