|
AVR STACK |
|
|
|
Aug 6 2008, 10:55
|

неотягощённый злом
     
Группа: Свой
Сообщений: 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>
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
 |
Ответов
|
Aug 6 2008, 15:39
|

неотягощённый злом
     
Группа: Свой
Сообщений: 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" \ ); \ })) Ещё раз убеждаюсь, что задавать правильные вопросы очень полезно для здоровья
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Aug 6 2008, 16:32
|

Гуру
     
Группа: Модераторы
Сообщений: 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)
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|