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

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

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

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

extern "asm" {}

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

Описание функции в asm-модуле Объявление функции в С-модуле
.global _asmfunc; … _asmfunc: … void asmfunc(void); … asmfunc(); …
.global asmfunc; … asmfunc: … extern "asm" void asmfunc(void); … asmfunc(); …

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

Для облегчения работы со стеком при вызове и возврате из подпрограмм, сохранении/восстановлении регистров и очистки стека от передаваемых в подпрограмму параметров может быть использован ряд макросов, описанных в файле 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;


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: