
- •Глава 1. Сведения о компиляторе
- •1.1.Введение
- •1.2. Основные вопросы
- •1.3. Описание компилятора и документация
- •1.4. Компилятор и другие средства разработки
- •1.5. Набор возможностей компилятора
- •1.5.1. Стандарт ANSI Си
- •1.5.2. Оптимизация
- •1.5.3. Поддержка стандартной ANSI библиотеки
- •1.5.4. Гибкие модели памяти
- •1.5.5. Драйвер компилятора
- •Глава 2. Отличия 16-битового компилятора от ANSI
- •2.1. Введение
- •2.2. Основные вопросы
- •2.3. Отличия ключевых слов
- •2.3.1. Определение атрибутов переменных
- •2.3.2. Определение атрибутов функций
- •2.3.3. Inline функции
- •2.3.4. Переменные в определенных регистрах
- •2.3.4.1. Определение глобальных регистровых переменных
- •2.3.4.2. Определение локальных регистровых переменных
- •2.3.5. Комплексные числа
- •2.3.6. Целые размером в двойное слово
- •2.3.7. Ссылки на тип с помощью typeof
- •2.4. Отличия операторов
- •2.4.1. Метки как значения
- •2.4.2. Условные операторы с опущенными операндами
- •2.4.3. Диапазоны case
- •2.5. Отличия выражений
- •2.5.1. Двоичные константы
- •Глава 3. Использование компилятора в командной строке
- •3.1. Введение
- •3.2. Основные вопросы
- •3.3. Обзор
- •3.4. Соглашение для имен файлов
- •3.5. Опции
- •3.5.1. Опции, специфические для устройств dsPIC
- •3.5.2. Опции для управления типом результатов
- •3.5.3. Опции для управления диалектом Cи
- •3.5.5. Опции для отладки
- •3.5.6. Опции для управления оптимизацией
- •3.5.7. Опции для управления препроцессором
- •3.5.8. Опции для ассемблера
- •3.5.9. Опции для компоновщика
- •3.5.10. Опции для поиска в каталогах
- •3.5.11. Опции для соглашений по генерации кода
- •3.6. Переменные окружения
- •3.7. Предопределенные имена макро
- •3.9. Компиляция нескольких файлов в командной строке
- •3.10. Особенные символы
- •Глава 4. Среда периода исполнения
- •4.1. Введение
- •4.2. Основные вопросы
- •4.3. Адресное пространство
- •4.4. Запуск и инициализация
- •4.5. Пространства памяти
- •4.6. Модели памяти
- •4.6.1. Ближние и дальние данные
- •4.6.2. Ближний и дальний код
- •4.7. Расположение кода и данных
- •4.8. Программный стек
- •4.9. Использование стека в Си
- •4.11. Соглашения по вызову функций
- •4.11.1. Параметры функции
- •4.11.2. Возвращаемое значение
- •4.12. Соглашения о регистрах
- •4.13. Двоичная инверсия и модульная адресация
- •4.14.1. Загрузочные и защищенные константы
- •4.14.2. Строковые константы как аргументы
- •4.14.3. Переменные с квалификатором const в безопасной Flash
- •4.14.4. Модель совместимости объектов
- •Глава 5. Типы данных
- •5.1. Введение
- •5.2. Основные вопросы
- •5.3. Представление данных
- •5.4. Целые
- •5.5. С плавающей точкой
- •5.6. Указатели
- •Глава 6. Дополнительные типы указателей Си
- •6.1. Введение
- •6.2. Управляющие PSV указатели
- •6.2.1. Определение данных для управления доступом PSV
- •6.2.2. Управляемый доступ PSV
- •6.2.3. Рассмотрение ISR
- •6.3. PMP указатели
- •6.3.1. Инициализация PMP
- •6.3.2. Объявление нового пространства памяти
- •6.3.3. Определение переменных в пространстве PMP
- •6.4. Внешние указатели
- •6.4.1. Объявление нового пространства памяти
- •6.4.2. Определение переменных во внешнем пространстве
- •6.4.3. Определение способа доступа к пространству памяти
- •6.4.3.2. Функции записи
- •6.4.4. Пример внешней памяти
- •Глава 7. Файлы поддержки устройства
- •7.1. Введение
- •7.2. Основные вопросы
- •7.3. Файлы заголовков процессора
- •7.4. Файлы определения регистров
- •7.5. Использование SFR
- •7.6. Использование макросов
- •7.6.1. Макросы настройки битов конфигурации
- •7.6.2. Макросы использования ассемблера inline
- •7.6.3. Макросы выделения памяти данных
- •7.6.4. Макросы объявления ISR
- •7.7. Адресация EEDATA из Си - только для dsPIC30F
- •7.7.1. Доступ к EEDATA через PSV
- •7.7.2. Доступ к EEDATA посредством команд TBLRDx
- •7.7.3. Дополнительные источники информации
- •Глава 8. Прерывания
- •8.1. Введение
- •8.2. Основные вопросы
- •8.3. Написание программы обработки прерывания
- •8.3.1. Рекомендации по написанию ISR
- •8.3.3. Кодирование ISR
- •8.3.4. Использование макросов для объявления простых ISR
- •8.4. Запись вектора прерывания
- •8.4.1. Вектора прерываний dsPIC30F (без SMPS)
- •8.4.3. Вектора прерываний PIC24F
- •8.4.4. Вектора прерываний dsPIC33F/PIC24H
- •8.5. Сохранение контекста в ISR
- •8.7. Вложенные прерывания
- •8.8. Разрешение/запрещение прерываний
- •8.9. Разделение памяти между основной программой и ISR
- •8.9.1. Разработка проблем
- •8.9.2. Разработка решений
- •8.9.3. Пример приложения
- •8.10. Использование PSV в ISR
- •Глава 9. Совместное использование ассемблера и Си
- •9.1. Введение
- •9.2. Основные вопросы
- •9.3. Смесь переменных и функций на ассемблере и Си
- •9.4. Использование ассемблера inline
- •Приложение A. Определяемое реализацией поведение
- •A.12. Квалификаторы
- •A.13. Деклараторы
- •A.14. Операторы
- •A.17. Сигналы
- •A.18. Потоки и файлы
- •A.20. Errno
- •A.22. Abort
- •A.23. Exit
- •A.24. Getenv
- •A.25. Система
- •A.26. Strerror
- •Приложение B. Встроенные функции
- •B.2. Список встроенных функций
- •Приложение C. Диагностика
- •Приложение D. Компиляторы Си PIC18 и PIC24/dsPIC
- •D.6. Использование стека
- •D.11. Банк доступа
- •D.12. Inline ассемблер
- •D.13. Прагмы
- •D.14. Модели памяти
- •D.15. Соглашения о вызове
- •D.16. Код запуска
- •D.17. Управляемые компилятором ресурсы
- •D.18. Оптимизация
- •D.20. Определяемое реализацией поведение
- •D.21. Битовые поля

