Встроенный ассемблер
Встроенный ассемблер Logisim-evolution предназначен для трансляции исходного текста программ в исполняемый машинный код (байт-код) целевого процессора. Редактор поддерживает автоматическую подсветку синтаксиса и динамическое обнаружение ошибок.
Примечание архитектора: Хотя внутренняя структура компилятора проектировалась с возможностью генерации стандартных файлов формата ELF, на данный момент эта функция находится в стадии разработки — генерация машинного кода осуществляется напрямую в память имитационной модели.
Интерфейс графического редактора
При запуске ассемблера открывается рабочее окно, состоящее из трёх основных областей:
- Панель инструментов — верхняя горизонтальная панель со значками быстрого доступа;
- Панель нумерации строк — левая вертикальная полоса, на которой также отображаются маркеры ошибок;
- Область редактирования — текстовое поле для написания и разбора исходного кода.
Функции панели инструментов
Иконки на панели предоставляют быстрый доступ к командам (многие из них продублированы горячими клавишами):
— Загрузить файл:
открывает исходный код из внешнего файла на диске. Горячие клавиши: Ctrl-L.
—
Сохранить файл: перезаписывает текущий открытый файл. Горячие клавиши: Ctrl-S.
— Сохранить
как…: открывает диалоговое окно для сохранения файла под новым именем.
—
Ассемблировать: выполняет синтаксический анализ и трансляцию кода без загрузки. Горячие клавиши: Alt-A.
— Предыдущая
ошибка: перемещает курсор к ближайшей ошибке выше по тексту. Горячие клавиши: Ctrl-P.
— Следующая
ошибка: перемещает курсор к ближайшей ошибке ниже по тексту. Горячие клавиши: Ctrl-N.
— Собрать и загрузить:
транслирует код и, при отсутствии ошибок, автоматически прошивает полученный байт-код в память имитационной модели SoC.
Горячие клавиши: Alt-R.
— Справка: открывает
текущую страницу документации.
Индикатор изменений: Справа от кнопок выводится текущая позиция курсора (строка/колонка) и общее число строк. Если этот счётчик подсвечивается жёлтым цветом, это сигнализирует о наличии несохранённых изменений в коде.
Диагностика ошибок в тексте
Строки с некорректным кодом подчёркиваются в редакторе тонкой красной линией, а на левой панели появляется соответствующий значок. При наведении указателя мыши на подчёркнутый фрагмент или на значок ошибки всплывает текстовое окно с её подробным описанием.
Важные ограничения парсера:- Если на одной строке допущено несколько синтаксических ошибок, на левой панели отобразится маркер только для первой из них;
- При разборе арифметических выражений красной линией может быть подчёркнут не весь ошибочный блок, а лишь его часть (например, только неверный операнд или число).
Математические вычисления и выражения
Ассемблер позволяет использовать математические выражения для динамического расчёта адресов и констант. Выражения разделяются на два типа:
- Относительно счётчика команд (PC): расчёт смещения ведётся от текущей исполняемой инструкции с обязательным использованием зарезервированного ключевого слова pc (например: pc+8, pc-0x40, mylabel-pc);
- Абсолютные вычисления: рассчитывают константное статическое значение с использованием предопределённых глобальных меток и констант.
Поддерживаемые арифметические операторы
- + — сложение;
- - — вычитание;
- * — умножение;
- / — целочисленное деление;
- % — остаток от деления (модуль);
- << — побитовый сдвиг влево;
- >> — побитовый сдвиг вправо.
Ограничение синтаксиса: Круглые скобки для явного задания приоритета в текущей версии ассемблера не поддерживаются.
КРИТИЧЕСКИ ВАЖНОЕ ПРАВИЛО:Вычисления выполняются строго последовательно слева направо, стандартный математический приоритет операторов полностью отсутствует!
- Выражение 5+10*2 будет обработано как (5+10)*2 и вернёт результат 30;
- Выражение 10*2+5 будет обработано как (10*2)+5 и вернёт результат 25.
Использование макросов
Макросы позволяют автоматизировать вставку повторяющихся блоков инструкций. Шаблон объявления макроса имеет вид:
.macro <имя_макроса> <количество_аргументов>
[Тело макроса: инструкции и локальные метки]
.endm
- <имя_макроса> — уникальный идентификатор для вызова макрокоманды в основном тексте программы;
- <количество_аргументов> — неотрицательное целое число (0, 1, 2…), определяющее число передаваемых параметров.
Параметризация: Внутри тела макроса обращение к переданным аргументам выполняется по их порядковому номеру через символ @ (например: @1 — первый параметр, @2 — второй и т. д.).
Локальная область видимости: Все метки, объявленные внутри тела макроса, изолированы (локальны) — к ним невозможно обратиться из основного кода программы. Сам макрос при этом может свободно ссылаться на любые внешние глобальные метки.
Вложенность: Допускается вызов одного макроса из тела другого. Однако рекурсия (вызов макросом самого себя) и циклические вызовы (взаимный вызов двух макросов друг другом) строго запрещены.
Директивы ассемблера
Объявление меток
Метки служат для именования контрольных точек и адресов переходов. Они декларируются с двоеточием на конце: <имя_метки>:. Имя метки обязано начинаться с латинской буквы и может состоять из символов латиницы, цифр и знака подчёркивания.
Объявление именованных констант (.equ)
Константы связывают текстовое имя со статическим значением. Синтаксис: .equ <имя> <значение_или_выражение>. Имя также должно начинаться строго с буквы.
Разделение на секции (.section)
Директива позволяет разбить исходный образ на функциональные сегменты: .section <имя_секции>. Поддерживаются четыре стандартных системных сегмента, для которых ключевое слово .section можно опускать:
- .text — исполняемый машинный код;
- .data — инициализированные глобальные переменные;
- .rodata — константы, доступные только для чтения;
- .bss — неинициализированные данные (заполняются нулями).
Комментарии (#)
Любой текст, расположенный в строке после символа решётки (#), считается комментарием и отбрасывается компилятором. Многострочные комментарии требуют установки символа # в начале каждой строки.
Строковые литералы
Для размещения строк в памяти используются директивы .string, .ascii или .asciz, после которых текст указывается в двойных кавычках: "текст". Строка может содержать стандартные управляющие escape-последовательности:
- \n — перевод строки (LF);
- \r — возврат каретки (CR);
- \t — горизонтальная табуляция;
- \f — разрыв страницы;
- \" — символ двойной кавычки;
- \\ — обратный слэш.
Важное отличие: Директивы .string и .asciz в отличие от .ascii автоматически добавляют в конец строки скрытый нулевой байт (\0), сигнализирующий о завершении строки.
Управление адресацией памяти (.org)
По умолчанию сборка проекта начинается с нулевого адреса (0x00000000). Изменить текущий указатель адреса размещения последующих инструкций или данных можно директивой .org <32-битный_адрес>.
Внимание: Ассемблер контролирует пересечения адресов только на границах разных секций. Если внутри одного сегмента директива .org возвращает указатель назад на уже заполненную область, старые данные будут перезаписаны новыми без вывода предупреждений.
Размещение констант в памяти
Для заполнения памяти фиксированными значениями используются перечисленные ниже директивы. При работе с многобайтными величинами упаковка данных всегда выполняется по стандарту little-endian (младший байт пишется по меньшему адресу):
- Побайтово: .byte выражение1[, выражение2, ...] — запись последовательности 8-битных данных;
- По словесно (16 бит): .half, .2byte или .short значение1[, значение2, ...] — последовательность 16-битных слов;
- По двойному слову (32 бита): .word, .4byte или .long значение1[, значение2, ...] — последовательность 32-битных значений;
- По четвёрному слову (64 бита): .dword, .8byte или .quad значение1[, значение2, ...] — последовательность 64-битных значений.