"DVDXpert" - компас в мире Hi-Fi и High End техники и другой stereo и home cinema аппаратуры.

ГЕНЕРАЦИЯ ОБЪЕКТНЫХ МОДУЛЕЙ (ФАЙЛОВ)

IT & hi-tech
4.0 / 5 (62 оценок)

Если специфицирована метка

Пример:

int_l org 0x20

; коды для вектора 20 будут находиться здесь int_2 org int_l+0xl0

; коды для вектора 30 будут находиться здесь

См. также FILL, RES

PAGE

Вставляет прогон страницы листинга page

Директива временно прекращает вывод текстового потока в файл листинга и заполняет остаток страницы символами перевода строки, что при печати приводит к "прогону" страницы в принтере. Вывод текста возобновляется с начала следующей страницы. Применяется для удобства оформления листинга и разбивки его на смысловые блоки.

См. также LIST, SUBTITLE, TITLE

PAGESEL

Генерирует код выбора страницы

pagesel

Директива применяется при генерации объектного файла. Является инструкцией компоновщику сгенерировать коды установки битов выбора страницы программной памяти, которая соответствует метке

Начиная с указанного адреса резервирует ячейки памяти, в количестве, указанном в . В неперемещаемом коде соответствует конкретному адресу программной памяти. В перемещаемом коде (с применением MPLINK) директива RES может быть также использована для резервирования ячеек под хранение данных. Адрес описывается словами для 12, 14 и 16битных контроллеров и байтами для расширенных 16битных контроллеров.

Вставляет пустую строку в текст листинга

space <ехрг>

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

space 3 ; вставляет три пустых строки в листинг

См. также LIST SUBTITLE

Описывает подзаголовок программы subtitle ""

Значение "" представляет собой ASCII строку длиной не более 60 символов, заключенную в двойные кавычки. Эта директива устанавливает второй заголовок программы, который используется как подзаголовок в выходном листинге.

Пример:

subtitle "input section"

См. также TITLE TITLE

Описывает заголовок программы title ""

Значение "*title_text>" представляет собой ASCII строку длиной не более 60 символов, заключенную в двойные кавычки. Директива определяет текст, который будет выводиться в первой строке каждой страницы файла листинга.

title "diagnostic code, rev 5.0"

См. также LIST, SUBTITLE

UDATA

Объявляет неинициализированный блок данных объектного файла udata

Директива используется при генерации объектного файла. Объявляет начало секции неинициализированных данных. Если значение

Если используется опция HIGH, то в выражении используются только биты с 8 по 15. В случае использования опции LOW используются только биты с 0 по 7. Если используется опция UPPER, то в выражении будут использованы только биты с 16 по 21й.

РАСПРЕДЕЛЕНИЕ ОЗУ

Пространство ОЗУ должно быть распределено в секции данных. Существует пять типов секции данных:

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

UDATA_ACS неинициализированные данные доступа. Эта секция данных используется для переменных, которые будут помещены в ОЗУ быстрого доступа микроконтроллеров PICI8CXX. Эта область ОЗУ используется для прямого обращения к данным некоторыми инструкциями.

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

UDATAJSHR неинициализированные скрытые данные. Эта секция данных применяется для переменных, которые будут помещены в "теневой" или противоположный активному банк памяти.

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

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

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

Когда преобразование исходного текста к виду, соответствующему требованиям перемещаемого кода, завершено, может быть сгенерирован объектный файл Для этого в оболочке MPASM для Windows или в соответствующем окне MPLABIDE надо галочкой отметить опцию "Object File" Диалоговые окна среды MPLAB подробно описаны в предыдущей главе.

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

Программа имеет иллюстративный характер, однако будучи ассемблированной, работает правильно. Исходный текст предназначен для контроллеров Р16С5Х, но с незначительными изменениями его можно применить и для PIC16X8X. Этот пример иллюстрирует создание перемещаемого кода и библиотечного модуля. Практические примеры программ с подробными комментариями мы рассматриваем далее, в соответствующей главе.?

Очевидно, что подпрограмма, перемножающая два 8битных числа, может нам понадобиться в дальнейшем и ее целесообразно выделить в библиотечный модуль. Для этого, как показано далее, выделяем подпрограмму в отдельный фрагмент и объявляем переменные mulcnd, mulplr, H_byte и L_byte как глобальные. Также объявляем глобальным имя подпрограммы умножения тру. Для того чтобы компоновщик зарезервировал ячейки ОЗУ под переменные, отводим им секцию данных директивой UDATA и директивой RES резервируем под каждую переменную необходимое число ячеек. Далее исходный файл ассемблируется как объектный модуль и на выходе получается объектный файл с расширением ".О".

