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

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

3.5.2.4 Обзор Ассемблера MPLAB ASM30

Язык Ассемблер – машинно-ориентированный язык низкого уровня с командами, соответствующими командам микроконтроллера.

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

Блок определений:

-секция подключаемых файлов;

-секция определения битов конфигурации;

-секция определения констант;

-секция определения макросов;

-секция объявления переменных.

Блок кода:

-обработчик прерываний;

-основной цикл программы;

-подпрограммы.

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

Пример исходного файла на языке Ассемблер:

.list P=P33FJ32MC204

271

.include "P33FJ32MC204.inc"

.global __reset

;Метка начала кода

__reset:

main: nop

goto main service:

nop nop retfie

.end

;Конец кода

Основу языка Ассемблер составляют директивы и инструкции. Директивы языка Ассемблер интерпретируются во время выполнения работы ассемблера и используются для определения секций памяти, инициализации констант, декларирования и определения символов и т. д. Инструкции являются командами микроконтроллера, непосредственно исполняются им во время работы.

3.5.2.5 Общий формат инструкций и директив языка Ассемблер

Общий формат инструкций и директив языка Ассемблер следующий: [метка:] инструкция [операнды] [;комментарии]; [метка:] директива [аргументы] [;комментарии].

Таким образом, каждая строка исходного файла может содержать до четырѐх информационных полей:

-метка;

-мнемоника команды;

-операнды команды;

-комментарии.

Метки используются для отметки позиции в коде. Во время компоновки, метки определяют адреса в памяти. Метки должны начинаться с первой колонки и за-

писываются строчными буквами. За меткой должно следовать двоеточие «:». Метка должна начинаться с символа латинского алфавита или двойного символа подчеркивания «__» и может состоять из цифр и букв латинского алфавита и символа подчеркивания «__».

272

Мнемоники инструкций микроконтроллера, директивы языка Ассемблер и мак-

рокоманды должны начинаться со второй (и далее) колонки.

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

Любой текст до конца строки после символа «;» трактуется как комментарий. Комментарии могут следовать за операндами, мнемониками и метками и могут начинаться в любой колонке.

3.5.2.6 Директивы языка Ассемблер

Существует пять основных типов директив языка Ассемблер:

-директивы контроля – управляют созданием разделов условно компилированного кода;

-директивы данных – управляют разделением памяти и назначением символических имен переменным и константам;

-директивы листинга – определяют формат и состав файла листинга. Эти директивы позволяют указывать заголовки, нумеровать страницы и настраивать другие параметры;

-макро директивы – управляют работой макросов и распределением данных в теле макроса;

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

Основные директивы языка Ассемблер перечислены ниже.

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

.LIST P = P33FJ32MC204

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

273

.INCLUDE “P33FJ32MC204.inc”

Директива .GLOBAL используется для того, чтобы позволить меткам, определѐнным внутри файла, использоваться в другом файле. Пример использования директивы:

.GLOBAL __reset

.GLOBAL __OscillatorFail

.GLOBAL __AddressError

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

Директива .SECTION декларирует секцию памяти. Атрибутами, следующими за директивой, задается расположение секции – например, в памяти RAM либо в программной памяти. Пример использования директивы:

.SECTION .DATA

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

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

Директива .EQU используется для определения символа и присвоения ему значения. Пример использования директивы:

.EQU FCY, #7370000

Вданном примере символу FCY присваивается литеральное значение 7370000.

Втаком контексте FCY является константой, которая может использоваться в коде.

Директива .HWORD используется для объявления инициализированных данных в пределах секции. Данные могут быть в виде констант, внутренних и внешних меток или их выражений. Пример использования директивы:

MINX: .HWORD 0x7FFF

274

Директива .EXTERN используется для объявления переменной либо метки, которая может использоваться в данном файле кода, однако определена как

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

.EXTERN LABEL

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

.LIST P = P33FJ32MC204

; текст программы

.END

3.5.2.7 Числовые константы и системы счисления

MPLAB ASM30 поддерживает шестнадцатеричную, десятичную и двоичную системы счисления. Для обозначения числового значения используется символ «#».

Синтаксические правила числовых значений приведены в таблице 3.10.

Таблица 3.10 – Синтаксис числовых значений

Тип

Синтаксис

Пример

 

 

 

 

Шестнадцатеричный

0x< числовое значение >

#0x9F

 

 

 

 

Десятичный

<числовое значение>

#123

 

 

 

 

Двоичный

0b<числовое значение>

#0b11

 

 

 

 

Пример 3.24. Вычислить значение выражения (25 + 13) * (18 – 9), результаты промежуточных вычислений хранить в рабочих регистрах. Выделить младшую тетраду результата и поместить еѐ в старшую.

Алгоритм решения задачи представлен на рисунке 3.24.

275

Начало W6 = W2 × W5

Ввод W6 = W6 ^ #0x000F

W2 = W1 + W2

W6 = W6 << 12

W5 = W3 – W4 Конец

Рисунок 3.28 – Схема алгоритма к примеру 3.24

Листинг программы к примеру 3.24 на языке Ассемблер:

.INCLUDE"P33FJ32MC204.inc"

.GLOBAL __reset

__reset:

 

; Метка начала исходного файла

MOV

#25, W0

; W0 = 25

 

