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

 
 
> AVR STACK
demiurg_spb
сообщение Aug 6 2008, 10:55
Сообщение #1


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Написал макросы для работы со стеком...
Но я не являюсь спецом по ASM в AVRGCC.
Прошу великих Гуру окинуть сие творчество на передмет косяков...
И вообще, можно-ли в GCC использовать стек в таком ключе или есть нюансы?
Код
// ============================================================================
#define __avr_stack_pop()                 \
(__extension__({                          \
    uint8_t __result;                     \
    __asm__ __volatile__                  \
    (                                     \
        "pop %0"            "\n\t"        \
        : "=r" (__result)                 \
        :                                 \
    );                                    \
    __result;                             \
}))

// ============================================================================
#define __avr_stack_push(value)           \
(__extension__({                          \
    uint8_t __value = (uint8_t)value;     \
    __asm__ __volatile__                  \
    (                                     \
        "push %0"            "\n\t"       \
        :                                 \
        : "r" (__value)                   \
    );                                    \
}))

Тест:
Код
#define stack_push  __avr_stack_push
#define stack_pop   __avr_stack_pop
    unsigned char i = 0;
    do
    {
        stack_push(i);
        i = stack_pop();
    } while (++i<5);

Выход:
Код
    cabe:    80 e0           ldi    r24, 0x00; 0
    cac0:    8f 93           push    r24
    cac2:    8f 91           pop    r24
    cac4:    8f 5f           subi    r24, 0xFF; 255
    cac6:    85 30           cpi    r24, 0x05; 5
    cac8:    d8 f3           brcs    .-10     ; 0xcac0 <main+0x2>


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
KRS
сообщение Aug 6 2008, 11:53
Сообщение #2


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



а для чего вам это надо?
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Aug 6 2008, 12:02
Сообщение #3


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Парсить удобно...

Да ещё была одна задумка, но она похоже накрылсь...

Хотел сохранять номер пункта родительского меню для последующего восстановления при возврате -
но пока не работает - MCU ресетится...
Разбираюсь в чём дело.
Если push и pop в одной процедуре - всё ок....


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Aug 6 2008, 13:11
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(demiurg_spb @ Aug 6 2008, 15:02) *
Если push и pop в одной процедуре - всё ок....
Естественно. Потому что в другой процедуре на стек еще положен адрес возврата, локальные переменные, сохраненный SREG. Даже в одной процедуре в теле компилятор может положить на стек временную переменную и вся ваша стройная система рухнет. По макросу: поскольку push изменяет ОЗУ, совсем честно было бы указать memory в списке clobber


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Aug 6 2008, 15:39
Сообщение #5


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(Сергей Борщ @ Aug 6 2008, 17:11) *
Естественно. Потому что в другой процедуре на стек еще положен адрес возврата, локальные переменные, сохраненный SREG. Даже в одной процедуре в теле компилятор может положить на стек временную переменную и вся ваша стройная система рухнет.

С адресом возврата я согласен.
Из Вашей ремарки можно сделать не совсем правильный вывод о том, что компилятор использует лишь стек, а как же куча?
Когда она используется?
К слову, бывает, что компиляторы разделяют аппаратный стек и программный ибо он быстрее на некоторых системах...
Я думаю что и для AVR архитектуры это тоже м.б. разумно...

Цитата(Сергей Борщ @ Aug 6 2008, 17:11) *
По макросу: поскольку push изменяет ОЗУ, совсем честно было бы указать memory в списке clobber

Доработал. Спасибо за совет!
Код
// ============================================================================
#define __avr_stack_pop()                 \
(__extension__({                          \
    uint8_t __result;                     \
    __asm__ __volatile__                  \
    (                                     \
        "pop %0"            "\n\t"        \
        : "=r" (__result)                 \
        :                                 \
        : "memory"                        \
    );                                    \
    __result;                             \
}))

// ============================================================================
#define __avr_stack_push(value)           \
(__extension__({                          \
    uint8_t __value = (uint8_t)value;     \
    __asm__ __volatile__                  \
    (                                     \
        "push %0"            "\n\t"       \
        :                                 \
        : "r" (__value)                   \
        : "memory"                        \
    );                                    \
}))

Ещё раз убеждаюсь, что задавать правильные вопросы очень полезно для здоровьяsmile.gif


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Aug 6 2008, 16:32
Сообщение #6


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(demiurg_spb @ Aug 6 2008, 18:39) *
С адресом возврата я согласен.
Из Вашей ремарки можно сделать не совсем правильный вывод о том, что компилятор использует лишь стек, а как же куча? Когда она используется?
Компилятор "сам" использует кучу только в одном случае - в С++ при создании объектов через new. В С кучу использует программист, через вызов функций malloc/free.
Цитата(demiurg_spb @ Aug 6 2008, 18:39) *
К слову, бывает, что компиляторы разделяют аппаратный стек и программный ибо он быстрее на некоторых системах...
Я думаю что и для AVR архитектуры это тоже м.б. разумно...
Да, есть у такого подхода плюсы, есть минусы. В данном случае вы спрашивали по avr-gcc, а у него всего один стек.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 6 2008, 18:01
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Сергей Борщ @ Aug 6 2008, 18:32) *
Компилятор "сам" использует кучу только в одном случае - в С++....
В С кучу использует программист, через вызов функций malloc/free.

Не совсем так - компилятор-то "сам" не использует, но некоторые вполне сишные библиотечные функции heap вынуждены пользовать - на вскидку strdup(), time()...


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Aug 7 2008, 08:07
Сообщение #8


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(zltigo @ Aug 6 2008, 21:01) *
Не совсем так - компилятор-то "сам" не использует, но некоторые вполне сишные библиотечные функции heap вынуждены пользовать - на вскидку strdup(), time()...
Естественно, но это функции, в исходнике которых явно указаны malloc/free. При использовании new компилятор вставляет malloc/free "от себя". Хотя... new тоже пишет программист.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post



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

 


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


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