Primula C Compiler     Xameleon Project        |        In English

Расширение синтаксиса ассемблера

Comment are off

Мы уже говорили что некоторые тонкости системы команд «Эверест» спрятаны за ассемблерными макросами. Пока не готов компилятор Си, нам приходится много писать на ассемблере и приходится прилагать много усилий для реализации сложных алгоритмов. Одной из проблем является необходимость помнить за что отвечает каждый из использованных регистров. Поэтому было принято решение о введении алиасов для регистров.

Простой пример — сторонний разработчик реализовал процедуру, которая возвращает указатель на голову списка, а у нас возникла необходимость посчитать количество элементов в этом списке. Обычно мы избегаем необходимости подсчитывать количество элементов в списке, вместо этого мы заводим переменную, которую увеличиваем на единицу при добавлении нового элемента и вычитаем единицу при удалении элемента. Это гораздо проще, чем каждый раз проверять все элементы списка для подсчёта их количества. Но сторонний разработчик не подумал над этим и возвращает нам лишь указатель на первый элемент списка. Проблему решает вот этот простейший код на Си:

item_counter

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

Для решения этой проблемы мы добавили возможность именовать регистры с помощью новой директивы ASSIGN.

assign r1 alias_for_structure ; Назначение имени регистру R1

Таким образом далее в тексте программы любое упоминание сочетания alias_for_structure автоматически заменяется на регистр r1.

Теперь берём на себя обязанности компилятора и вручную генерируем ассемблерный код для вышеприведённого примера программы:
sample_2_code

Строка с комментарием «просто тест» и есть просто тест, демонстрирующая возможности адресации. В случае генерации кода компилятором она бы не появилась в этом коде. Мы добавили её чтобы показать возможности нашего ассемблера. Заглянем в дизассемблированный дамп чтобы увидеть машинный код, сгенерированный из нашего примера:

sample_2_disasm

Теперь понятно, для чего мы добавили в пример лишнюю строку с чтением поля data_ptr структуры list_item — при нулевом смещении (первое поле структуры) ассемблер использует более короткую форму инструкции, что продемонстрировано на последней картинке.

Также мы обнаружили и исправили несколько небольших ошибок в ассемблере.

Наконец, мы обновили версию макроассемблера на нашем сайте, поместив в один архив версию для Windows и версию для Linux — обе версии собраны из одного и того же исходного кода. Чтобы получить исполняемые версии для Linux, вам потребуется с помощью следующей инструкции распаковать вложенный архив с исполняемым кодом для Linux:

tar xf linux_bin.tar

Оставить комментарий