Основной модуль программы считывает данные с выводов портов (по умолчанию после сброса они настроены на ввод) и вызывает подпрограмму умножения.

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

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

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

Скрипт компоновщика также сообщает, какие области памяти данных и программ физически доступны для заданного микроконтроллера. Затем компоновщик пробует разместить программный код в память программ и распределить переменные в памяти данных. Если программа слишком велика, либо для хранения переменных не хватает ячеек, MPLINK генерирует сообщение об ошибке. В этом случае надо попробовать еще раз разобраться, какие переменные являются временными и могут использовать одну и ту же ячейку ОЗУ и попытаться оптимизировать программный код, в противном случае придется использовать более мощный микроконтроллер. Использование компоновщика позволяет очень гибко использовать определенную область ОЗУ под хранение значений переменных из разных участков программы. Если, например, некоторые значения переменных используются только в фрагменте кода инициализации по сбросу, то затем эти же ячейки могут быть "отданы" для хранения переменных другого фрагмента программы. Достаточно лишь соответствующим образом описать переменные и область памяти (см. раздел директив MPASM) и компоновщик автоматически распределит адреса в выходном коде. Вам не понадобится постоянно помнить, какая ячейка освободилась и жестко присваивать им имена. Впрочем, в случае с

несложными программами, имена переменных очень часто ставят в соответствие определенным адресам ОЗУ. Мы тоже будем так делать в примерах простых программ.

Существует огромное количество различных библиотечных файлов, практически для всех типов микроконтроллеров Microchip, написанных как на ассемблере, так и на MPLABC17/C18.

ВХОДНЫЕ И ВЫХОДНЫЕ ФАЙЛЫ КОМПОНОВЩИКА

Рассмотрим подробнее, какие входные и выходные файлы используются при работе компоновщика.

Входные файлы

Объектные файлы (.О) перемещаемые коды, создаваемые из исходных файлов.

Библиотечные файлы (.LIB) коллекция объектных файлов, собранных вместе для удобства.

Скрипты компоновщика (.LKR) расшифровка распределения памяти для индивидуальных процессоров / проектов.

Примечание: исходные файлы используются, если генерируется файл листинга.

Выходные файлы:

Файлы COFF (.OUT, .COF) промежуточные файлы, используемые компоновщиком MPLINK для генерации файлов .COD, .HEX или .LST.

Файл кода (.COD) отладочный файл, используемый MPLAB.

Исполняемый файл (.HEX) двоичный исполняемый файл, не содержащий никакой отладочной информации.

Файл листинга (.LST) файл, содержащий оригинальный исходный код совместно с окончательным двоичным кодом и некоторой служебной информацией.

Файл карты памяти (.МАР) показывает распределение памяти после компоновки, включая занятые и не занятые участки.

MAPфайл представляет собой обычный текстовый файл и его можно открыть для просмотра командой меню MPLAB File>Open. Окно автоматически обновляется при каждой перекомпиляции проекта. В файле находится информация о физическом размещении вы

ходных кодов программы и данных после компоновки. Файл содержит три таблицы. Первая таблица (Section Info) содержит информацию о каждой секции, включая имя секции, ее тип, начальный адрес, в какой области памяти находится секция: данных или программ и ее размер в байтах. Существует четыре типа секций: код (code)

инициализированные данные (idata) неинициализированные данные (udata) инициализированные данные ROM (romdata).

Как вы помните, проект MPLAB представляет из себя композицию некоторых модулей или блоков (nodes), среди которых могут быть (не обязательно все сразу) исходные файлы ассемблера, исходные файлы С, библиотечные файлы, предварительно откомпилированные объектные файлы и файлы скриптов компоновщика. В результате обработки проекта генерируются выходные файлы мы достаточно подробно рассмотрели их раньше. Наряду с ассемблером и компилятором С 17/С 18, MPLINK играет роль инструмента, при помощи которого обрабатывается проект.

НАСТРОЙКА ПРОЕКТА MPLAB ДЛЯ ИСПОЛЬЗОВАНИЯ MPLINK

После создания проекта (Project > New Project) вы получаете доступ к окну редактирования свойств проекта. Мы подробно рассмотрели работу с этим окном ранее, в главе, описывающей работу с MPLAB. Выделите имя проекта щелчком мышки и, когда станет активной кнопка "Node Properties", нажмите на нее. В диалоге "Node Properties", в поле "Language Tool" выберите MPLINK. Если необходимо, установите другие опции компоновщика.

