Программа рис. 1.19 практически полностью соответствует
программе рис. 1.17. Отличие заключается в том, что экспортируемые
имена предваряются подчеркиванием (соглашение языка С) и
объявляются директивой GLOBAL. Небольшое отличие наблюдается в
функции _out_char. Ее аналог out_char_ax1 принимает символ (для выдачи
в UART) в регистре ах1, а _out_char – через программный стек Поэтому в
индексном регистре I6 формируется указатель на выдаваемый символ,
хранящийся в стеке.
Передаваемые в качестве параметров функции значения хранятся по
следующим адресам: первый аргумент – в SP + 1, второй – в SP + 2 и т.д.
SP хранится в индексном регистре I4, поэтому первым шагом при
формировании указателя на передаваемый параметр является I6 = I4.
Затем в модификационный регистр М5 записывается 1 и окончательно
командой MODIFY(I6, M5); формируется указатель.
Простота адаптации уже написанных программ на ассемблере
позволяет широко использовать их в программах на СИ. Необходимо
только следить, чтобы соблюдались соглашения об доступных (scratch),
сохраняемых (preserved) и предопределенных (dedicated) регистрах.
//---------- Содержимое файла AsyncMix.ldf
ARCHITECTURE(ADSP-2181) // определение типа процессора
SEARCH_DIR( $ADI_DSP\218x\lib ) // определение пути к библиотекам
// Имена файлов, библиотек, ключей берутся из командной строки,
// необходимо также подключить libc.dlb, но это можно сделать также
// через Project | Project Options | Link | Additional options: libc.dlb
$OBJECTS = $COMMAND_LINE_OBJECTS, libc.dlb;
// 2181 имеет 16K слов (24-bit) ПП и 16K слов (16-bit) ПД
MEMORY {
// Используем всю доступную ПП и ПД
int_area {TYPE(PM RAM) START(0x0000) END(0x002f) WIDTH(24)}
prog_area {TYPE(PM RAM) START(0x0030) END(0x37fe) WIDTH(24)}
data_area {TYPE(DM RAM) START(0x0000) END(0x2fff) WIDTH(16)}
heap_area {TYPE(DM RAM) START(0x3000) END(0x37ff) WIDTH(16)}
stack_area {TYPE(DM RAM) START(0x3800) END(0x3fdf) WIDTH(16)}
}
PROCESSOR p0 {
// Ключи для линкера берутся из командной строки
LINK_AGAINST( $COMMAND_LINE_LINK_AGAINST )
// Имя выходного файла берется из командной строки
OUTPUT( $COMMAND_LINE_OUTPUT_FILE )
SECTIONS {
// Секция таблицы векторов прерываний,
// названия векторов определены в 218x_int_tab.asm
sec_int {