Глава 2. Отличия 16-битового компилятора от ANSI
Если вы хотите перекомпилировать qsort или другие исходные файлы, которые в действительности не используют вашу глобальную регистровую переменную, так чтобы они не использовали этот регистр для любой другой цели, то достаточно задать опцию командной строки компилятора -ffixed-reg. Вам не требуется действительно добавлять декларацию глобальной регистровой переменной к исходному коду.
Функция, которая может изменить величину глобальной регистровой переменной, не может быть безопасно вызвана из функции, компилированной без этой переменной, поскольку она могла бы затереть величину, которую вызывающий код ожидает
получить при возврате. Следовательно, функция, которая является точкой входа в |
|
|
. |
часть программы, которая использует глобальную регистровую переменную, |
|
|
A |
должна явно сохранять и восстанавливать величину, которая принадлежит |
|
вызывающему ее коду. |
|
Библиотечная функция longjmp восстанавливает в каждую глобальную регистровую переменную величину,Wilsonкоторую та имела на момент setjmp.
Все декларации глобальных регистровых переменных должны предшествовать
всем определениям функций. Если такая декларация появляется после определений функций, регистр в этих функциях может быть использован для других целей.
Глобальные регистровые переменные не могут иметь начальных значений,
поскольку выполняемый файл не имеет средства, чтобы обеспечить начальное состояние регистра.
2.3.4.2. Определение локальных регистровых переменных
Вы можете определить локальную переменную в выбранном регистре подобно |
|
этому: |
by |
|
register int *foo asm ("w8");
Здесь w8 - имя регистра, который должен быть использован. Заметьте, что этот
Определение такой регистровой переменной не резервирует регистр; он остается доступным для другого использования в местах, где управление потоком определяет, что переменная больше не нужна. Использование подобных переменных может оставить компилятору слишком мало доступных регистров, чтобы компилировать отдельные функции.
синтаксис аналогичен использованному при определении глобальных регистровых переменных,Translatedно определение локальной регистровой переменной должно появляться внутри функции.
Эта опция не дает полной уверенности в том, что компилятор сгенерирует код, который имеет эту переменную в заданном вами регистре все время. Вы не можете кодировать явную ссылку на этот регистр в операторе asm и рассчитывать, что она всегда сошлется на эту переменную.
Назначенные регистрам локальные переменные могут быть удалены, когда они оказываются неиспользуемыми. Ссылки на локальные регистровые переменные могут быть удалены, перемещены или упрощены.
2.3.5. Комплексные числа
Компилятор поддерживает комплексные типы данных. Вы можете объявить как комплексные целые типы, так и комплексные типы с плавающей точкой, используя ключевое слово __complex__.
Например, __complex__ |
float |
x; объявляет x как |
переменную, |
чья |
вещественная и мнимая части имеют тип float. __complex__ |
short int |
y; |
объявляет y как переменную, вещественная и мнимая части которой имеют тип short int.
Для записи констант комплексного типа используйте суффиксы 'i' или 'j' (любой из них, они равноправны). Например, 2.5fi имеет тип __complex__ float, а 3i имеет тип __complex__ int. Такая константа является чисто мнимой величиной, но
© 2008 Microchip Technology Inc. |
DS51284H(ru) стр. 2-19 |

