Читайте также:
|
|
Рекомендуемый способ создавать подпрограмму языка ассемблера с правильным интерфейсом состоит в том, чтобы начать его с исходного файла языка ассемблера, созданного компилятором C. Обратите внимание, что вы должны создать скелетный код для каждого функционального прототипа.
Следующий пример показывает, как создавать скелетный код, к которому можно легко добавлять функциональное тело подпрограммы. Скелетный исходный текст должен объявить только требуемые переменные и исполнять простые доступы к ним. В этом примере, подпрограмма ассемблера берет int и double, и возвращает int:
extern int gInt;
extern double gDouble;
int func(int arg1, double arg2)
{
int locInt = arg1;
gInt = arg1;
gDouble = arg2;
return locInt;
}
int main()
{
int locInt = gInt;
gInt = func(locInt, gDouble);
return 0;
}
Примечание: В этом примере используется низкий уровень оптимизации при компилировании кода, чтобы показать доступ к локальным и глобальным переменным. Если более высокий уровень оптимизации используется, необходимые ссылки на местные переменные могли бы быть удалены в результате оптимизации. Фактическое объявление функции неизменно в независимости от уровня оптимизации.
Вызов подпрограмм ассемблера из C++
Соглашение о вызовах C не применимо к функциям C++. Наиболее важно, имя функции не достаточно идентифицировать функцию C++. Область действия и тип функции также требуются, чтобы гарантировать безопасное для типа редактирование, и разрешать перегрузку.
Другое различие в том, что не static функции члена устанавливают дополнительный, скрытый параметр, указатель this. Однако, при использовании взаимосвязи C, соглашение о вызовах соответствует соглашению о вызовах C. Подпрограмма ассемблера может поэтому вызываться из C++ когда объявлено следующим способом:
extern "C"
{
intmy_routine(int x);
}
Размещение доступа к памяти сложных структур данных не определено, и может изменяться между версиями компилятора. Поэтому рекомендуется обратиться к ним из подпрограмм ассемблера.
Чтобы достигать эквивалента не static функции члена, неявный указатель this должен быть сделан явным:
class X;
extern "C"
{
voiddoit(X *ptr, intarg);
}
Возможна “обертка” запрос к подпрограмме ассемблера в функции члена. Использование встроенной функции члена удаляет верхний из дополнительного кода запроса — при условии, что функция inlining позволяется:
class X
{
public:
inline void doit(intarg) {::doit(this, arg); }
};
Примечание: Поддержка для имен C++ из кода ассемблера чрезвычайно ограничена. Это означает что:
· файлы листинга ассемблера как результат от компилирования файлов C++ вообще нельзя приводить к ассемблеру.
· не возможно ссылаться или определять функции на C++ не имеющие замены на C в ассемблере.
Дата добавления: 2014-12-19; просмотров: 108 | Поможем написать вашу работу | Нарушение авторских прав |