MOV

#13, W1

; W1 = 13

 

ADD

W0, W1, W2

; W2 = W0

+ W1

MOV

#18, W3

; W3 = 18

 

MOV

#9, W4

; W4 = 9

 

SUB

W3, W4, W5

; W5

= W3

- W4

MUL.SS

W2, W5, W6

; W6

= W2

* W5

AND

#0x000F, W6

; W6

= W6

^ #0x000F,

 

 

; выделение младшей

 

 

; тетрады

 

SL

W6, #12, W6

; W6

= W6

<< 12, сдвиг

 

 

; влево на 12 разрядов

.END

 

; Конец исходного файла

Результат выполнения алгоритма – регистр W6 содержит значение

0x6000.

276

3.5.3 Конструирование программ

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

пригодный для программирования микроконтроллера, либо

файл библиоте-

ки, предназначенный для последующего использования в

других програм-

мах и часто другими программистами.

 

На рисунке 3.25 приведена обобщенная схема процесса конструирования программы в общем случае.

Prog.asm

Prog.o

Main.c

Main.o

Prog.hex

CPU

Ассемблирование,

Программирование

 

компиляция

 

Math.lib

Компоновка

Рисунок 3.25 – Обобщенная схема процесса конструирования программы

Процесс конструирования программы включает в себя три этапа:

-разработка исходного кода;

-ассемблирование и компиляция исходного кода;

-компоновка программы или библиотеки.

3.5.3.1Разработка исходного кода

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

277

объектного кода (.inc), заголовочные файлы для библиотек и файлов объектного кода (.h), а также справочные файлы, содержащие информацию по использованию библиотек, предоставляемых, как правило, другими разработчиками. Включаемый файл содержит информацию о библиотеке или файле объектного кода, необходимую для работы ассемблера. Этот файл включается программистом в файлы исходного кода программы посредством специальной директивы. Заголовочный файл содержит информацию о библиотеке или файле объектного кода, необходимую для работы компилятора языка С. Данный файл также включается программистом в файлы исходного кода при помощи специальной директивы. На этапе разработки исходного кода программист, использующий ассемблер, создает файлы исходного кода программы на языке Ассемблер (.asm) и соответствующие им включаемые файлы (.inc). В случае использования языка С программист создает файлы исходного кода на языке C (.c) и соответствующие им заголовочные файлы (.h). В некоторых случаях исходный код программы состоит из файлов, написанных на языках Ассемблер и С. Кроме этого, в процессе разработки исходных кодов программист, как правило, создает файлы примечаний (.txt), предназначенные для последующего сопровождения программы. В редких случаях разработка программы ведется с «чистого листа», без использования библиотек и соответствующих им включаемых и заголовочных файлов.

3.5.3.2 Ассемблирование и компиляция исходного кода

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

Исходными данными для ассемблера являются файлы исходного кода на языке Ассемблер (.asm) и включаемые файлы (.inc), созданные программистом на предыдущем этапе. В случае успешного ассемблирования создаются файлы объектного кода программы (.o). Эти файлы являются промежуточными в процессе конструирования программы. Файл объектного кода не является выполнимым и не пригоден для программирования микроконтроллера. При этом он содержит машинно-зависимый код, а также дополнительную информацию для компоновщика. Файл объектного кода не содержит в явном виде информацию, доступную для анализа программистом. Кроме файлов объектного кода ассемблер создает различные файлы отчета: файл ошибок (.err), файл листинга (.lst) и файл перекрестных ссылок (.xrf). Файл ошибок содержит ошибки, предупреждения и сообщения, сгенерированные во время ассемблиро-

вания. В случае наличия ошибок файл объектного кода не создается. Файл ли-

278

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

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

Файлы объектного кода, сгенерированные различными компиляторами и ассемблерами, имеют единый формат, что позволяет объединять их при компоновке. Эта особенность дает возможность при разработке программы использовать различные языки программирования. Кроме этого, большинство компиляторов языка С позволяет при необходимости включать в исходный код фрагменты кода, написанные на языке Ассемблер.

3.5.3.3 Компоновка программы или библиотеки

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

Исходными данными для компоновщика являются файлы объектного кода (.o), сгенерированные ассемблером и компилятором на предыдущем этапе,

а также файлы библиотек (.lib). В случае успешной компоновки генерируется выполнимый файл (.hex), пригодный для программирования микро-

контроллера. Данный файл содержит выполнимый код программы в одном из так называемых hex-форматов (INHX8M, INHX8S, INHX32). Кроме выполнимого файла компоновщик создает различные файлы отчета: файл листинга (.lst), файл распределения памяти (.map), а также различные служебные файлы: файл для отладки (.cod) и COFF-файл (.out). Файл листинга содержит исходный код и объектный код всей программы, а также результат дизассемблирования. Файл распределения памяти содержит информацию о размещении секций программы, использовании памяти программы и информацию о распределении переменных и меток программы.

Библиотекарь используется для создания и модификации файлов библиотек (.lib). Файл библиотеки представляет собой коллекцию файлов

279

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

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

Avg.asm Avg.o

Add.asm

Add.o

Math.lib

Библиотека

Mult.c Mult.o

Исходные

Объектные

файлы

файлы

Рисунок 3.26 – Создание файла библиотеки

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

280