- •Сергеев Сергей Набор данных прямого доступа (da - Direct access data sets)
- •Суворова Василиса
- •Ярков Павел
- •3. Описание блока управления данными ( для bsam(Basic sequential access method))
- •Наборы данных – pds и pdse
- •5.9.3 Что такое pdse?
- •Наборы данных vsam
- •Совмещение c и ассемблера Беляев Максим
- •Встроенные функции
- •СовмещениеC и модулей на ассемблере
- •Встроенный ассемблер
- •Вызов программ ассемблера из c
- •Создание скелетного кода
- •Соглашение о вызовах
- •Выборсоглашенияо вызовах
- •Функциональные объявления
- •Сохранение рабочих регистров
- •Вызов функции
- •Выход из функции
- •Ограничение для специальных типов функций
Сохранение рабочих регистров
AVR регистры CPU разделены на три отдельных части, которые описаны в этой главе.
Рабочие регистры
Любая функция может изменять содержание рабочего регистра. Если функция нуждается в значение регистра после вызова другой функции, оно должно сохраняться в течение этого вызова, например в стеке.
Для обоих соглашений о вызовах, следующие 14 регистров могут использоваться как рабочие регистры функций:
R0-R3, R16-R23, и R30-R31
Сохраняемые регистры
Сохраняемые регистры наоборот сохраняются вопреки вызовам функций. Любая функция может использовать сохраняемый регистр в своих целях, но должна сохранить прежнее значение до использования и восстанавливать его при выходе функции.
Для обоих соглашений о вызовах, следующие сохраняемые регистры используются:
R4-R15 и R24-R27
Обратите внимание, что регистраторы R4-R15 могут быть блокированы из командной строки, и использоваться для глобальных регистровых переменных; см. -lock_regs и __regvar.
Специальные регистраторы
Для некоторых регистраторов имеются некоторые предпосылки, которые вы должны рассмотреть:
указатель вершины стека регистр Y должен всегда указывать на последний элемент стека. В случае прерывания, все ниже точки, на который указывает указатель стека, будет разрушено.
При использовании -v4 или -v6 опции процессора, регистр RAMPY - указатель на часть стека данных.
При использовании опции процессора, которая использует любой из регистров EIND, RAMPX, или RAMPZ, эти регистры работают как рабочие регистры.
Вызов функции
В течение вызова функции, вызываемая функция:
передает параметры, или в регистрах или через стек
помещает все остальные параметры в стек данных (CSTACK)
Управление передается вызываемой функции с адресом возврата, автоматически задвинутым в стек адреса возврата (RSTACK).
Вызываемаяфункция:
сохраняет любых локальные регистры необходимые функции в стеке данных
распределяет пространство для авто переменных и временных значений
продолжает выполнять непосредственно саму функцию.
Регистровые параметры против параметров стека
Параметры можно передавать функции, используя один из двух основных методов: в регистрах или в стеке. Намного более эффективно использование регистров, чем брать их из памяти, поэтому соглашение о вызовах разработано так, чтобы использовать регистры в максимально возможной степени. Параметры сохранения, не переданные в регистрах, передаются через стек.
Регистровые параметры
Для обоих соглашений о вызовах, регистраторы, доступные для проходящих параметров:
R16-R23
Параметры распределяются по регистрам согласно алгоритму первого подходящего, используя требования выравнивания параметра согласно следующей таблице:
Параметр |
Выравнивание |
Используемые регистры |
8-bit значение |
1 |
R16, R17, R18, R19, R20, R21, R22, R23 |
16-bit значение |
2 |
R17:R16, R19:R18, R21:R20, R23:R22 |
24-bit значение |
4 |
R18:R17:R16, R22:R21:R20 |
32-bit значение |
4 |
R19:R18:R17:R16, R23:R22:R21:R20 |
Назначение регистров, использующее старое соглашение о вызовах
В старом соглашении о вызовах, два крайних левых параметра передаются в регистрах, если они скалярные и до 32 битов в размере.
Следующая таблица показывает некоторых из возможных комбинаций:
Параметры |
Параметр 1 |
Параметр 2 |
f(b1,b2,…) |
R16 |
R20 |
f(b1,w2,…) |
R16 |
R20, R21 |
f(w1,l1,…) |
R16, R17 |
R20, R21, R22, R23 |
f(l1,b2,…) |
R16, R17, R18, R19 |
R20 |
f(l1,l2,…) |
R16, R17, R18, R19 |
R20, R21, R22, R23 |
Где b обозначает, 8-разрядный тип данных, w обозначает 16-разрядный тип данных, и l обозначает 32-разрядный тип данных. Если первый и – или второй параметр - 3-байтовый указатель, это будут пропускать в R16-R19 или R20-R22 соответственно.
Распределение регистров, использующее новое соглашение о вызовах
В новом соглашении о вызовах, максимальное число параметров передаются в регистрах. Остальные параметры передаются в стеке. Компилятор может изменять порядок параметров, чтобы достичь наиболее эффективного использования регистров.
Алгоритм для назначения параметров для регистраторов - довольно сложен в новом соглашении о вызовах.
Ниже следует несколько примеров комбинаций назначения регистра. Функция с описанием (не C++):
void foo(char __far * a, int b, char c, int d)
Будет распределено как: a – в R18:R17:R16, b – в R21:R20 (требование выравнивания предотвращает R20:R19), с – в R19 (метод первого подходящего), и d – в R23:R22 (метод первого подходящего).
Другойпример:
void bar(char a, int b, long c, char d)
Это привело бы к распределению: a – в R16 (метод первого подходящего), b – в R19:R18 (выравнивание), C – в R23:R22:R21:R20 (метод первого подходящего), и d – в R17 (метод первого подходящего).
И третийпример:
voidbaz(char a, char __far * b, int c, int d)
Это дало бы следующее распределение параметров: а – в R16, b – в R22:R21:R20, с – в R19:R18, и d – в стеке.
Параметры Стека
Имеется только ограниченное число регистров, которые могут использоваться для передачи параметров. Когда нет больше доступных регистров, параметры передаются в стеке.
Кроме того, параметры передаются в стеке в следующих случаях:
Структурные типы: struct, union, и class если больше чем 4 байта
тип данных double (64-разрядные числа с плавающей запятой)
неименованные параметры для функций переменной длины, т.е. функции объявленные как foo (param1, ...), например printf(…).
Размещение Стека
Вызов Функции создает порядок расположения стека следующим образом:
-
П араметры Стека
Любые параметры, которые не вошли в регистры.
Сохраняемые регистры
R4-R15, R24-R27
Авто переменные
Область для локальных переменных.
Временная память
Любые временные значения.
Скрытые параметры
В дополнение к параметрам, видимым в функциональном объявлении и определении, также могут быть скрытые параметры:
функция, возвращающая структуры или объединения больше чем четыре байта скрывает дополнительный параметр, который является заданным по умолчанию, в зависимости от используемой модели памяти, указывающий на местоположение, где результат должен быть сохранен. Этотуказательдолженбытьвозвращенвызываемойфункцииассемблера.
Для не static функций члена C++, этот указатель передается как первый параметр (но помещенный после возвращения указателя на структуру, если он один). Обратите внимание, что статические функции члена не имеют указателя this.