У меня есть много примеров на основе thumb и cortex-m http://github.com/dwelch67
Как указал Иоахим, вы пропускаете первую запись в таблице векторов, указатель стека.cortex-m не имеет той же таблицы векторов, что и рука, то есть таблица, которая загружается в режиме arm с инструкциями arm.
Чтобы завершить ответ, для cortex-m вы можете настроить стек следующим образом:поместив начальное значение для указателя стека в это первое местоположение слова
.cpu cortex-m3
.thumb
.word 0x10008000 /* stack top address */
.word _start /* 1 Reset */
.word hang /* 2 NMI */
.word hang /* 3 HardFault */
.word hang /* 4 MemManage */
, вы, безусловно, сможете запустить указатель стека вручную, как если бы вы были в режиме охраны или в большинстве других процессоров.
Я бы сделал так, чтобы ваш код попадал в бесконечный цикл, так что, как написано, вы не попадаете в неопределенные инструкции и т. Д. (Должно быть 0xFFs, которые на cortex-m0, я думаю, не определены, на-m3 или -m4 с поддержкой armv7 thumb2, это может быть реальной инструкцией).
Обратите внимание, что я не использовал +1 на своих векторах.Вы должны знать свои инструменты.Вам нужен этот lsbit для указания адреса большого пальца / режима большого пальца в ветви.Хотя я усвоил урок по этому (придется найти такой вопрос)
Рука / Большой палец: использование BX в коде Thumb, для вызова функции Thumb или для перехода к инструкции Thumb в другомfunction
Если ассемблер gnu поместит директиву .thumb_func перед меткой, эта метка помечается как метка большого пальца, и инструменты gnu будут использовать адрес | 1.
.thumb_func
.globl _start
_start:
Вам нужно время от времени собирать и разбирать, чтобы убедиться, что ваша таблица строится правильно, а ветви и тому подобное используют правильный адрес.
0: 10008000 andne r8, r0, r0
4: 0000005b andeq r0, r0, fp, asr r0
8: 00000050 andeq r0, r0, r0, asr r0
c: 00000050 andeq r0, r0, r0, asr r0
10: 00000050 andeq r0, r0, r0, asr r0
видите, по-видимому, у меня ошибкав одном из моих примеров ... он никогда не делает ничего, кроме сброса (в этом примере не использовались прерывания, так что мне так и не удалось узнать).забыл .thumb_func
hang: b .
произведено
00000050 <hang>:
50: e7fe b.n 50 <hang>
изменить на
.thumb_func
hang: b .
и таблица векторов перейдет к
00000000 <hang-0x50>:
0: 10008000 andne r8, r0, r0
4: 0000005b andeq r0, r0, fp, asr r0
8: 00000051 andeq r0, r0, r1, asr r0
c: 00000051 andeq r0, r0, r1, asr r0
10: 00000051 andeq r0, r0, r1, asr r0
14: 00000051 andeq r0, r0, r1, asr r0
thisинтересно, измените код на
.cpu cortex-m3
.thumb
.word 0x10008000 /* stack top address */
.word _start+1 /* 1 Reset */
.word hang+1 /* 2 NMI */
.word hang+1 /* 3 HardFault */
.word hang /* 4 MemManage */
.word hang /* 5 BusFault */
, и он на самом деле не делает плюс один, а вместо него или один.
00000000 <hang-0x50>:
0: 10008000 andne r8, r0, r0
4: 0000005b andeq r0, r0, fp, asr r0
8: 00000051 andeq r0, r0, r1, asr r0
c: 00000051 andeq r0, r0, r1, asr r0
10: 00000051 andeq r0, r0, r1, asr r0
Это немного беспокоит.Суть в том, что две вещи: с помощью cortex-m вы можете установить указатель стека в таблице векторов, во-вторых, при запуске нового проекта разберите и изучите таблицу векторов, чтобы убедиться, что это то, что вы ожидаете.Esp, если он не делает то, что, как ты думаешь, должен.