Ассемблер

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

Сегодня появился трнаслятор ассемблерных мнемоник в машинный код и у процессора, о котором говорилось ранее. Рассмотрим подробнее несколько ассемблерных исходников:

;
; Главный тестовый модуль
;
function main
lea r1, $my_str ; Макро-операция загрузки адреса
push r15 ; Макро операция сохраняет адрес возврата (регистр 15) в стеке
call _strlen ; Макро-операция вызова функции
pop r15 ; Макро операция восстанавливает адрес возврата (регистр 15) из стека
return
end

$my_str db ‘Hello world!’,13,10,0

include strlen.asm

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

Функция _strlen определена во внешнем файле strlen.asm. Исходный код функции strlen код:

; Функция нахождения длины строки
; Вход: R1 — адрес строки
; Выход: R0 — длина строки в байтах

function _strlen
xor r0, r0 ; Обнуление длины
m1:
mov r2, (r1) ; Загрузка машинного слова
rol r2, 8 ; Циклический сдвиг на 8 бит влево
col load r3, 0xff ; Загрузка восьмибитной константы
and r3, r2 ; Первая проверка на конец строки
je done ; Найден терминатор строки
inc r0 ; Длина строки + 1
rol r2, 8 ; Циклический сдвиг на 8 бит влево
col
load r3, 0xff ; Загрузка восьмибитной константы
and r3, r2 ; Первая проверка на конец строки
je done ; Найден терминатор строки
inc r0 ; Длина строки + 1
rol r2, 8 ; Циклический сдвиг на 8 бит влево
col
load r3, 0xff ; Загрузка восьмибитной константы
and r3, r2 ; Первая проверка на конец строки
je done ; Найден терминатор строки
inc r0 ; Длина строки + 1
rol r2, 8 ; Циклический сдвиг на 8 бит влево
col
load r3, 0xff ; Загрузка восьмибитной константы
and r3, r2 ; Первая проверка на конец строки
je done ; Найден терминатор строки
inc r0 ; Длина строки + 1
inc r1, 4 ; Переход на следующее машинное слово
jmp m1 ; Продолжение подсчёта
done:
return ; Возврат из функции
end

Поскольку система команд активно дорабатывается, операции с разрядностью меньше машинного слова ещё не определены, поэтому в примере используется маска и сдвиги.

Результатом работы ассемблера является MIF файл в формате Altera Quartus. Такие файлы использу.тся в качестве образа ПЗУ и являются частью прошившки ПЛИС. Пример MIF файла, сгенерированного на основе вышеприведённых примеров:

— MIF file ROM microcode
WIDTH=32;
DEPTH=23;
ADDRESS_RADIX=HEX;
DATA_RADIX=HEX;
CONTENT BEGIN
0000 : 04910010;
0001 : 37e360ef;
0002 : 048f0018;
0003 : 68fe36e3;
0004 : 05000000;
0005 : 48656c6c;
0006 : 6f20776f;
0007 : 726c6421;
0008 : 0d0a0000;
0009 : 21006831;
000a : 32280c22;
000b : 3282002e;
000c : 36003228;
000d : 0c53ff22;
000e : 32820022;
000f : 36003228;
0010 : 0c53ff22;
0011 : 32820016;
0012 : 36003228;
0013 : 0c53ff22;
0014 : 3282000a;
0015 : 36003614;
0016 : 8fffce05;
END;

Помимо .MIF файла, ассемблер создаёт .VH файл с микрокодом для возможности симуляции проекта.

Демонстрационный архив с исполняемым файлом и простейшим примером: MacroAssemblerDemo


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