Переменные в функцию - стек или ОЗУ?

Тема в разделе "Микроконтроллеры AVR", создана пользователем parovoZZ, 24 янв 2019.

  1. parovoZZ

    parovoZZ Гуру

    Указатели изучили. А теперь вопрос - а так ли они полезны?
    Не секрет, что адресация глобальных переменных прямая, а переменных в стеке - косвенная. Стек в AVR программный, то бишь откусывается от ОЗУ. Так вот вопрос - при передаче в функцию (и обратно) больших объемов данных (которые невозможно передать через РОН) что будет производительнее - через глобальные переменные или через параметры? Понятно, что в функцию вида
    Код (C++):
    uint8_tMy_super_function(uint8_t data);
    upload_2019-1-24_10-10-27.gif
    переменные уйдут через РОН, а вот в такую
    Код (C++):
    void My_super_function(uint8_t*data,uint8_t*ret);
    upload_2019-1-24_10-10-27.gif
    через стек? Так может ну его нафик, стек этот?
     
    Последнее редактирование: 24 янв 2019
  2. DetSimen

    DetSimen Гуру

    • Options for the C compiler avr-gcc) to make int 8 bits, but that is not supported by avr-libc and violates C standards (int must be at least 16 bits). It may be removed in a future release.


    • 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.


    • 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. r29:r28 (Y pointer) is used as a frame pointer (points to local data on stack) if necessary. The requirement for the callee to save/preserve the contents of these registers even applies in situations where the compiler assigns them for argument passing.


    • Fixed registers (r0, r1): Never allocated by gcc for local data, but often used for fixed purposes:


    r0 - temporary register, can be clobbered by any C code (except interrupt handlers which save it), may be used to remember something for a while within one piece of assembler code

    r1 - assumed to be always zero in any C code, may be used to remember something for a while within one piece of assembler code, but must then be cleared after use (clr r1). This includes any use of the [f]mul[s] instructions, which return their result in r1:r0. Interrupt handlers save and clear r1 on entry, and restore r1 on exit (in case it was non-zero).

    • Function call conventions: Arguments - allocated left to right, r25 to r8. All arguments are aligned to start in even-numbered registers (odd-sized arguments, including char, have one free register above them). This allows making better use of the movw instruction on the enhanced core.


    If too many, those that don't fit are passed on the stack.

    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. 8-bit return values are zero/sign-extended to 16 bits by the called function (unsigned char is more efficient than signed char - just clr r25). Arguments to functions with variable argument lists (printf etc.) are all passed on stack, and char is extended to int.
     
  3. DetSimen

    DetSimen Гуру

    Нет. Через стек параметры будут пхаца, только если в R8-R25 не влазют. Вообще, да, стековая адресация дольше непосредственной, но это не повод делать все переменные глобальными.

    Тем более, непосредственной адресации в AVR памойму нет. Это когда загрузить регистр по явно заданному адресу, все равно сначала адрес загружается в X/Y/Z а потом оттуда (косвенно) в регистр. Так какая разность тогда, указывает ли индексный регистр на переменные или на стек?

    Могу ошибаца.
     
  4. parovoZZ

    parovoZZ Гуру

    А если надо перепихнуть пару-тройку 64 бит переменных, или 128 бит? Неужели они все в РОН залягут? Тем паче, я же указатель передаю на них? Или AVR-GCC пофигу?
     
  5. DetSimen

    DetSimen Гуру

    ктонить знает, есть ли у AVR аналоги Z80
    LD A, (NN)
    LD HL, (NN)
    и т.д?
    Памойму нет. Можно только загружать непосрецтвенно X,Y или Z и адресоваться потом ими
     
  6. DetSimen

    DetSimen Гуру

    те, что влезут в R8-R25 передадуца в регистрах, остальные - через стек. А ты, тем более, передаешь указатели - это 2 регистра всего (на Меге - 3 или 4, не помню). Точно знаю, что тип __uint24 и __int24 у AVR есть
     
  7. parovoZZ

    parovoZZ Гуру

    могу сказать точно - аккумулятора в AVR нет. Инфа 146%
     
  8. parovoZZ

    parovoZZ Гуру

    то бишь на этом моменте вообще можно не запариваца - сами переменные в стек не уходят?
     
  9. DetSimen

    DetSimen Гуру

    нет. только адреса уходят
     
  10. DetSimen

    DetSimen Гуру

    это я и так знаю. я имел ввиду чонить типа LD Rn,(NN)
     
  11. parovoZZ

    parovoZZ Гуру

    Я правильно резюмирую, что если параметров не много (укладываются в РОНы) и/или мы параметры передаем по указателю, то и запариваца нинада))?
     
  12. DetSimen

    DetSimen Гуру

    Да
    если ты передаешь, допустим long

    void f(long value);

    то в регистры кладется 4 байта, а если

    void f(long *value)

    то 2.

    Но. В первом случае, как ни меняй value внутри функции, на внешней переменной, которую ты передал, это никак не отразица, а во втором - отразится. поэтому, добрые люди придумали модификаторы const

    void f(const long *value) - нельзя *value присвоить новое значение
     
    Последнее редактирование: 24 янв 2019
  13. DetSimen

    DetSimen Гуру

    Но, на всякий случай, надо у взрослых спросить.
     
    Последнее редактирование: 24 янв 2019
  14. parovoZZ

    parovoZZ Гуру

    ну есть что-та.
    Screenshot_2019-01-24 ATtiny24A 44A 84A - doc8183 pdf.png
    А что там да как я не в курсе. АСМ для меня не больше, чем крякозябры
     
    DetSimen нравится это.
  15. parovoZZ

    parovoZZ Гуру

    внутри функции? Это хорошо =)
    А вот жешЪ команда LDS. Что такое (к) - вообще не отгружаю.
     
  16. DetSimen

    DetSimen Гуру

    да, спасибо, я почитаю щас
     
  17. parovoZZ

    parovoZZ Гуру

    А структура в параметрах по указателю передается?
     
  18. DetSimen

    DetSimen Гуру

    Неть
     
    Последнее редактирование: 25 янв 2019
  19. DetSimen

    DetSimen Гуру

    структура относится к типам-значениям, как int, float, char и т.д, и, если размер позволяет (влазит вся в r8-R25), компилятор передаёт ее в регистрах, как остальные типы-значения. Если размер больше - структура кладется (копируется) в стек. Именно поэтому, передав структуру в функцию, как её поля унутре не меняй, на первоначальной (переданной) структуре это никак не отразится. Хочешь изменить переданную структуру - передавай указатель на неё, а лучше - ссылку. Ссылка гарантирует, что в функцию придёт именно адрес структуры, а не NULL.
    Если я неправ, уважаемый AsperDaffy меня поправит.
     
    parovoZZ нравится это.
  20. DetSimen

    DetSimen Гуру

    кстати, классы памойму, тоже в С++ - типы значения, значить вышеизложенное на их тоже распространяется.
    именно поэтому так любимый новичками String лучше передавать в функцию по ссылке, иначе на стеке создается его копия.