Цитата
Возникает вопрос где сохраняются переменные i, ch1, ch2
i - резервируется место в стеке
ch1, ch2 - скорее всего выкинутся компилятором после оптимизации т.к. не используются
Цитата
Куда помещается значение, возвращаемое функцией?
Return values: 8-bit in r24 (not r25!), 16-bit in r25:r24, up to 32 bits in r22-r25, up to 64 bits in r18-r25.
Перевода надеюсь не надо.
Цитата
Call-used registers (r18-r27)
Call-used registers (r18-r27, r30-r31):
May be allocated by gcc for local data. You may use them freely in assembler subroutines. Calling C subroutines can clobber any of them - the caller is responsible for saving and restoring.
Могут быть распределены gcc для локальных переменных. Вы МОЖЕТЕ их использовать в ассемблерных подпрограммах. Вызываемая Си-подпрограмма МОЖЕТ ЗАТЕРЕТЬ любое содержимое - вызывающая программа ответственна за сохранение и воссстановление.
Цитата
Call-saved registers (r2-r17)
Call-saved registers (r2-r17, r28-r29):
May be allocated by gcc for local data. Calling C subroutines leaves them unchanged. Assembler subroutines are responsible for saving and restoring these registers, if changed.
Могут быть распределены gcc для локальных переменных. Вызываемая Си-подпрограмма ДОЛЖНА их вернуть НЕИЗМЕНЕННЫМИ. Ассемблерная подпрограмма ответственна за сохранение и восстановление, если их изменяет.
Цитата
Повторю вопрос: а где на самом деле сохраняются эти переменные в Call-used registers или Call-saved ergisters?
И те и другие сохраняются в стеке, только Call-used registers сохраняте вызывающая подпрограмма, а Call-saved ergisters ДОЛЖНА сохранять вызываемая подпрограмма (если, тем более, она написана на асме)
Если хотите узнать как компилятор СИ (WinAVR) работает со стеком, то посмотрите оттранслированный листинг любой функции. В кратце при вызове функции это происходит так:
1. Вызывающая функция сохраняет в стеке (если надо) Call-used registers, и параметры некоторых функций (например printf)
2. Процессор аппаратно (в команде CALL или FCALL) сохраняет в стеке адресс возврата
3. Вызываемая программа сохраняет в стеке используемые Call-saved registers, в том числе и указатель стека (r28-r29)=(Y).
4. Вызываемая программа играется со стеком как душе угодно, в том числе размещает там свои локальные переменные.
5. Вызываемая программа восстанавливает Call-saved registers из стека
6. Процеесор аппаратно (в команде RET или FRET), воостанавливает PC из стека
7. Вызывающая функция восстанавливает из стека Сall-used registers, и также очищает стек от параметров некоторых функций (например printf)
Если Вы пишите на Си, то замарачиваться по этому поводу не надо. Если только на Асме, то также замарачиваться не надо. И если только миксуете код - то надо знать правила вызовов Си-функций