|
Соглашения по регистрам, Cortex M3, gcc 4.7.2 |
|
|
|
Feb 12 2013, 18:55
|

Профессионал
    
Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634

|
Вижу, что в документе Cortex-M3 programming manual написано - при входе в прерывание сохраняется Цитата ● R0-R3, R12 ● Return address ● PSR ● LR Добавление __attribute__((__interrupt__)) (как я смог понять из кода) добавляет выравнивание стека на 8. В этом нет необходимости - обработка прерывания процессором это обеспечивает независимо от требования на выравнивание. А что обеспечивает сохранение остальных регистров? Или эти регистры в gcc 4.7.2 в случае их использования в вычислениях сохраняются автоматически? Сейчас при невнимательном тестировании на первый взгляд всё работает и без __attribute__((__interrupt__)). В документе http://gcc.gnu.org/onlinedocs/gcc-4.7.2/gc...tion-Attributes написано только то, что я и понял - на Cortex Mx только выравнивает стэк: Цитата On ARMv7-M the interrupt type is ignored, and the attribute means the function may be called with a word aligned stack pointer. В start-up никаких изменений режима работы процессора не делается. CODE static void ResetException( void ) {
uint32_t * pSrc, * pDest ;
/* Low level Initialize */ arm_cpu_initialize(); // watchdog disable, clock initialize
/* Initialize the relocate segment */ pSrc = & _sidata; pDest = & __data_start;
if ( pSrc != pDest ) { // compiled for FLASH for ( ; pDest < & __data_end ; ) { *pDest++ = *pSrc++ ; } } // Следить, чтобы переменные не оказались в стеке, очищаемом сейчас. // Для этого, например, использована секция noinit /* Clear the zero segment */ for ( pDest = & __bss_start; pDest < & __bss_end; ) { * pDest ++ = 0; }
/* Branch to main function */ main();
/* Infinite loop */ for (;;) ; }
Сообщение отредактировал Genadi Zawidowski - Feb 12 2013, 19:18
|
|
|
|
|
Feb 12 2013, 19:29
|

embarrassed systems engineer
    
Группа: Свой
Сообщений: 1 083
Регистрация: 24-10-05
Из: Осокорки
Пользователь №: 10 038

|
Цитата(Genadi Zawidowski @ Feb 12 2013, 21:19)  Не все регистры сохраняются. А с остальными (R4..R11) как быть - как обеспечить их сохранение? В gcc. Их сохранение должна обеспечить сама вызываемая процедура. То есть - если процедуре надо использовать какой-либо из регистров R4-R11, то она его сама предварительно сохраняет, пользует и потом восстанавливает. Регистры R0-R3 процедура может использовать на свое усмотрение, их сохранять от процедуры не требуется. Итого - произошло прерывание/исключение - флаги, R0-R3 и прочие сохранились, а остальные регистры R4-R11 вызванная процедура сама не разрушит. Кстати, это не только к GCC относится, но и ко всем компиляторам, которые следуют APCS - "Procedure Call Standard for the ARM® Architecture" - документ есть на сайте ARM.
|
|
|
|
|
Feb 12 2013, 19:33
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(Genadi Zawidowski @ Feb 12 2013, 21:19)  Не все регистры сохраняются. Конечно не все... Цитата(Genadi Zawidowski @ Feb 12 2013, 21:19)  А с остальными (R4..R11) как быть - как обеспечить их сохранение? Вас Си интересует? Никак не обепечивать. Компилятор знает что делает...
|
|
|
|
|
Feb 13 2013, 05:38
|

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

|
Цитата(Genadi Zawidowski @ Feb 12 2013, 23:36)  значит функции обработчиков перерывания вообще ни в каких особых атрибутах в Cortex не нуждаются... Абсолютно верное заключение. Но для того чтобы отличить обычную функцию от обработчика я всё равно предваряю её ключевым для кейла словом __irq. Лишнего самодокументирования не бывает ИМХО. Код void __irq EXTI9_5_IRQHandler(void) { EXTI->PR = (1<<9); //сбросили флаг прерывания
// do something else }
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Feb 13 2013, 06:57
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
У меня Код #ifdef __cplusplus # define INTERRUPT extern "C" #else # define INTERRUPT #endif
// ...
INTERRUPT void UART3_IRQHandler() { // ... } Цитата(Genadi Zawidowski @ Feb 12 2013, 21:36)  Хотелось прочитать это где-то в документации на компилятор. Например в главе calling conventions или ещё где-то в подобном месте. Для gcc 4.7.2 не нашёл. Уже ж сказано, что это стандартизовано ARM-ом и ссылка на документ дана: Цитата(VslavX @ Feb 12 2013, 21:29)  Кстати, это не только к GCC относится, но и ко всем компиляторам, которые следуют APCS - "Procedure Call Standard for the ARM® Architecture" - документ есть на сайте ARM.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Feb 13 2013, 18:49
|

Профессионал
    
Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634

|
Пока мне APCS встретилось только в таком контексте: Цитата -mapcs-frame Generate a stack frame that is compliant with the ARM Procedure Call Standard for all functions, even if this is not strictly necessary for correct execution of the code. Specifying -fomit-frame-pointer with this option causes the stack frames not to be generated for leaf functions. The default is -mno-apcs-frame. Вот помню в Borland-овской документации было написано, в каких регистрах что возвращается (тогда ещё не умели передавать в регистрах), для каких типов что. Просто меня спрашивают: вот ты сделал такой обработчик - а где гарантия, что регистры не используются? И я кроме честного слова за free software пока ничего не могу ответить...
|
|
|
|
|
Feb 14 2013, 09:31
|

Профессионал
    
Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634

|
Цитата GCC следует стандартным соглашениям для архитектуры ARM Просто, где это сказано? Где написано, что эти соглашения действуют для gcc с ключами "по умолчанию". Поиск чертырех букв APCS - абревиатуры названия на сайте gnu ничего не даёт (только как часть имени ключа). Я так понимаю, KEIL следует стандарту своей же фирмы. Но кто декларировал совместимость keil и gcc? Как я знаю, это разные продукты... Цитата Как же, а в ассемблерный листинг посмотреть? Там все регистры видны Ассемблерный листинг зависит от кода... от сложности выражений. Простые функции ничего не используют, только LR.
Сообщение отредактировал Genadi Zawidowski - Feb 14 2013, 09:37
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|