в современных и вменяемых средах разработки всё задаётся явно прямо в исходниках и сразу видно где например лежит стек и как он подключается при запуске через таблицу прерываний.
вот например смотри мою минимальную прога на нормальном Си в нормальной среде разработке, которая уделала все извращения на асме что были в статье.
https://habrahabr.ru/post/274901/#comment_8738493
расшифровываю
__attribute__ ((section(".co_stack"))) - это атрибут заставляет положить массив для стека в секцию с именем .co_stack, а далее в LD файле (задаёт порядок компановки секций в прошивке и управляет адресами что куда ложить) указывается что эта секция должна идти после секции данных
__attribute__ ((section(".min_isr_vector"))) - таким же образом даёт имя min_isr_vector, а в ld файле указывается что эта секция первая в прошивке и всегда идёт с адреса 0х08000000.
стеку не нужна уменьшать на Х значение, если память заканчивается на 2020000, то в SP можно запихать 2020000. Потому что при команде push В НАЧАЛЕ уменьшается значение SP а потом уже кладётся по этому уменьшенному значению сохраняемые данные.
Да и SP указывает на память и обязано быть кратным 4 (машинному слову, 20000FFF недопустимо!)
Извините но Иар и Кейл не очень среды (но компиляторы в них хорошые, да), и поэтому надо пользоваться вменяемыми и не устаревшими в 90ых годах инструментариями. Тогда и вопросов не возникнет. вот в эклипсе с плагином CDT для си и с++ во всех примерах сразу сделано нормально выделение стека. А в последних вообще идеально. В Attolic и всяких RED от NXP так же хорошо всё сделали нарпимер, так что выбор среды по душе не проблема, надо только захотеть ;)