Автор:
diver
Дата публикации: Дек 06, 2006 на данном форуме.
Форт-ассемблер для процессоров на базе ядра AVR32
Приводится описание кросс компилятора языка ассемблера для микропроцессорного ядра фирмы Atmel – AVR32, реализованного на языке Форт. Кратко описаны особенности языка ассемблера и структуры программных кодов процессорного ядра. Представлены варианты решений компилятора, рассмотрена реализация групп команд по способу компиляции кода и отдельных команд, не входящих в подобные группы.
Введение
Рынок современных контроллеров представлен широким спектром 4-8-16-32-х разрядных решений многих фирм производителей. Как правило, большинство контроллеров имеют солидную поддержку программным обеспечением как то фирм производителей, поставляющих ассемблеры для своих изделий, так целого ряда фирм, специализирующихся на компиляторах языков среднего и высокого уровня (IAR systems, Sun Microsystems, Forth Inc.[1-3]), представляющих на рынке компиляторы языков C/C++, Java, Forth, для встраиваемых систем. Эта тенденция не обходит стороной и проекты с открытыми исходными кодами (Open Source Projects)[4].
Несмотря на достаточно недавнее появление на рынке процессорного ядра AVR32 и микроконтроллеров на его основе, многие компании уже предлагают для него соответствующие компиляторы, в частности языка С/С++. Ядро AVR32 обладает достаточной производительностью и объемом адресного пространства для поддержания достаточно серьезных операционных систем.
Основные языки для написания программ и операционных систем для встраиваемых систем на сегодняшний день – C, Java и ассемблер. Причем ассемблер используется для написания критичных по времени приложений, функций, либо простейших операционных сред. В этом ключе несколько обделены вниманием форт-системы, появившиеся в конце 70-х начале 90-х годов прошлого века [6]. Форт-системы изначально сочетали в себе функции компилятора, интерпретатора, среды разработки и операционной системы. Из-за своей специфики форт-системы сегодня являются узкоспециализированными эффективными системами.
Целью данной работы является реализация языка ассемблера процессорного ядра AVR32 для использования при целевой компиляции программ и в качестве основы для написания ядра виртуальной форт машины (FVM). Форт ассемблер реализован при помощи компилятора SP-Forth 4.07 [5].
Особенности архитектуры AVR32
Хотя AVR23 заявлен Atmel как процессор с RISC архитектурой набор его команд имеет довольно длинный список в 180 команд, включая поддержку DSP,языка Java, взаимодействие с математическим сопроцессором [7]. Команды процессора могут содержать до 4-х операндов, и до 5-ти операндов содержат команды работы с сопроцессором. Команды работы с памятью содержат 2 – 4 операнда, при этом одной мнемонике может соответствовать до 5-ти вариантов кода и, соответственно комбинаций кода, одним из примеров является команда загрузки слова в память:
Код:
ld.w Rd, Rp++
ld.w Rd, --Rp
ld.w Rd, Rp[disp4]
ld.w Rd, Rp[disp16]
ld.w Rd, Rp[Ri<<sa]
ld.w Rd, Rp[Ri:half<<2].
Следует отметить, что Atmel , по-видимому, были приложены значительные усилия по достижению компактного бинарного кода. Количество видов кодировки инструкций и операндов, по документации, равно 58. Из них 18 видов (~32%) являются 16-ти битными. Оборотной стороной этого является повышенная нагрузка на компилятор, который должен корректно обрабатывать многочисленные варианты кодировок инструкций. В частности, затруднена работа с константами и непосредственными численными значениями: часто число при этом “рассеяно” по двум или четырем байтам кода [7]. Регистры процессора представлены 13-ю регистрами общего назначения, указателем стека, программным счетчиком, регистром связи, регистром статуса и набором из 71-го системного регистра, отраженных в адресное пространство процессора.
Форт-ассемблерКак отмечено в [8-10], Форт является простейшим языком для написания ассемблера. Любая Форт-система имеет текстовый интерпретатор для разбора текстовых строк и выполнения соответствующих команд. А основной задачей ассемблера является преобразование текстовых строк в байты кода. Операнды и режимы адресации также реализуются через слова Форта.
Язык также включает определяющие слова, которые позволяют легко описать большие наборы слов с общим действием. Эта возможность очень полезна при определении мнемоник ассемблера. При работе ассемблера доступны все слова Форта, и они могут быть использованы при использовании ассемблера не только для вычисления адресов и операндов, но и для выполнения более сложных действий.
Реализация Форт-ассемблера avr32fasmAvr32fasm состоит из двух словарей. Словарь avr32-cross, содержит слова для работы с памятью целевой системы, выделения и разбора операндов, сборки и компиляции процессорных команд в выделенную область памяти инструментальной системы. Слова из avr32-cross используют базовый словарь Форт системы – FORTH.
Словарь avr32-asm содержит слова, определяющие аппаратные ресурсы целевого процессора, коды условий переходов и реализации самих команд ядра AVR32.
Avr32-asm при компиляции новых определений использует слова двух словарей avr32-cross и FORTH.
Изначальная ориентация avr32fasm на интеграцию в Форт систему позволяет исползовать набор ранее определенных меток и ссылок на них (аналогично словам @@1:, @@1 в реализации ассемблера для x86/Pentium [11]), так называемые локальные метки, действующие внутри слов. Данное решение позволяет применять однопроходовую технологию, характерную для большинства Форт-систем. При способе упаковки кода, примененного в AVR32, это упрощает компиляцию меток внутри слов и вызовов слов непосредственно из ассемблерных определений.
Словарь avr32-crossСловарь avr32-cross состоит из слов, необходимых для компиляции ассемблерных инструкций в область памяти, отведенную под целевой код. Начало целевой памяти находится в value-переменной THERE0, переменная THERE содержит текущее значение. Слово TW, компилирует слово в целевое пространство:
Код:
: TW, ( x -- ) THERE W! THERE 2 + TO THERE ;
.
Поскольку ассемблер префиксный, в задачи слова, компилирующего инструкцию, входит разбор строки операндов, сборка кода инструкции и компиляция его в целевое пространство. Синтаксис, реализованный в avr32fasm, близок к синтаксису ассемблера AVR32, за исключением зависимости от регистра и строгой необходимости разделять пробелами команду и операнды, а так же сами операнды между собой:
Код:
инструкция операнд_1, операнд_2, … операнд_N .
Для разбора части строки, следующей за инструкцией, используются слова Форта для интерпретации входного потока. Операнды при этом являются словами ассемблерного словаря и при исполнении оставляют свой код на стеке, например:
Код:
: next-reg:half ( 1|0 -- Rd :x ) \ разделяет операнд вида: 'Rd:x,' и 'Rd:x'
NextWord ROT - \ x -- addr n-x \ 'Rd:t'
2DUP 2 - SFIND IF EXECUTE ELSE 2DROP ABORT THEN \ -- addr n Rd
-ROT + 2- 2
SFIND IF EXECUTE ELSE 2DROP ABORT THEN \ -- Rd :x
;
Для ассемблерных инструкций с несколькими наборами операндов, таких как группы команд обмена с памятью ld и st, применяется рекурсивный алгоритм разбора строки операндов.
Код:
: l/s-operand ( addr n -- x[...] type )
reg++ IF 4 EXIT THEN
--reg IF 5 EXIT THEN
0x5B str ! \ ищем [
2DUP \ -- addr n addr n
str 1 SEARCH \ addr n addr[ n2 io
IF \ -- addr n addr[ n2
DUP >R 2SWAP R> - take-op -ROT \ -- Rp addr[ n2 ,-взяли Rp
SWAP 1+ SWAP 2- \ -- Rp addr2 n2 ,убрали [ из строки
10 n +! RECURSE \ n=1
ELSE 2DROP THEN
0x3C3C str ! \ ищем <<
2DUP str 2 \ -- addr2 n2 addr2 n2
SEARCH \ -- addr2 n2 addr<< n3 io
IF \ -- addr2 n2 addr<< n3
2DUP 2>R NIP - \ addr2 n2-n3
2DUP S" :" SEARCH NIP NIP \ addr2 n2-n3 :half?
IF \ часть регистра
reg:half-str 4 LSHIFT OR \ -- Ri :half \ -- :halfRi
2 n +!
ELSE \ целый регистр и sa
take-op \ -- Ri addr<< n3 ,-взяли Ri
THEN
2R> 2 - SWAP 2+ SWAP \ -- Ri addrSA n4 , осталась строка в фомате str
2 n +! RECURSE \ n=2
ELSE 2DROP THEN \ -- addrSA n4
take-op \ при операндах типа [Rp] - неопределенная ситуация
DUP 7 > IF -1 n +! THEN
n 1+! \ -- disp|sa
n @ 0 n !
LEAVE
;
Слово l/s-operand определяет операнды видов: Rp++, --Rp, Rp[disp4], Rp[disp16], Rp[Ri<<sa], Rp, Rp[Ri:x<<sa] . Оставляет на стеке коды составляющих операнда и число, идентифицирующее его тип.
В отдельную группу можно выделить слова, компилирующие коды операций и операндов в область целевой памяти, осуществляющие сборку кодов ассемблерных инструкций. Реализации этих слов различаются только из-за специфики формирования кода каждого из типов инструкций, примеры компилирующих слов:
Код:
: dsp-halfword ( Rd Rx :x Ry :y opcode -- )
4 LSHIFT SWAP 4 LSHIFT OR \ -- Rd Rx :x Ry opcode_0:y00
2 ROLL 5 LSHIFT OR \ -- Rd Rx Ry opcode:x:y00
3 ROLL OR TW, \ opcode:x:yRd -- Rx Ry
0xE000 OR SWAP 9 LSHIFT OR TW, ;
По способу компиляции кода инструкции были выделены в тридцать пять групп. В пределах группы ассемблерные инструкции имеют один формат. Для компиляции кода инструкций определены специальные слова, созданные на основе конструкции CREATE DOES>:
Код:
: halfword-arith-instr \ using op1 halfword-arith-instr instr-name
\ syntax: addhh.w Rd, Rx:x, Ry:y
CREATE , CELL ALLOT
DOES> @ >R 1 next-reg 1 next-reg:half 0 next-reg:half \ -- Rd Rx :x Ry :y
R> dsp-halfword ;
и др.
Определяющие слова используют один или несколько кодов инструкций и вызывают необходимые для каждого типа ассемблерных команд слова выборки операндов. В словаре avr32-asm эти слова применяются при создании ассемблерных инструкций форт-ассемблера.
Словарь avr32-asmСловарь avr32-asm содержит коды операндов, условий перехода и ключи модификации операндов. В данный словарь включены инструкции, компилированные при помощи определяющих слов из avr32-cross, а также инструкции в силу специфики своего кода, не вошедшие в группы и определенные через двоеточие.
Регистры файл-регистра процессора и системные регистры, отраженные в адресное пространство определены в словаре, как обыкновенные константы (при помощи слова CONSTANT). Аналогичным образом определены и условия перехода.
Большинство инструкций ассемблера компилируются с помощью определяющих слов из словаря avr32-cross:
Код:
0xA100 0x0002 0xE0E0 0x0000 0xA110 0xA101 load-instr ld.d
\ syntax: ld.d Rd, Rp++
\ syntax: ld.d Rd, --Rp
\ syntax: ld.d Rd, Rp[disp4]
\ syntax: ld.d Rd, Rp[disp16]
\ syntax: ld.d Rd, Rp[Ri<<sa]
\ syntax: ld.d Rd, Rp[Ri:half<<2]
.
Двадцать три команды, образующие “группы” из одной команды, определены через двоеточие, к примеру, инструкции работы с кэш памятью, сопроцессором, поддержки языка Java и некоторые арифметические операции:
Код:
: cop \ syntax: cop CP#, CRd, CRx, CRy, Op
1 next-op 1 next-reg 1 next-reg 1 next-reg 0 next-op \ -- CP#, CRd, CRx, CRy, Op
DUP 2/ >R \ сохранили Ор на будущее
0x1 AND 12 LSHIFT >R \ -- CP#, CRd, CRx, CRy ; r: -- op op'
SWAP 4 LSHIFT OR SWAP 8 LSHIFT OR SWAP 13 LSHIFT OR
\ собрали операнды
\ -- CP#0CRdCRxCRy r: -- op op'
R> OR TW,
R> DUP 0xF AND SWAP 0x30 AND 5 LSHIFT OR \ -- op''
0xE1A0 OR TW, ;
Выводы и результаты
Словарь кросс ассемблера содержит порядка 335 слов, включая инструкции и регистры процессорного ядра. Общий размер скомпилированного кода форт-ассемблера asm32fasm составляет 25697 байт. Представленный форт-ассемблер avr32fasm предоставляет программисту максимально близкий синтаксис к обычному ассемблеру при сохранении функциональности языка Форт, и представляет собой однопроходной префиксный ассемблер без оптимизации кода. Текущая версия компилируется системой SP-Forth 4.007 [5].
Литература
1. IAR systems./
http://www.iar.com
2. Sun Microsystems. /
http://www.sun.com
3. Forth Inc. /
http://www.forth.com
4. Open Source Projects /
http://www.sourceforge.net
5. SP-FORTH - ANS FORTH 94 for Win95/98/ME/NT/2000/XP Open source project /
http://spf.sf.net
6. Дьяконов В.Н. Форт-системы программирования персональных ЭВМ. – М.:Наука. Гл. ред. физ.-мат. лит., 1992 – 352с.
7. AVR32 Architecture Document, Atmel Corporation 2006 /
http://www.atmel.com/literature
8. С.Н. Баранов, Н.Р. Ноздрунов Язык Форт и его реализации. Лениград. Машиностроение, Ленинградское отделение,1988.
9. Leo Brodie Thinking FORTH A Language and Philosophy for Solving Problems Englewood Cliffs, N.J., Prentice-Hall, Inc., 1984
10. Brad Rodriguez Build Your Own (Cross-) Assembler....in Forth /
ftp://ftp.forth.org/pub/Forth.
11. 486 and Pentium assembler for Windows 32bit Forth, version 1.26 1994, 1995, by Jim Schneider /
ftp://ftp.netcom.com/pub/ja/japs/486asm.zip