Главная -> Книги

(0) (1) (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) (16) (17) (18) (19) (20) (21) (22) (23) (24) (25) (26) (27) (28) (29) (30) (31) (32) (33) (34) (35) (36) (37) (38) (39) (40) (41) (42) (43) (44) (45) (46) (47) (48) (49) (50) (51) (52) (53) (54) (55) (56) (57) (58) (59) (60) (61) (62) (63) (64) (65) (66) (67) (68) (69) (70) (71) (72) (73) (74) (75) (76) (77) (78) (79) (80) (81) (82) (83) (84) (85) (86) (87) (88) (89) (90) (91) (92) (93) ( 94 ) (95) (96) (97) (98) (99) (100) (101) (102) (103) (104) (105) (106) (107) (108) (109) (110) (111) (112) (113) (114) (115) (116) (117) (118) (119) (120) (121) (122) (123) (124) (94)

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

Для реализации перемещающего ассемблера необходимо различать абсолютные и переместимые" (перемещаемые) объекты - имена и выражения: значение абсолютного объекта не зависит, а значение переместимого объекта зависит от адреса загрузки. В ассемблер встраивается набор правил, позволяющих ему различать абсолютные и перемести-мые объекты. Наиболее распространены следующие правила: 1) все численные константы считаются абсолютными; 2) счетчик адреса переместим; 3) имя в поле метки является переместимым и только в директиве EQU определяется типом объекта в поле операнда; 4) выражения, состоящие только из абсолютных имен и констант, считаются абсолютными; 5) разность двух переместимых имен абсолютна; 6) если REL - переместимое имя, а ABS - абсолютная константа, имя или выражение, то выражения REL, REL-j--f ABS, ABS+REL, REL-ABS будут переместимыми.

Чтобы ассемблер мог различать абсолютные и переме-стимые модули, удобно использовать две различные директивы ORG: директива AORG начинает абсолютный модуль, а директива RORG - переместимый модуль. Встретив директиву RORG, ассемблер строит программу так, как будто она начинается по адресу, равному значению операнда этой директивы. При этом составляется список (таблица перемещения) всех ячеек, содержащих переместимые объекты, так как значения их должны быть скорректированы при загрузке в другую область памяти. Директивы .ASECT и .CSECT языка ассемблера процессоров СМ выполняют примерно такие же функции, как и директивы AORG и RORG, но инициализация счетчика адреса производится оператором прямого присваивания. Формат объектного модуля перемещающего ассемблера приведей на рис. 7-5. Каждая запись в таблице перемещения содержит относительное значение переместимого адреса и указатель одно-связного списка всех ячеек (операндов команд передачи управления), которые содержат этот адрес. Конец списка идентифицируется нулем.

В процессе загрузки определяется константа, называемая загрузочным смещением (программным смещением), которая прибавляется ко всем переместимым адресам.



Длина таблицы

Относительный

Указатель о-

адрес

1 о.

1 0

Рнс. 7-5. Формат выхода перемещающего ассемблера

В листинге переместимые адреса отмечаются буквой R или апострофом.

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

Более совершенные ассемблеры выводят содержательные сообщения об ошибках. Конечно, ассемблер не может обнаружить в программе логические ошибки, поэтому его сообщение «число ошибок равно нулю» не гарантирует правильного выполнения программы.

Ассемблер выводит на печать документ программы - листинг. Каждая строка листинга обычно содержит следующую информацию (слева направо): номер строки, адрес памяти, собственно программные байты (или слова), идентификаторы ошибок, копия полной строки исходной программы. Адреса памяти и программные байты печатаются в 8- или 1б-ричном представлении.

ЗАГРУЗЧИК

По рис. 7-2 загрузке предшествует обработка объектных модулей редактором связей. Однако первой удобнее рассмотреть сравнительно простую программу-загрузчик.

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



ков, выполняющих все более сложные функции.

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

Для загрузки любых программ в произвольные области памяти используется абсолютный загрузчик. На рис. 7-4 был приведен формат выхода абсолютного ассемблера. Абсолютный загрузчик, рассчитанный на данный формат, выделяет необходимую информацию и записывает программные байты по абсолютным адресам памяти. При загрузке осуществляется вычисление контрольной суммы блоков и сравнение ее с содержимым поля CKSM. Расхождение контрольных сумм свидетельствует об ошибках, и операцию загрузки приходится повторять. При восприятии последнего блока с нулевым полем ВС загрузчик помещает в программный счетчик пусковой адрес программы и прекращает свои действия.

Самым гибким по выполняемым функциям является перемещающий загрузчик. Главная функция его заключается в автоматической коррекции переместимых адресов в программе при загрузке ее по фактическому адресу загрузки так, чтобы в новой области памяти программа выполнялась правильно. Загрузчик прибавляет смещение к каждому относительному адресу в таблице перемещения. Затем он «просматривает» список записей в таблице перемещения и записывает перемещенный адрес в каждый элемент списка. Полученный абсолютный загрузочный модуль записывается в память и готов для выполнения.

РЕДАКТОР СВЯЗЕЙ

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



(0) (1) (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) (16) (17) (18) (19) (20) (21) (22) (23) (24) (25) (26) (27) (28) (29) (30) (31) (32) (33) (34) (35) (36) (37) (38) (39) (40) (41) (42) (43) (44) (45) (46) (47) (48) (49) (50) (51) (52) (53) (54) (55) (56) (57) (58) (59) (60) (61) (62) (63) (64) (65) (66) (67) (68) (69) (70) (71) (72) (73) (74) (75) (76) (77) (78) (79) (80) (81) (82) (83) (84) (85) (86) (87) (88) (89) (90) (91) (92) (93) ( 94 ) (95) (96) (97) (98) (99) (100) (101) (102) (103) (104) (105) (106) (107) (108) (109) (110) (111) (112) (113) (114) (115) (116) (117) (118) (119) (120) (121) (122) (123) (124)