STM32 Передача управления между программами. Пишем загрузчик.

Sdílet
Vložit
  • čas přidán 20. 01. 2019
  • В ролике рассказывается о том, как передать управление из одной программы в другую. Размещение двух программ во FLASH памяти.
    STM32 Хранение данных и конфигурации во FLASH памяти - • STM32 Хранение данных ...
    STM32 UART с библиотекой HAL - • STM32 UART с библиотек...
    STM32 Шифрование данных. Библиотека Cryptolib от ST - • Video
    ------------------------------------------
    Поддержать автора канала можно перейдя по ссылке:
    yoomoney.ru/to/4100116547550395
    Или просто отправив перевод на Yandex.кошелек:
    4100116547550395
    А также переводом по номеру карты Сбер:
    4279-3000-1033-0561
    ------------------------------------------
  • Věda a technologie

Komentáře • 96

  • @serjkp
    @serjkp Před 5 lety +1

    С удовольствием посмотрел урок. Спасибо, очень понятно и доступно объясняете.

  • @DjMelMelovski
    @DjMelMelovski Před 4 lety +3

    Огромное спасибо! Всё просто и понятно объяснили! Попробовал - получилось!

  • @alexst2975
    @alexst2975 Před 4 lety +1

    Большое спасибо! Без вас никогда бы не разобрался!

  • @sailtogether3236
    @sailtogether3236 Před 2 lety +1

    О, благодаря вашему видео удалось собрать два ардуиновских скетча, в которых первый стартует второй (и даже второй потом снова стартует первый). Огромное спасибо! Теперь можно наконец прямо в ардуине написать загрузчик, накатывающий обновления с флешки.

  • @bobahkz
    @bobahkz Před 5 lety +1

    Большое спасибо! Всё по полочками и с объяснениями!!! Лайк!

  • @danilgaijin8366
    @danilgaijin8366 Před 5 lety +2

    Огромное спасибо за видео. Очень познавательно!

  • @SiemensSxg75Patch
    @SiemensSxg75Patch Před 5 lety

    Как раз недавно читал про создание загрузчиков. Хорошее видео!

  • @user-ee8tg1wg5y
    @user-ee8tg1wg5y Před 3 lety +1

    Спасибо! Все коротко и ясно.

  • @ArthurIslamRU
    @ArthurIslamRU Před 5 lety

    Спасибо большое. Ждём новых видео

  • @user-je8oz6lh6w
    @user-je8oz6lh6w Před 3 lety

    Еще раз - СПАСИБО ОГРОМНОЕ. И донатики.

  • @azbukaChisel
    @azbukaChisel Před 5 lety +1

    Спасибо за урок!

  • @akovalev341
    @akovalev341 Před 3 lety

    прикольный гайд. Буду пробовать.

  • @kardanium
    @kardanium Před 4 lety +1

    Я так запустил программу в RAM. Запускаемую программу собрал в адресном пространстве RAM и бинарник её сунул запускающей программе. При старте я скопировал массив в нужный адрес RAM, загрузил из ее таблицы адрес ResetHandler и назначил его указателю на void функцию. Потом переназначил таблицу векторов, адрес указателя стека и дёрнул функцию передачи управления (ту самую void функцию). В новом стеке остаётся адрес возврата, который можно использовать, если нужно вернуться в загрузчик. Для этого нужно просто выйти из main функции.

  • @user-bl6pe7by7i
    @user-bl6pe7by7i Před 3 lety +1

    Дякую за пояснення,)Промучивши пів дня L552, невийшло завести перехід до основної програми( Завтра вже з більш менш розуміням це робитиму.

  • @expertkis
    @expertkis Před 3 lety +1

    Здравствуйте! По времени 10.50в видео Вы ставите настройку отчищать только сектор, а не весь чип, не подскажите где аналогичные настройки в CubeIDE, если таковые есть

  • @Maxnicknameable
    @Maxnicknameable Před 3 lety +1

    По смещению таблицы векторов: у меня заработало только когда изменил VECT_TAB_OFFSET, пока пытался изменить VTOR в main - не работало.

  • @user-ob1pr1tt6l
    @user-ob1pr1tt6l Před 3 lety

    Очень годный контент!
    Так держать!
    Есть вопрос :
    16:34 как Вы настроили, чтобы не активная ветка условной компиляции выделялась серым цветом? Какие только настройки я не пробовал.....
    Если что, я использую Keil uVision 5.23

  • @ArthurIslamRU
    @ArthurIslamRU Před 5 lety

    Добрый день(вечер). Расскажите, почему вы убираете полностью медь с плат, оставляя только дорожки?

    • @VladimirMedintsev
      @VladimirMedintsev  Před 5 lety

      Плата показанная на видео - 4х слойная. Так что два слоя не видно, на самом деле там не все так однозначно. На плате стоит радиомодуль GSM и сверху видно антенну.
      А так спасибо огромное за идею я как-нить сделаю видео по печатным платам и его сразу же утопят в потоке дизлайков. Просто единого мнения нету. Но идея огромное спасибо еще раз.

  • @omaral-wadi8746
    @omaral-wadi8746 Před 4 lety

    Было очень полезно, спасибо!
    Но можете объяснить пожалуйста почему мы смешаем таблицу векторов прерывания?

    • @VladimirMedintsev
      @VladimirMedintsev  Před 4 lety +2

      Вы создаете программу, кроме всего прочего она может содержать обработчики прерываний которые сама же эта программа и использует. Это ее часть.
      Логично, что размещая в памяти вторую программу у нее будут свои обработчики прерываний. А как нам об этом сказать процессору? У него есть регистр.

  • @rodionoff
    @rodionoff Před 3 lety

    Здравствуйте! Спасибо за видео, за это и всё видео что Вы сделали. Повторил данный пример на F030. В нём нет регистра VTOR! и NVIC_SetVectorTable как в F100 тоже нет. Управление передается, но вероятно таблица векторов не подменяется. И еще проблема с переопределением тактовой частоты в главной программе. В загрузчике HSI включен, в главной программе тактирование от HSE включаю (с PLL) но частота все равно 8Mhz. Не сталкивались ли с подобными проблемами?

    • @VladimirMedintsev
      @VladimirMedintsev  Před 3 lety

      Загрузчик на f030 куда интересно у вас там программа помещается. Ну а по сути я в видео показываю общий подход. Для каждого конкретного контроллера reference manual позволит разобраться в деталях. Надо поднимать документацию на ядро и смотреть где он хранит информацию о векторе прерывания. А по тактирования тот же подход надо смотреть условия переключения.

    • @rodionoff
      @rodionoff Před 3 lety +2

      @@VladimirMedintsev F030C8T6 - 64k, место есть, опять же сделал с прицелом на будущие проекты. Для себя сделал вывод, что если предполагается обновлять прошивку бутлоадером, чип лучше сразу с запасом по памяти выбирать. По документации понятно - использование HALовских DeInit не избавляет от ньюансов каждого конкретного чипа.
      Вобщем так подмена таблицы прерываний для F0:
      __disable_irq();
      volatile uint32_t *VectorTable = (volatile uint32_t *)0x20000000; // адрес SRAM на который будет подменена область памяти 0x0000 0000
      volatile uint32_t *SourseTable = (volatile uint32_t *)APPLICATION_ADDRESS;
      //адрес начала главной программы 0x0800 4000
      for(uint32_t VectorIndex = 0; VectorIndex < 44; VectorIndex++)
      //Количество векторов - считал вручную по ASM файлу
      {
      VectorTable[VectorIndex] = SourseTable[VectorIndex];
      // переносим копию таблицы с 0x08004000 на 0x20000000
      };
      SYSCFG->CFGR1 &= ~(SYSCFG_CFGR1_MEM_MODE);
      // Очистка битов регистра ремапа
      SYSCFG->CFGR1 |= (SYSCFG_CFGR1_MEM_MODE_0 | SYSCFG_CFGR1_MEM_MODE_1); //установка ремапа адресов
      теперь процессор обращаясь к содержимому по адресу 0x0000 0000 попадет на данные из адреса 0x2000 0000 куда скопирована таблица из 0x0800 4000.
      если нужно прыгнуть в бут, нужно очистить биты SYSCFG->CFGR1 - ремап вернется на 0x0800 0000

  • @user-to2tb6pi2g
    @user-to2tb6pi2g Před 4 lety

    Спасибо Вам за уроки они мне помогали ещё с AVRok. Недавно стала передо мной задача написать загрузчик для оборудования. И все бы хорошо, да вот Corex M0 используемый на применяемом контроллере STM32F072R не поддерживает перенос векторов прирываний:(. В даташите вычитал что его можно скопировать в оперативку и от туда использовать. Но как это на деле выглядит не знаю. В интернете примеров не нашел. Подскажите пожалуйста.

    • @VladimirMedintsev
      @VladimirMedintsev  Před 4 lety

      Честно говоря я не видел такого в даташите на F0, не дадите номер страницы? Прям вот в рам можно, а во флэш нельзя? Хотя с другой стороны а что мешает то же самое провернусь с оперативной памятью?

    • @user-to2tb6pi2g
      @user-to2tb6pi2g Před 4 lety

      @@VladimirMedintsev Даташит RM0091 страница 53, раздел Physical remap.

    • @VladimirMedintsev
      @VladimirMedintsev  Před 4 lety +1

      @@user-to2tb6pi2g Да, спасибо, прочитал и удивился. С другой стороны они же и пишут вариант обхода этой особенности контроллера. Более того, они ссылаются на AN4065 а в нем (в его архиве) и есть пример который показывает как обходить эти ограничения. Думаю что разобраться там совсем не проблема.

  • @user-kv2wj6dl7f
    @user-kv2wj6dl7f Před 5 lety

    Добрый день. Не подскажете, каким плагином Вы раскрашивали содержимое hex-файла в notepad++?

    • @VladimirMedintsev
      @VladimirMedintsev  Před 5 lety

      Все по умолчанию. Ничего не устанавливал.

    • @user-kv2wj6dl7f
      @user-kv2wj6dl7f Před 5 lety

      Странною У меня последняя версия notepad++, но ничего не подсвечивается :-(

    • @user-kv2wj6dl7f
      @user-kv2wj6dl7f Před 5 lety +1

      Всё. Нашел. Спасибо.

  • @azzzza9957
    @azzzza9957 Před 5 lety +1

    Поправте меня если я ошибаюсь. Как я понял, если использовать такой метод то в памяти микроконтролерра одновременно будут существовать две таблицы прерываний: первая создается от «бутлоадера», а вторая от «прошивки»?

    • @VladimirMedintsev
      @VladimirMedintsev  Před 5 lety

      Абсолютно верно, но в регистре процессора хранится адрес начала только той таблицы, которая соответствует выполняемой программе.

  • @MrYuriGu
    @MrYuriGu Před 3 lety

    Cпасибо, Владимир! Приходилось ли Вам писать загрузчик для программы расположенной во внешней QSPI Nor Flash, другими словами, реализовать XiP?

    • @VladimirMedintsev
      @VladimirMedintsev  Před 3 lety

      Нет, не приходилось.

    • @CanchezAK
      @CanchezAK Před 3 lety

      Если я правильно понимаю, то достаточно установить соединение с памятью и дальше исполнять программу, залитую согласно указанным в видео правилам, только что её придётся сначала прочитать, потом записать в память контроллера, а потом уже исполнить, либо отслеживать исполнение каждой отдельной команды и читать память дальше до тех пор, пока данные в памяти не закончатся, но я вообще не уверен, что это возможно. Хотя, наверное, я просто плохой программист:)

  • @ivanivan3815
    @ivanivan3815 Před 5 lety

    Спасибо за добротный материал. А не подскажете, есть-ли возможность создания scatter файла линкера для одновременной заливки основной программы и дампа бутлоадера по нужным адресам?

    • @VladimirMedintsev
      @VladimirMedintsev  Před 5 lety

      Есть много способов одновременно залить и собственный бутлоадер и основную программу. Как правило линковать их вместе для этих целей нет никакого смысла. Наоборот правильнее заливать их последовательно. В этом случае меньше шанс утечки дешифрующей части бутлоадера в чужие руки. Хотя, конечно, это зависит от вашего подхода.

    • @ivanivan3815
      @ivanivan3815 Před 5 lety

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

    • @VladimirMedintsev
      @VladimirMedintsev  Před 5 lety

      Взять два или более готовых .hex файлов. Командой copy file1.hex + file2.hex + file3.hex скопировать в один файл, его и заливать в процессор любым доступным вам методом.

    • @VladimirMedintsev
      @VladimirMedintsev  Před 5 lety

      Ну а если вам так хочется использовать именно scatter файл, то читаем его формат и пишем как в инструкции. См ссылку. Но лично я такой вариант не использую. Т.к. если в каких программах и использую область данных во flash, то и загружает ее программа. Дерективы компилятора располагающие данные по конкретным адресам никто не отменял. www.keil.com/support/man/docs/ARMLINK/armlink_pge1362075656353.htm

    • @ivanivan3815
      @ivanivan3815 Před 5 lety

      Спасибо за разъяснения.

  • @tupoy_ytub_uberi_psevdonim

    Это все очень интересно, но теперь есть вопрос, а как устроен бутлодер с юсб (DFU режим) и с защитой от стирания? У меня в black pill можно программировать с помощью stlink не смещая ничего но бутлодер не стирается.

    • @VladimirMedintsev
      @VladimirMedintsev  Před rokem

      Он в системной части памяти. Вы не можете его стереть.

    • @tupoy_ytub_uberi_psevdonim
      @tupoy_ytub_uberi_psevdonim Před rokem

      @@VladimirMedintsev вот оно как, понял, спасибо. пошел изучать этот вопрос.

  • @aleksandrzakutnyy4450
    @aleksandrzakutnyy4450 Před 5 lety

    покажите пожалуйста пример на стм32 3-5 запущенных задач и передачу данных между ними. пусть даже это будет мигание светодиодами с разными периодами. может быть у стма есть для этого специальные аппаратные блоки или программные типовые шаблоны

    • @VladimirMedintsev
      @VladimirMedintsev  Před 5 lety

      Аппаратных блоков таких нет, а вот программные шаблоны есть. Называются они FreeRTOS. Очень удобная штука. С обменом данными между задачами, приоритетами, семафорами. Одно удовольствие с ней работать. Как-нибудь сделаю видео.

    • @aleksandrzakutnyy4450
      @aleksandrzakutnyy4450 Před 5 lety

      @@VladimirMedintsev , также интересно и без ОС. она съест половину выч мощности наверно. ОС наверно выгодно использовать при более 7- 10 задачах. а в простейших случаях хотелось бы без нее обойтись. например задача основная пид регулятор с периодом 5мкс , задача клавиатуры и задача вывода на дисплей. может у микроконтроллеров есть для этого соответствующее количество таймеров для прерываний.

    • @VladimirMedintsev
      @VladimirMedintsev  Před 5 lety

      @@aleksandrzakutnyy4450 Простите меня за грубость, но без операционной системы это просто извращение какое-то получится. Для вас видимо самое время прочитать про FreeRTOS. Она потребляет меньше того, что у вас на таймерах и прерываниях получится, а надежность в разы выше. Ну а про вычислительную мощность. Блин ее даже в самом дешевом процессоре столько, что не знаешь куда девать. А уж задача ПИД регулятора чего может быть проще.

  • @Mappex
    @Mappex Před 5 lety

    Добрый день! Можете подсказать, как лучше сделать оповещение об ошибке в программе, например, МК повис или произошла программная ошибка, и к примеру у нас есть красный светодиод и в случае ошибки его надо задействовать. Вопрос, как это лучше всего сделать?

    • @Sergey_Bobrov
      @Sergey_Bobrov Před 5 lety

      Если МК повис, то светодиод уже не сработает, в этом случае спасет watchdog timer.

    • @VladimirMedintsev
      @VladimirMedintsev  Před 5 lety

      @@Sergey_Bobrov Если повис, то сделать ничего нельзя. Но, в случаях возникновения ошибок все вполне реализуемо. Кроме того, после срабатывания сторожевого таймера тоже можно сказать что было не так. Ну в смысле сделать индикацию и разбор подвисания.

  • @talipovp500
    @talipovp500 Před 5 lety

    Добрый день . А со стороны компьютера какой софт можно использовать для обновления прошивки?

    • @VladimirMedintsev
      @VladimirMedintsev  Před 5 lety

      Тут вариантов много. Если созданное вами устройство имеет на борту USB, то вы можете эмулировать Mass Storage Device и принять прошивку как файл. Если хотите можете отправить прошивку по UART ну в принципе по абсолютно любому удобному для вас интерфейсу. Следовательно если это USB то со стороны компьютера вам ничего не нужно в принципе, если это UART то любой терминал. Логика я думаю понятна.
      Ну или вообще обновляйтесь через сеть. В данном случае я всего лишь показал как передавать управление.

    • @talipovp500
      @talipovp500 Před 5 lety

      Если это будет происходить через терминал ? как можно защититься от того что контроллер не будет успевать принимать новые данные а данные будут продолжать лететь. Mass Storage Device пока не вникал но виртуальный ком порт думаю подниму (я на SPL) Думаю пользователю будет удобнее пользоваться только USB шнурком . а не USB-TTL переходником.

    • @talipovp500
      @talipovp500 Před 5 lety

      неужели проще перейти на HAL ?

    • @VladimirMedintsev
      @VladimirMedintsev  Před 5 lety

      У всего есть свое назначение и цель. На SPL удобно писать части программы наиболее критичные по времени и занимаемому обьему. На HAL писать гораздо быстрее и проще. Сейчас ведь у всех какая цель - продукт должен максимально быстро оказаться на рынке, а доделывать потом в следующей ревизии. Маркетинг мать его...

    • @VladimirMedintsev
      @VladimirMedintsev  Před 5 lety

      Все зависит от создаваемого вами устройства. А что касается успевать-не успевать так для этого есть контроль CTS-RTS и все такое...

  • @Sergey_Bobrov
    @Sergey_Bobrov Před 5 lety +3

    Хорошо бы примеры на github выкладывать.

    • @VladimirMedintsev
      @VladimirMedintsev  Před 5 lety +3

      Нет, выкладывать я ничего и никуда не буду.
      Я показываю что и как можно делать, а делать каждый должен сам.

    • @Sergey_Bobrov
      @Sergey_Bobrov Před 5 lety +1

      @@VladimirMedintsev Очень странный у вас подход. Если человек просмотрел и осознал ваше видео, то он обязательно сам должен ручками набить текст проекта, вместо того чтобы взять готовые примеры и доработать под себя? Вообще считается хорошим тоном выкладывать исходники о которых идет речь в видео.
      Ну и похоже вы сами взяли за основу видео и исходники от avislab www.avislab.com/blog/stm32-bootloader_ru/ . Ничего не имею против этого, дополнительные объяснения никогда не помешают, хотя возможно стоило упомянуть автора.

    • @VladimirMedintsev
      @VladimirMedintsev  Před 5 lety

      @@Sergey_Bobrov Скажите, а вы по поводу основы, такое заключение сделали только по той причине, что увидели в тексте appJumpAddress? Если так, то немного вас расстрою. На хабре - habr.com/ru/post/309218/ переменная так же называется. Такая же стилистика в имени переменной используется на сайтах cyberforum.ru, itnan.ru, radiokot.ru, it-ua.info, rssing.com, telegrammy.net ну и еще пару сотен адресов могу привести. И вот на микротехнике JumpAddress, что тоже очень похоже. А если серьезно, то идею для этого кода и идею имени переменной я взял на сайте www.keil.com. Так какого автора по вашему мне стоило упоминать? Ну между прочим avislab я до этого не видел. Надо будет поглядеть.

    • @Sergey_Bobrov
      @Sergey_Bobrov Před 5 lety

      @@VladimirMedintsev Понятное дело, что того автора, у которого взяли идею. Хотя в любом случае это ваше дело. А вот про выкладывание исходников все-таки предлагаю подумать.

    • @BalabayUA
      @BalabayUA Před 5 lety +2

      Ну какие тут исходники, десяток строчек кода и подправленный адрес памяти в настройках? Автор объяснил теорию, для меня это важней. Адрес перехода, стек и таблица векторов. Просто.

  • @qoblanqoblan9379
    @qoblanqoblan9379 Před rokem

    в последные видео нету да
    не показывает

  • @XpIOHdeJIb3000
    @XpIOHdeJIb3000 Před rokem +1

    Хотел чуть поправить в комментарии, но тут столько ошибок, что их разбор займёт больше времени, чем длится видео.

    • @VladimirMedintsev
      @VladimirMedintsev  Před rokem +1

      О, круто, чтобы вас сильно не утомлять разбором всех ошибок, давайте пару слов, самую грубую из всех 100500 допущенных назовите, пожалуйста.

    • @XpIOHdeJIb3000
      @XpIOHdeJIb3000 Před rokem

      @@VladimirMedintsev у вас hal вызывает system init до main, где переназначает vtor. Делая одно и то же в разных местах, вы просто подкладываете бомбу программисту, которому достанется в наследство ваш код.

    • @VladimirMedintsev
      @VladimirMedintsev  Před rokem +1

      Понятно....

    • @XpIOHdeJIb3000
      @XpIOHdeJIb3000 Před rokem +2

      @@VladimirMedintsev кто-то не знает как хал работает, это понятно. Кстати, у вас nvic остался не сброшенный.

  • @ibrag2012
    @ibrag2012 Před 4 lety

    А мені подобається нога BOOT0: можна додати ще один процесор та прошивати перший другим (чи другий першим). Зручно якщо воно десь на Марсі :)

    • @VladimirMedintsev
      @VladimirMedintsev  Před 4 lety +1

      А можно сделать так чтобы процессор прошивал себя самостоятельно, а в случае проблемы восстанавливал предыдущую версию прошивки. Сложного в этом ничего нету. И boot0 в этом случае не понадобится. В случае с Марсом выглядит все немного по другому. Там несколько процессоров в виде одинаковых блоков действуют параллельно, и сбойный модуль просто исключается из процесса принятия решения. Т.е. его можно исключать из кластера. Да, это требует определенного подхода к проектированию системы в целом, но в медицине, авиации и космосе это применяется. К примеру в инсулиновых помпах стоит 2 процессора.

    • @sailtogether3236
      @sailtogether3236 Před 2 lety

      Прошивка одним МК из другого особенно актуальная сейчас, в месяцы дефицита и всеобщего подорожания МК.

  • @harrys_potter
    @harrys_potter Před 2 měsíci

    Здраствуйте,делаю все тоже самое через cmsis, почему то не выполняется программа

    • @VladimirMedintsev
      @VladimirMedintsev  Před 2 měsíci

      Если мы говорим о передаче управления, то она и написана на CMSIS, и как видно из видео - работает.

    • @harrys_potter
      @harrys_potter Před 2 měsíci

      @@VladimirMedintsevвы то hal пользуетесь,а я нет,пока не выходит(

    • @VladimirMedintsev
      @VladimirMedintsev  Před 2 měsíci

      @harrys_potter для перехода я хал не использовал. Он там как вспомогательное.

    • @harrys_potter
      @harrys_potter Před měsícem

      ⁠@@VladimirMedintsevнекорректно обьясняете,в переменной appjumpaddress будет не то что вы там написали 0x0800C000,а именно адресс Reset H тоесть адресс перехода но основную программу,а по 0x0800C000 хранится адресс указателя стека,тоесть его вершина которая записывается в регистр SP

    • @harrys_potter
      @harrys_potter Před měsícem

      я не пойму но по вашему методу у меня попадает в hard fault и висит на нем

  • @MAGAVHEBRON
    @MAGAVHEBRON Před 2 měsíci

    День добрый. Почему видос про шифрование не доступен?

  • @OpenFrimeTVcom
    @OpenFrimeTVcom Před rokem +1

    Если не ошибаюсь то адрес стека не нужно переставлять. он там при старте программы сам устанавливает куда нужно.

  • @aidagamemnon
    @aidagamemnon Před rokem

    Было бы полезно указать способ указать свойство NO RETURN на функцию перехода из бутлоадера в прошивку (чтобы пре переходе стек не заполнялся сразу адресом возврата).
    И в дополнение, при использовании библиотеки HAL адрес смещения вектора прерываний указывается в файле system_stm32xxxxx.c (/*!< Uncomment the following line if you need to relocate your vector Table in
    Internal SRAM. */
    /* #define VECT_TAB_SRAM */
    //#define VECT_TAB_OFFSET 0x0 /*!< Vector Table base offset field.
    //This value must be a multiple of 0x200. */)

    • @VladimirMedintsev
      @VladimirMedintsev  Před rokem

      А чем это было бы полезно? Ну пусть будет в стеке. Как только произойдет запуск основной программы у нее свой стек, своя жизнь.

    • @aidagamemnon
      @aidagamemnon Před rokem

      @@VladimirMedintsev Неверно. Вы сначала устанавливаете новый стек, а потом делаете переход, а значит новый стек уже будет использован для хранения адреса возврата.

  • @user-dy7dd3by6t
    @user-dy7dd3by6t Před rokem

    холопам привет