Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Возврат на основную программу из ассемблерной подпрограммы, вызванной еще одной асемблерной подпрограммой.
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
Omnicake
Здравствуйте, подскажите, какой команду в THUMB инструкции ассемблера использовать, чтобы вернутся из подпрограммы на asm в main.c если сама подпрограмма была вызвана из другой? То есть путь примерно такой: main.c -> подпрограмма1.s -> подпрограмма.2.s . Нужно из подпрограммы2 прыгнуть в main.c. Ранее использовал bx lr, но тут вложение глубже. Заранее спасибо.
demiurg_spb
Цитата(Omnicake @ Apr 18 2014, 11:05) *
Здравствуйте, подскажите, какой команду в THUMB инструкции ассемблера использовать, чтобы вернутся из подпрограммы на asm в main.c если сама подпрограмма была вызвана из другой?
Той же самой: BX LR
Definitive Guide to the ARM Cortex-M3, Second Edition
Глава 4.3.4 (даже выделено рамкойsm.gif )
И вообще вся глава 4 будет вам полезна.
Omnicake
Случай в рамке описывает сценарий, когда main тоже на ассемблере и можно использовать PUSH LR, а как мне поступить если main является c-файлом?
SSerge
Цитата(Omnicake @ Apr 18 2014, 14:05) *
То есть путь примерно такой: main.c -> подпрограмма1.s -> подпрограмма.2.s . Нужно из подпрограммы2 прыгнуть в main.c.

А зачем? Вам же самому потом по этим граблям ходить!

Другое дело, когда в подпрограмма1 есть вызов подпрограмма2 и сразу же после него возврат.
В этом случае можно немного поэкономить, заменив две команды в самом конце подпрограмма1
BL sub2 ;вызов подпрограммы2
BX LR ;возврат из подпрограммы1 в main
тут я немного погорячился, см. ниже
на одну команду
B sub2 ;переход на подпрограмму2 с последующим возвратом из неё сразу в main
Omnicake
Немного запутался...получается если у меня будет прописано B sub2, произойдет прыжок на подпрограммы2, в которой я в конце пишу BX LR, обеспечивающая возврат на подпрограмму 1 на строчку после B sub2 (END например) и после выполнения END он выйдет на main?
SSerge
При вызове sub1 из main адрес возврата сохраняется в регистре LR.
Соответственно, для возврата нужно содержимое LR записать в PC (счётчик команд), команда BX LR именно это и делает.

Но если мы хотим из sub1 вызвать sub2, то так просто это уже не сделать, нужно куда-то сохранить текущее содержимое LR, оно нам ещё потребуется, ведь в нём лежит адрес возврата (в main).
Поэтому в sub1 придётся написать
PUSH {LR} ;
......
BL sub2
POP {PC}
И вот это всё можно заменить на простой переход к sub2.
В LR тогда останется адрес возврата в main, куда и произойдёт возврат из sub2 после исполнения в ней команды BX LR
Omnicake
Все, понял. Пробежался по ссылке выше (спасибо большое, кстати) и дошло. Команда B - не изменяет состояние регистра LR, поэтому при переходе от sub1 к sub2 он не изменится и можно будет через BX LR во второй программе на него вернуться. Спасибо за помощь.
ViKo
На C пишите, а в ассемблерный листинг глядите! Иначе - капец!
toweroff
Цитата(Omnicake @ Apr 18 2014, 13:19) *
Все, понял. Пробежался по ссылке выше (спасибо большое, кстати) и дошло. Команда B - не изменяет состояние регистра LR, поэтому при переходе от sub1 к sub2 он не изменится и можно будет через BX LR во второй программе на него вернуться. Спасибо за помощь.

скажите, а в чем сакральный смысл такого подхода?
SSerge
Цитата(toweroff @ Apr 18 2014, 17:50) *
скажите, а в чем сакральный смысл такого подхода?

Это оптимизация путём отрубания хвостов, или, выражаясь высоким штилем, устранение хвостовой рекурсии.
toweroff
Цитата(SSerge @ Apr 18 2014, 15:45) *
Это оптимизация путём отрубания хвостов, или, выражаясь высоким штилем, устранение хвостовой рекурсии.

но так вроде же оптимизатор сам должен это делать?

UPD
Сейчас специально проверил пример из ссылки. Вызов из main() одной функции, в ней переход B в рекурсивную, там вычисления все в простом цикле, после чего возврат из первой стандартно BX LR с сохранением результата в R0
Keil 5.10, armcc 5.04.0.49
kolobok0
Цитата(toweroff @ Apr 18 2014, 16:05) *
....Сейчас специально проверил пример из ссылки.....



тсссссс. спугнёте велостроителей...
а так всё красиво начиналось... sad.gif
andrewlekar
Честно не знал, что компиляторы си умеют TCO. Теперь не буду так рекурсии избегать, как обычно.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.