16-битовый компилятор Си. Руководство
вы можете сформировать любую комплексную величину, добавляя ее к вещественной константе.
Для извлечения вещественную части комплексного выражения exp, запишите __real__ exp. Аналогично, использование __imag__ позволит извлекать мнимую часть. Например:
|
__complex__ float z; |
|
|
|
|
float r; |
|
|
|
|
float i; |
|
|
|
|
r = __real__ z; |
|
|
|
|
i = __imag__ z; |
A |
|
|
Оператор |
|
комплексного |
типа, выполняет |
|
'~', использованный с величинами. |
||||
комплексное сопряжение. |
|
|
|
|
|
Wilson |
|
автоматические |
переменные в |
Компилятор может разместить комплексные |
несмежных адресах; возможно даже размещение вещественной части в регистре, тогда как мнимая часть будет находится в стеке (или наоборот). Формат отладочной информации не имеет возможности представления несмежного расположения, подобного вышеупомянутому, поэтому компилятор описывает несмежные комплексные переменные как две раздельные переменные некомплексного типа. Если фактическое имя комплексной переменной foo, две фиктивных переменных получают имена foo$real и foo$ mag.
2.3.6. Целые размером в двойное слово
Компилятор поддерживает типы данных для целых, которые в два раза длиннее чем |
|||
long |
by |
|
|
int. Просто запишите long long int для целого со знаком или unsigned |
|||
long |
long int для целого без знака. Для записи констант типа long |
long |
int, |
добавьте суффикс LL к целому. Для записи констант типа unsigned |
long |
long |
|
int, добавьте суффикс ULL к целому. |
|
типом |
|
Предполагается,Translatedчто x[]() - массив функций; описанный тип является |
Вы можете использовать эти типы в арифметике подобно любым другим целым типам. Сложение, вычитание и поразрядные логические операции для этих типов реализованы открытым кодом, но деление и сдвиги реализованы не на основе открытого кода. Операции, не использующие для реализации открытый код, требуют специальных библиотечных подпрограмм, которые поставляются с компилятором.
2.3.7. Ссылки на тип с помощью typeof
Другой путь ссылки на тип выражения состоит в использовании ключевого слова typeof. Синтаксис для использования этого ключевого слова выглядит похожим на sizeof, но конструкция семантически работает подобно определению имен типов с помощью typedef.
Есть два способа записи аргумента для typeof: с помощью выражения или типа. Ниже дан пример с выражением:
typeof (x[0](1))
возвращаемых функциями значений.
Вот пример с именем типа в качестве аргумента:
typeof (int *)
Здесь описанный тип является указателем на int.
Если Вы пишете файл заголовка, который должен работать при включении в ANSI Си программу, используйте __typeof__ вместо typeof.
Конструкция typeof может использоваться везде, где допустимо ключевое слово typedef. Например, вы можете использовать его в декларации, в приведении, а также внутри sizeof или typeof.
DS51284H(ru) стр. 2-20 |
© 2008 Microchip Technology Inc. |