Добавьте исходные файлы в ваш проект, используя кнопку "Add Node". Укажите программный инструмент, при помощи которого будет скомпилирован каждый исходный файл, выбирая имя этого файла и нажимая кнопку "Node Properties".

Добавьте предварительно откомпилированные файлы и библиотеки (например, входящие в состав MPLABC17/C18). Вы можете добавить несколько файлов одновременно, если выбирая файлы в списке будете удерживать нажатой клавишу . Затем добавьте скрипт компоновщика в качестве одного из модулей проекта, используя кнопку "Add Node" Окончив настройку, нажмите кнопку "ОК" окна редактирования свойств проекта.

Генерация выходных файлов

Когда проект MPLAB настроен, вы можете выполнить его сборку, запустив процесс обработки командой меню Project > Make Project. Сгенерированные hexфайлы автоматически загружаются в ОЗУ вашего компьютера. Кроме этого, генерируются дополнительные файлы для документирования и отладки, их назначение мы рассмотрели в разделе "Входные и выходные файлы компоновщика".

Логические секции, используемые в исходном коде для размещения кодов и данных.

Существуют четыре основные категории директив, применяемых в скриптах. Сейчас мы подробнее рассмотрим каждую из этих директив. Комментарии в скриптах помечаются символами косой черты "II", любой текст, помещенный между этими символами, игнорируется. Мы не будем описывать опции командной строки, потому что менеджер проектов MPLAB автоматически подставляет их в соответствии с настройками диалоговых окон. Вероятность того, что вы будете работать непосредственно с командной строкой, очень мала, но в случае необходимости вы можете обратиться к файлу помощи MPLINK.

Чтобы размер стека был определен как '0x20' в области ОЗУ, предварительно определенной как 'gprO', в скрипт компоновщика должна быть включена строка:

STACK SIZE=0x20 RAM=gprO

НЕКОТОРЫЕ ПРЕДУПРЕЖДЕНИЯ ПО ПОВОДУ ПРИМЕНЕНИЯ СКРИПТОВ

Компания Microchip® приводит следующие предупреждения, связанные с применением скриптов компоновщика:

Вполне возможно, что перед использованием вам понадобится модифицировать файлы скриптов, поставляемые в комплекте с MPLINK.

Вам понадобится устанавливать размер стека, если вы используете MPLABC17/C18 с MPLINK.

Вам понадобится разделять страницы памяти, если ваш код содержит инструкции GOTO или CALL без применения псевдоинструкции PAGESEL.

В MPASM вы не можете переключать впредназад секции в одиночном файле, т.е. вы не должны делать нечто наподобие этого'

CODE MY_ROM

(инструкции программы)

UDATA MY_VARS (переменные)

CODE MY_ROM

(вновь инструкции программы)

КАК РАБОТАЕТ КОМПОНОВЩИК

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

Итак, как мы уже знаем, компоновщик комбинирует входные объектные модули в один выходной исполняемый модуль. Входные объектные модули могут содержать перемещаемые или абсолютные секции кода или данных, которые компоновщик разместит в памяти. Архитектура памяти описана в скрипте компоновщика. Скрипт предоставляет гибкий механизм для спецификации блоков памяти. Если компоновщик не может найти блок памяти, в котором должна располагаться специфицированная секция, то генерируется ошибка.

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

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

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

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

АЛГОРИТМ РАЗМЕЩЕНИЯ СЕКЦИЙ

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

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

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

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

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

Существуют и другие примеры, очень большие и сложные, иллюстрирующие применение компоновщика, но их описание выходит за рамки этой книги Как правило, сложные проекты из множества файлов, со сложными скриптами компоновщика применяются для написания программ под микроконтроллеры, более мощные, чем PIC 16F83/84. Для создания таких проектов недостаточно прочесть однудве книги. Необходим опыт программирования более простых приложений, желательно для микроконтроллеров различных семейств.


Еще по теме:
 Что же такое цифровое и аналоговое телевидение и чем они отличаются?
 ЦИФРОВЫЕ КОНСТАНТЫ И СИСТЕМЫ СЧИСЛЕНИЯ
 Экспресс.
 Возможности виртуальных студий
 ПРОГРАММЫ И СХЕМЫ ПИШЕМ ПЕРВЫЕ ПРОГРАММЫ

Добавить комментарий:
Введите ваше имя:

Комментарий:

Защита от спама - решите пример: