- PVSM.RU - https://www.pvsm.ru -
Ряд статей (раз [1], два [2], три [3]) навел на мысли о том, что Excel можно использовать как транслятор в ассемблерный код AVR.
Сопоставим Excel с основными фичами «обычного» редактора кода. Список самых популярных фич следующий:
Фича редактора кода | Как реализовать в Excel | Как реализовано в Atmel Studio |
---|---|---|
Подсветка синтаксиса | Условное форматирование ячеек в зависимости от содержания | Подсветка команд |
Автодополнение | Пользовательские функции VBA; Именованные диапазоны; Ячейка как миниконсоль с макросом на cобытие Change; |
Нет |
Отступы | Вручную переход в соседний столбец | Вручную |
Проверка правильности расстановки скобок | Есть встроенный контроль | Только при сборке |
Контекстная помощь по коду | Нет | Есть список имен меток |
Сворачивание блока кода | Функция группировки столбцов и строк | Нет |
Статический анализатор | На ходу показывает ошибки в ссылках | Нет |
Выглядит приемлемо. Кое-что достается «даром», кое-что надо доработать.
Но главное отличие табличного процессора от текстового – пользователь может размещать блок информации в произвольном месте пространства, а не только друг под другом. Эту особенность мы используем, чтобы превратить плоский код в почти полноценную блок-схему.
Общий подход и терминологию примем отсюда. [1]
Весь алгоритм разделим на ветки. Ветка играет роль самостоятельного программного блока.
У каждой ветки есть имя, которое является точкой входа в нее. Оно должно быть уникальным и осмысленным. Все имена веток размещаются в верхней строке, которую так и назовем – «строка имен».
Ветка заканчивается одним или несколькими переходами к другим веткам. Переходы от одной ветки к другой размещаются в самой нижней строке. Назовем ее «строка переходов».
Также принимаем правило, что изнутри одной ветки нельзя переходить внутрь другой.
Для ветвлений и циклов внутри ветки также применяются метки. То есть меток в программе очень много. Каждый раз придумывать новое уникальное имя – это рутина. Здесь на помощь приходит базовая функциональность Excel. Каждая ячейка уже имеет уникальное имя, состоящее из имени столбца и номера строки.
На VBA создадим функцию label с аргументом типа Range. Метка в ассемблере AVR должна иметь на конце двоеточие. Т.е. наша функция labelполучает на вход ссылку на ячейку, в которой размещается сама и вычисляет ее адрес в формате A1. Затем добавляет к ней текст «_M:». Фрагмент «_M» не случаен, мы будем использовать это дальше – в форматировании ячеек.
В настоящих визуальных средах переходы обозначаются стрелками. Это удобно и наглядно.
В табличном процессоре вместо стрелочек можно подкрашивать ячейки, образующие путь к метке от команды перехода. В примерах так и сделано.
Если получается уместить весь код ветки на один экран, то можно не отрисовывать маршруты. Все команды перехода и метки будут перед глазами.
Для блок-схем существуют стандарты на обозначения отдельных элементов. Например, прямоугольник – это вычисление; ромб – условие и т.д. При работе с табличным процессором нам доступны управление цветом, начертанием и границами.
В Excel есть удобная функция условного форматирования. Использовать ее можно по-разному, но мы введем всего три простых правила:
На гифке ниже представлено, как работа с метками и переходами выглядит после всех настроек.
Сборщик листинга обходит итоговую программу сверху вниз и справа налево. По одной ячейке за раз.
Алгоритм сборки пропускает пустые ячейки и ячейки, которые содержат символ «;», т.е. комментарии.
Отладка алгоритма и окончательная сборка проекта происходит в студии. Обратная связь кода в студии с ячейками Excel отсутствует. Поэтому для ловли ошибок в итоговый листинг напротив каждой команды указываем ссылку на ячейку. По этой ссылке мы находим проблемную команду на схеме в Excel.
Базовое алгоритмическое решение – это ветвление вида:
If <условие> then
<действие>
Else
<действие>
End if
Для него в ассемблере AVR есть команды условного перехода (breq, brne, sbic и прочие). Эти команды указывают программе, куда перейти при выполнении условия.
Теперь представим, как должна выглядеть программа такого ветвления с учетом озвученных выше принципов:
У команды brne и ее аналогов есть ограничение. Дальность перехода составляет 64 слова в каждую сторону. Поэтому длинный макрос, вставленный в ответвление «Нет» может вызвать out of range.
Для обхода этого ограничения обработку «Нет» производить в отдельной ветке, которая будет правее метки перехода от brne. Либо использовать подпрограмму, в которой вызывается макрос.
Если выбирать приходится из большого количества вариантов, в ЯВУ используется Select Case:
Select Case <переменная>
Case <условие1>
Case <условие2>
Case <условие3>
Case else
End select
На ассемблере под AVR доступны индексные переходы. Покажем вариант реализации.
Здесь видно, что нарушен запрет прыжка из тела ветки к другой ветке. Это сделано преднамеренно, иначе программа займет слишком много места по горизонтали.
По этой же причине вектор прерываний следует выполнить в один столбик.
Цикл, когда необходимо минимум одно повторение, в нотации ЯВУ выглядит следующим образом:
Do
<действие>
Loop while <условие>
Пример, как это выглядит в Excel и итоговый код в студии:
Пример на ЯВУ:
Do while <условие>
<Действие>
Loop
Пример, как это выглядит в Excel и итоговый код в студии:
Обработка массивов или работа с числами предполагает использование вложенных циклов.
Общий вид на ЯВУ:
Do
Do
<действие>
Loop while <условие 2-го уровня>
<действие>
Loop while <условие 1-го уровня>
Реализовать вложенный цикл можно двумя путями: либо внутри одной ветки, либо с помощью нескольких веток. Покажем оба варианта.
Есть ситуации, когда из цикла необходимо выйти до его окончания. Например, логический ноль на 0-вой ножке порта D может говорить о какой-то неисправности. Программа должна покинуть основной цикл и запустить тревогу.
В ЯВУ используется команда break, а общий алгоритм имеет следующий вид:
Do
<действие>
If <условие прерывания> then break
Loop while <условие>
Снова покажем, как будет выглядеть алгоритм без веток и с ветками.
Подпрограммы вызываются командами call, icall, rcall. Тут есть важная особенность. Подпрограмму необходимо вызывать строго из тела ветки. Если же вызов разместить в строке переходов, возврат из подпрограммы почти гарантированно произойдет в неверное место.
Обязательные требования к подпрограмме:
Внутренняя структура подпрограммы может быть произвольной – применяем все те же автоматические метки label для реализации логики.
Приведем код тестовой программы с бегущим огоньком. Пример включает циклы, ветвления и вызов подпрограммы.
Конечный результат выглядит так:
Листинг всей программы в Excel со скрипом уместился на один экран:
Автор: PalaginAV30
Источник [4]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/358617
Ссылки в тексте:
[1] раз: https://habr.com/ru/post/345320/
[2] два: https://habr.com/ru/post/80893/
[3] три: https://habr.com/ru/post/246975/
[4] Источник: https://habr.com/ru/post/526838/?utm_source=habrahabr&utm_medium=rss&utm_campaign=526838
Нажмите здесь для печати.