- •Эрни Каспер Программирование на языке Ассемблера для микроконтроллеров семейства i8051
- •1.Что нужно знать программисту о микроконтроллерах семейства i8051
- •1.1.Общие сведения об архитектуре i8051
- •1.2.Правила записи команд микроконтроллера семейства i8051 на Ассемблере
- •1.3.Форматы и способы адресации данных
- •1.4.Форматы и способы адресации команд
- •1.5.Команды пересылки информации
- •1.6.Команды поразрядной обработки информации
- •1.7.Команды арифметических операций
- •1.8.Управляющие команды
- •2.Директивы ассемблера для микроконтроллеров семейства i8051
- •2.1.Общие понятия о процессах трансляции и компоновки
- •2.2.Обработка имен транслятором и компоновщиком
- •2.3.Директивы резервирования памяти и инициализации данных
- •2.4.Использование выражений в операндах
- •2.5.Директивы условной трансляции
- •2.6.Директивы подстановок
- •2.7.Директивы управления вводом и выводом
- •Глава 3.
- •3.Кросс-средства фирмы 2500 a.D. Software, Inc. Для семейства i8051
- •Глава 4
- •4.Программирование арифметических действий
- •4.1.Кодирование информации в микроконтроллере
- •4.2.Арифметические действия с большими числами
- •4.3.Арифметические действия с отрицательными числами
- •4.4.Контроль точности при программировании арифметических операций
- •Глава 5
- •5.Программирование вычисления функций
- •5.1.Возведение в квадрат и извлечение квадратного корня
- •5.2.Переход от десятичной системы счисления к двоичной и обратно
- •5.3.Вычисление функций при помощи таблиц
- •5.4.Вычисление обратной функции по таблице прямой функции
- •5.5.Компенсация систематических погрешностей при помощи таблиц
- •Глава 6
- •6.Программирование фильтрации сигналов
- •6.1.Особенности цифровой фильтрации сигналов
- •6.2.Программирование простейших фильтров нижних частот
- •6.3.Программирование фильтра для оценки параметров сигнала
- •6.4.Программирование медианного фильтра
- •Глава 7
- •7.Программирование взаимодействия с внешними устройствами
- •7.1.Общие вопросы взаимодействия
- •7.2.Порядок выполнения прерываний в микроконтроллерах семейства i8051.
- •7.3.Синхронизация работы программы внешним или внутренним сигналом
- •7.4.Программирование приема информации от датчиков
- •7.5.Программирование выдачи команд на исполнительные устройства
- •7.6.Программирование ввода и вывода информации для пользователя
- •8.Несколько рекомендаций о стиле программирования
- •8.1.Стиль программирования и использование ресурсов
- •8.2.Оформление исходного текста программы
- •8.3.Системы обозначений, выражения и простые подстановки
- •8.4.Применение подпрограмм и сложных текстовых подстановок
8.3.Системы обозначений, выражения и простые подстановки
От общих вопросов оформления программы перейдем к частностям, которые поначалу могут показаться мелочами. Но значительная доля ошибок приходится именно на мелочи. Желательно тем или иным образом разделять обозначения зарезервированных имен от имен, назначаемых программистом. Для этого можно использовать различие между прописными и строчными буквами. В настоящей книге мнемокоды команд и директив, а также все зарезервированные слова языка записаны прописными буквами. Имеет также смысл отличать команды от директив, для этого в мнемокоде директивы лучше использовать точку. Если для записи зарезервированных имен используются прописные буквы, то имена, назначенные программистом, лучше записывать строчными буквами.
Использование мнемоники при записи имен, назначаемых программистом, затрудняется тем, что ассемблер воспринимает только латинский алфавит. В связи с этим только некоторая часть программистов может щеголять знанием английского языка. У англоязычных программистов принято обозначать операнды существительными, а подпрограммы -глаголами. Несведущие в английском языке с успехом пользуются русскими словами, записанными на латинице. Программист может изобретать и использовать свои мнемонические правила, укладывающиеся в синтаксические ограничения языка. Эти правила позволяют уменьшить вероятность ошибок при записи имен и следить за смыслом выполняемых действий. Так, например, имена разных групп операндов могут иметь различную длину. При использовании переменной, состоящей из двух байтов, полезно использовать для них имена с одинаковым корнем и двумя разными суффиксами: lo (low — нижний) для младшего байта и hi (high — верхний) для старшего. Для того чтобы отличать битовые переменные, можно использовать префикс f_ (флаг). Такого рода правила не противоречат синтаксису Ассемблера и существенно облегчают работу программиста. Вводя свои мнемонические правила, следует записывать их в комментариях. Необходимо следить за непротиворечивостью этих правил, дабы не запутаться самому. При выборе своего стиля программист должен предусматривать меры по уменьшению вероятности разного рода ошибок при вводе исходного текста и его коррекции. Некоторые широко используемые приемы такого рода рассмотрены ниже.
Необходимы определенные правила и при выборе длины имени. Некоторым программистам нравится использовать короткие имена, но чрезмерное увлечение сокращением объема исходного текста в байтах не всегда оправдано. Умеренная избыточность в длинах имен полезна, так как она уменьшает вероятность совпадения с другим именем в случае опечатки. Транслятор способен выявлять опечатки только в том случае, когда результат ошибки не приводит к совпадению с другими именами в программе. В том случае, когда "время жизни" переменной ограничивается несколькими командами или небольшим блоком команд, целесообразно использовать для нее регистр общего назначения или ячейку памяти с однобуквенным именем. Полезно также использовать локальные метки для передачи управления в пределах небольшого блока. В остальных случаях общепринятые правила выбора имен рекомендуют назначать короткие имена объектам в модуле и длинные — объектам, используемым для связи между модулями.
Еще одной группой мелочей, которые могут добавить массу неприятностей, являются константы. Во-первых, при записи констант программист может допустить ошибки в вычислениях. Во избежание этого нужно пользоваться теми возможностями, которые предоставляет ассемблер для перехода от одной системы счисления к другой и для вычисления выражений. Поэтому нужно записывать константы в таком виде, чтобы смысл их был понятен программисту, а пересчет их значений во внутренний код будет произведен автоматически. Числовые константы удобнее записывать в десятичном виде. Логические константы удобнее записывать в двоичном или шестнадцатеричном виде. Символьные константы удобнее записывать в виде строки. Если константа получается как результат каких-то арифметических вычислений, то лучше записать ее в виде выражения, объяснив в комментарии смысл его операндов. Такой стиль записи констант облегчает поиск ошибок, чтение программы и ее модернизацию. Во-вторых, при записи одной и той же константы в разные операторы возможна ошибка (описка). Во избежание этого следует использовать подстановки.
Числовые и простые текстовые подстановки являются весьма полезными с точки зрения борьбы с опечатками. Их эффективность проявляется при создании исходных текстов, но еще более они нужны при коррекции программ. Если в процессе создания программы еще можно (хотя и трудно) уследить за числовыми или логическими константами, записанными в разных командах, то сделать это при коррекции практически невозможно. Так что настоятельно рекомендуется использовать поименованные константы, определяемые числовыми подстановками. Их использование полностью исключает возможность ошибочной записи разных значений одной и той же константы в разные операторы.
Пользу простых текстовых подстановок можно продемонстрировать на следующем примере. При записи исходного текста программы, использующей регистры общего назначения, очень легко перепутать номера регистров. Ведь транслятор не может обнаружить ошибочный ввод цифры в имени регистра, если эта цифра находится в пределах от 0 до 7. А если программист при помощи простой текстовой подстановки задаст свои мнемонические обозначения регистрам микроконтроллера, это существенно уменьшит вероятность необнаруженных опечаток.