Передаваемые параметры функций




Общие сведения

 

Размеры и выравнивания базовых типов данных C++:

 

Имя типа Размер в словах процессора Количество значимых бит Выравнивание типа данных в памяти
char      
short      
int      
long      
void *      
float      
double      
long double      

 

Примечание: размер типа данных совпадает с выравниванием данного типа в памяти.

 

Архитектурные особенности:

Обращение в память для чтения 64-х битного длинного слова возможно только по четному адресу.

Важное следствие: вызов функции возможен, только когда регистр указатель стека имеет четное значение. Данное требование усугубляется, если в процессе выполнения программы могут происходить прерывания, поскольку в момент прихода прерывания указатель стек должен иметь чётное значение. Прерывание может прийти в любое момент, когда регистр PC (счётчик команд) чётный, отсюда правило – к началу выполнения любой команды, размещённой по чётному адресу указатель стека должен быть чётным.

Передаваемые параметры функций

Все параметры функции передаются через стек. Для базовых типов данных в стеке передается сам параметр. Для структурных типов данных (структуры, классы, объединения) в стеке передается указатель на структуру.

Компилятор может порождать дополнительные, неявные параметры для функций. Для функций, возвращающих структурный тип данных, добавляется параметр - указатель на область стека в которой располагается структура. Если у функции имеется такой параметр, то он предшествует всем остальным явным и неявным параметрам. Для функций членов класса компилятор порождает неявный параметр - указатель на объект класса (this). Такой параметр предшествует всем явным параметрам. Если у функции имеется два неявных параметра - указатель на возвращаемую структуру и указатель this, то первым параметром является указатель на возвращаемую структуру, вторым указатель this, затем идут явные параметры.

Параметры размещаются в стеке начиная с последнего, т.е. первый параметр имеет наибольший адрес, последний параметр имеет наименьший адрес.

Выравнивание параметров в памяти соответствует обычному выравниванию переменных такого типа. При этом в стеке могут образовываться неиспользуемые места. Такие неиспользуемые места имеют размер 1 слово и располагаются по четным адресам. Поскольку, при выполнении инструкции перехода к подпрограмме, указатель стека должен иметь четное значение, выравнивание параметров производится относительно места в стеке, где располагаются PC и PSW при переходе к подпрограмме.

 

Примеры:

1. Расположение в стеке параметров функции f(int a, long b, int c) на момент входа в функцию (адрес растет вверх):

 

 
Текущий указатель стека
PSW
PC
a
Неиспользуемое место
Старшая часть b
Младшая часть b
c

 

2. Расположение в стеке параметров функции g(int a, int b, long c, int d) на момент входа в функцию (адрес растет вверх):

 

 
Текущий указатель стека
PSW
PC
a
b
Старшая часть c
Младшая часть c
d

 

Замечание: Следует обратить внимание, что параметры размером в 1 слово всегда выравниваются на больший адрес и соответственно пустые места всегда занимают часть длинного слова с меньшим адресом. Такое выравнивание гарантирует, что расположение параметра в стеке не зависит от последующих параметров. Это особенно важно для функций с переменным числом параметров, когда функция обращаясь к своему параметру не знает о типе и вообще о существовании следующего параметра.

 

Алгоритм 1. Вычисление расположения параметров функции в стеке и занимаемого ими размера:

1. Установить переменную РАЗМЕР в 0. Эта переменная содержит размер, занимаемый параметрами в стеке.

2. Взять очередной параметр из списка параметров в направлении от первого параметра к последнему. Если список параметров полностью просмотрен, то закончить работу.

3. Если параметр имеет размер 2 слова (long, то принять в качестве смещения параметра РАЗМЕР + 2; РАЗМЕР += 2. Перейти к шагу 2.

4. В данном случае параметр имеет размер 1 слово (int). Принять в качестве смещения параметра РАЗМЕР + 1; РАЗМЕР += 1. После этого взять следующий параметр из списка. Если список полностью просмотрен, то закончить работу.

5. Если следующий параметр имеет размер 1 (ситуация int,int), то в качестве смещения второго параметра взять РАЗМЕР + 1; РАЗМЕР += 1. Перейти к шагу 2.

6. В данном случае мы имеем первый параметр размера 1 слово и второй параметр размером 2 слова (ситуация int, long). Добавляется одно слово выравнивания по смещению РАЗМЕР + 1. В качестве смещения второго параметра взять РАЗМЕР + 3; РАЗМЕР += 3. Перейти к шагу 2.

 

В результате работы данного алгоритма вычисляется смещение каждого параметра относительно места в стеке, где при вызове функции располагается PC, и общий размер места в стеке занимаемого параметрами.

 

Например, для функции f из примера 1 параметр a имеет смещение 1, слова заполнения между параметрами a и b имеет смещение 2, параметр b - смещение 4, параметр c - смещение 5. Параметры занимают 5 слов в стеке (адрес растет вверх):

 

  Смещение
Текущий указатель стека  
PSW  
PC  
a  
Неиспользуемое место  
Старшая часть b  
Младшая часть b  
c  

 

 

Алгоритм 2. Заполнение стека параметрами при вызове функции:

1. Составляем полный список параметров функции, включая неявно добавленные компилятором

2. Вычисляем размер, занимаемый параметрами функции в стеке, и смещения параметров. Вычисление производится с помощью алгоритма 1.

3. Если размер, занимаемый параметрами в стеке, нечетный, то выравниваем вершину стека на нечетный адрес. Если размер, занимаемый параметрами в стеке, четный, то выравниваем вершину стека на четный адрес.

4. Заносим параметры в стек, добавляя в нужных местах слова заполнения.

5. Производим вызов функции. Шаг 3 гарантирует нам, что вершина стека перед вызовом функции будет иметь четной адрес.

 

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2022-09-12 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: