Читайте также:
|
|
Компилятор языка С/С++ предваряет любое внешнее имя знаком подчеркивания. Поэтому чтобы имя метки или переменной из ассемблерного модуля было видно в функциях С/С++, следует:
- либо метку в ассемблерном модуле начинать с подчеркивания;
- либо в программе на С при описании внешней метки использовать конструкцию вида:
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;
Дата добавления: 2015-11-16; просмотров: 52 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Передача параметров в функции и возврат значений | | | Вызов подпрограммы на ассемблере из программы на С |