Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
27
Добавлен:
02.05.2014
Размер:
164.86 Кб
Скачать

8.2. Загрузка абсолютной программы

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

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

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

Будем считать, что объектная программа представляет собой совокупность записей трех типов:

1) запись-заголовок;

2) запись-тело;

3) запись-окончание.

Запись-заголовок имеет следующий вид:

Н.Имя_программы.Начальный_адрес_программы.Размер_программы

Запись-тело имеет следующий вид:

T.Начальный_адрес_записи.Размер_записи.Коды_команд_и_данных

Запись-окончание имеет следующий вид:

Е.Адрес_первой_исполняемой_команды

Пример. Напишем программу PROG, имеющую следующий код:

push ds 1E

mov ax, 0 B8 00 00

push ax 50

ret CB

Считая, что программа должна располагаться с нулевого адреса, в соответствие с нашим определением объектная программа будет иметь следующий вид:

H PROG 6

T 0000 1 1E

T 0001 3 B80000 ; B8 00 00

T 0004 1 50

T 0005 1 CB

E 0000

Или H PROG 6

T 0000 6 1EB8000050CB ; 1E B8 00 00 50 CB

E 0000

Алгоритм работы загрузчика для такой программы достаточно прост:

1) Просматриваем запись-заголовок и сравниваем размер программы с имеющейся свободной памятью. Если памяти не хватает, то не грузим программу, если памяти хватает, то переходим к пункту 2.

2) Последовательно считываем записи-тела и располагаем коды команд и данных из этих записей в памяти по указанным адресам. Делаем это, пока не дойдем до записи-окончания.

3) Дойдя до записи-окончания, делаем переход на адрес, указанный в этой записи, т.е. к первой выполняемой инструкции программы.

8.3. Загрузка перемещаемой программы

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

Рассмотрим простейший пример.

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

mov ax, [0000]

(есть синтаксическая ошибка, надо писать mov ax, ds:[0000] или mov ax, cs:[0000]).

Запись-тело для такой инструкции будет выглядеть следующим образом:

Т 0007 4 8A260000 ; 8А 26 0000 (0007 - адрес инструкции)

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

Помимо того, что адресная часть записей объектного кода (второй столбец записей с признаками Т и Е) должна измениться с 000Х на 200Х, должна измениться и информация внутри записей, а именно, там, где в записи-теле есть адрес 0000, должен стоять адрес 2000. Т.е. записи должны подвергнуться модификации, для того чтобы программа стала перемещаемой.

Поэтому в объектном коде перемещаемой программы существуют записи еще и другого, кроме Н, Т и Е, типа. Эти записи называются записями-модификаторами. Структура их, в общем виде, имеет следующий вид:

М.Адрес_модифицируемого_поля.Значение_модификации

В нашем конкретном примере запись-модификатор, относящийся к инструкции mov ax, [0000], будет иметь вид:

М 0009 2000

Для каждого перемещаемого данного должна существовать запись-модификатор.

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

Например. Добавление в запись-тело признака модификации.

Запись: Т 0007 4 8А260000 может быть изменена следующим образом:

Т 0007 2 8А26

Т 0009 2 0000

После длин поля добавляется признак модификации 1 - перемещаемый код, 0 - неперемещаемый код.

Т 0007 2 0 8А26

Т 0009 2 1 0000

Загрузчик анализирует это поле записи в процессе загрузки и добавляет при необходимости к данным начальный адрес.

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

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

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

Соседние файлы в папке Шпоры по СПО