Читайте также:
|
|
Функции обработки прерываний
Функции обработки прерываний отличаются от обычных функций C по этому:
· Если используется, флажки и рабочие регистраторы сохранены
· вызовы функций обработки прерываний сделаны через векторы прерывания; прямые вызовы не позволяются
· нет аргументов для передачи в функции обработки прерываний
· возврат из функции обработки прерываний использует команду RETI.
Функции Монитора
Функции монитора вызывают блокирование прерываний в течение выполнения функции. При функциональном входе, состояние регистра SREG сохраняется и глобальные прерывания заблокированы. При выходе из функции происходит восстановление регистра SREG, и таким образом состояние прерывания, существующее перед функциональным запросом, также будет восстановлено
Примеры
Далее приводиться ряд примеров объявления и соответствующих соглашений о вызовах. Сложность примеров увеличивается к концу.
Пример 1
Предположим, что мы имеем следующее объявление функции:
intadd1(int);
Эта функция берет один параметр из регистров R17:R16, и возвращает значение к вызывающей её программе в регистрах R17:R16.
Следующая подпрограмма ассемблера совместима с объявлением; возвратит значение, которое является на один больше чем значение передаваемого параметра:
SUBI R16,FF
SBCI R17,FF
Пример 2
Этот пример показывает, как структуры передаются через стек. Предположим, что мы имеем следующие объявление:
struct a_struct { int a; int b; int c;};
int a_function(struct a_struct x, int y);
Функция запроса должна резервировать шесть байтов на вершине стека и копировать содержание struct к тому местоположению. Целочисленный параметр y передается в регистрах R17:R16. Возвращаемое значение передается назад к вызывающей программе в регистрах R17:R16.
Пример 3
Функция возвращающая struct.
structa_struct { int a; };
structa_structa_function(int x);
Функция запроса должна распределить местоположение памяти для возвращаемого значения и передавать указатель на неё как скрытый первый параметр. Указатель на местоположение, где возвращаемое значение должно быть сохранено, передается в первой паре регистра/регистров, которая является R16, R17:R16, и R18:R17:R16 для Tiny, Small, и Large модели памяти соответственно. Параметр x передается в R19:R18, R19:R18, и R21:R20 Tiny, Small, и Large модели памяти соответственно.
Предположим, что функция вместо того как объявляли, возвращает указатель на структуру:
structa_struct * a_function(int x);
В этом случае, возвращаемое значение - скаляр, так не имеется никакого скрытого параметра. Параметр x пропускают в R17:R16. Возвращаемое значение возвращено в R16, R17:R16, и R18:R17:R16 для Tiny, Small, и Large модели памяти соответственно.
Информация о структуре вызовов
При отладке приложения, использующего C-SPY, возможно рассмотреть стек вызовов, то есть функции, которые вызвали текущую функцию. Компилятор делает этот возможным, добавляя информацию отладки, которая описывает размещение структуры запроса, в особенности информацию относительно того, где сохранен адрес возврата.
CFI директивы обеспечат C-SPY информацией относительно состояния функции(й) запроса. Наиболее важный из этого - адрес возврата, и значение указателя вершины стека при входе подпрограммы ассемблера или функции. По этим данным C-SPY может восстанавливать состояние для функции вызова, и таким образом раскручивать стек.
Полное описание относительно соглашения о вызовах может потребоваться подробная информация о структуре вызовов. Во многих случаях, более ограниченный подход удовлетворит.
При описании информации структуры вызовов следующие три условия должны присутствовать:
· имя блока описания доступных ресурсов, которые будут прослежены
· общий блок, соответствующий соглашению о вызовах
· блок данных описание изменений, которые выполнены в структуре вызова. Это типично включает информацию относительно того, когда указатель вершины стека изменен, и когда постоянные регистры сохранены или восстановлены из стека.
Дата добавления: 2014-12-19; просмотров: 84 | Поможем написать вашу работу | Нарушение авторских прав |