реклама на сайте
подробности

 
 
> Организация стека в компиляторе WinAVR
Giekelberri
сообщение Jan 28 2011, 13:41
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 18
Регистрация: 28-01-11
Пользователь №: 62 532



Добрый день всем!

Дано:
Компилятор WinAVR-20090313 в связке со средой разработки AVRStudio 4.
МК - ATMega1280, но это не важно.

Пусть есть программа на ЯВУ Си:

int SumEvaluate(int a, int b, int c)
{
int sum = 0;
sum = a + b + c;
return sum;

}
void main(void)
{
int i;
char ch1;
char ch2;
i = evaluate(5,4,10);
printf("%d",i);

}

Известно, что стек начинается с конца SRAM и растет в сторону уменьшения адреса.
Возникает вопрос где сохраняются переменные i, ch1, ch2? В соответствии с документацией на WinAVR, они могут сохраниться в двух местах:
Call-used registers (r18-r27)
или
Call-saved ergisters (r2-r17)

Если бы переменных было много (ch3, ch4, ch5, ch6, ...), места в регистрах РОН не хватило бы и тогда был бы задействован стек. В этом случае на вершину стека указывал бы указатель стека, хранящийся в Z-регистре или Y-регистре соответственно. А каким образом в этом случае известна глубина стека?

Повторю вопрос: а где на самом деле сохраняются эти переменные в Call-used registers или Call-saved ergisters? И как становиться известна глубина стека когда для размещения переменных не хватает регистров общего назначения ?

И второй вопрос, аналогичен первому - что происходит при вызове функции? Счетчик PC помещается в стек, это понятно. а куда помещаются локальные переменные для данной функции? Сначала в регистры общего назначения или сразу в стек? Куда помещается значение, возвращаемое функцией?
Какое максимальное количество параметров, которое возможно передать функции? Непанятна sm.gif

Сообщение отредактировал Giekelberri - Jan 28 2011, 13:43
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Giekelberri
сообщение Jan 31 2011, 14:29
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 18
Регистрация: 28-01-11
Пользователь №: 62 532



Всем спасибо за ответы! Частично разобрался с организацией стека. Для этого воспользовался советами посмотреть откомпилированный код без оптимизации.

Код
int evaluate(int a, int b, int c)
{
    int sum = 0;
    sum = a + b + c;
    return sum;
}
int main(void)
{
    int i;
    char ch1;
    char ch2;
    i = evaluate(5,4,10);
    return 0;
}


Даже без оптимизации компилятор выкинул ch1 и ch2.
Параметры функции сначала сохранил в РОН. Войдя в функцию evaluate() выделил для них место в стеке и сохранил их в стеке.
Далее вычисление суммы. Тут заметна избыточность кода. Так как переменных всего три можно было их вычислить и без использования стека.
Результат, как вы правильно сказали, и в соответствии с документацией, был помещен в r24:r25

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

А количество параметров, передаваемых функции, как я понял ограничивается только размером стека, т. е. стремиться к Internal SRAM.
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 18:06
Рейтинг@Mail.ru


Страница сгенерированна за 0.01382 секунд с 7
ELECTRONIX ©2004-2016