Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
AiPSP_ekzamen_main.docx
Скачиваний:
2
Добавлен:
01.07.2025
Размер:
1 Мб
Скачать
☆

2.5. Взаимодействие подпрограмм на с и ассемблере

2.5.1. Описания имен и области их видимости

Компилятор языка С/С++ предваряет любое внешнее имя знаком подчеркивания. Поэтому чтобы имя метки или переменной из ассемблерного модуля было видно в функциях С/С++, следует:

- либо метку в ассемблерном модуле начинать с подчеркивания;

- либо в программе на С при описании внешней метки использовать конструкцию вида:

extern "asm" {}

Не следует забывать, что в модуле, где метка описана, ее имя следует объявлять как global, а в модуле, в котором к ней идет обращение – как extern, например:

Описание функции в asm-модуле

Объявление функции в С-модуле

.global _asmfunc;

…

_asmfunc:

…

void asmfunc(void);

…

asmfunc();

…

.global asmfunc;

…

asmfunc:

…

extern "asm" void asmfunc(void);

…

asmfunc();

…

2.5.2. Макросы для работы со стеком при вызове и возврате из функций на ассемблере

Для облегчения работы со стеком при вызове и возврате из подпрограмм, сохранении/восстановлении регистров и очистки стека от передаваемых в подпрограмму параметров может быть использован ряд макросов, описанных в файле asm_sprt.h. Основные из них приведены в таблице.

Макрос

Программный код для ADSP-21060

Описание применения макроса

leaf_exit

i12=dm(m7,i6);

jump (m14,i12) (db);

nop;

RFRAME

Эпилог функции – последняя строка ассемблерной программы

ccall(x)

cjump (x) (DB);

dm(i7,m7)=r2;

dm(i7,m7)=PC

Вызов функции с именем x

reads(x)

dm(x, i6)

Читает значение из стека, которое находится со смещением x относительно указателя кадра стека (I6), например:

R0=reads(1) -> R0=dm(1,I6);

puts

dm(i7, m7)

Помещает в стек значение регистра, например:

puts=R0 -> dm(I7,M7)=R0;

gets(x)

dm(x, i7)

Читает значение из стека со смещением x относительно его вершины (I7):

R0=gets(3) -> R0=dm(3,I7);

alter(x)

modify(i7, x)

Изменяет значение указателя на вершину стека (I7) на число x, позволяя таким образом (при x>0) очистить стек от x верхних слов. Это может быть полезно при очистке стека от параметров процедуры в вызывающей функции

save_reg

puts=r0;\

puts=r1;\

...

puts=r15

Последовательно сохраняет в стеке все регистры регистрового файла

restore_reg

r15=gets(1);\

r14=gets(2);\

... r0=gets(16);\

alter(16)

Последовательно восстанавливает из стека все регистры регистрового файла и очищает стек

Пример подпрограммы на ассемблере с использованием макросов.

Вызов: my_func(int a, int b, int c, int d, int e);

#include <asm_sprt.h>

...

my_func: puts=R3; // сохранить R3

R3 = reads(1); // R3 = d (доступ к парам. отн. I6)

...

R3 = gets(1); // восстановить R3

alter(1); // и вытолкнуть его из стека - необязательно

leaf_exit;

my_func.end: nop;

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]