【发布时间】:2020-03-22 23:13:27
【问题描述】:
如何将 CM4 的汇编代码重写为 CM0?这是来自 FreeRTOS 页面的硬故障处理示例。它检查在发生硬故障之前哪个堆栈指针处于活动状态,并提供指向堆栈寄存器开头的指针:
" tst lr, #4 \n"
" ite eq \n"
" mrseq r0, msp \n"
" mrsne r0, psp \n"
" ldr r1, [r0, #24] \n"
" ldr r2, handler2_address_const \n"
" bx r2 \n"
" handler2_address_const: .word prvGetRegistersFromStack \n"
如果没有任何更改,它会产生多个错误:
Error: unshifted register required -- tst r0,#4''
Error: selected processor does not support 'ite eq' in Thumb mode
Error: Thumb does not support conditional execution
Error: Thumb does not support conditional execution
Error: invalid offset, target not word aligned (0x00000002)
Error: invalid offset, value too big (0x00000002)
我尝试过的:
以这种方式替换tst并删除IT
" mov r1, lr\n"
" lsr r0, r1, #3\n" // Replace tst with lsr and cmp
" cmp r0, #1\n"
" mrseq r0, msp\n" // <- Error: Thumb does not support conditional execution
" mrsne r0, psp\n" // <- Error: Thumb does not support conditional execution
好的。启用统一语法:
".syntax unified\n"
".thumb\n"
" mov r1, lr\n"
" lsrs r0, r1, #3\n" // tst gives "Can not honor suffix width" so replaced it with lsrs and cmp
" cmp r0, #1\n"
" ite eq\n" // <- Error: selected processor does not support `ite eq' in Thumb mode. If I remove it compiler states that mrseq must be in IT block
" mrseq r0, msp\n"
" mrsne r0, psp\n"
" ldr r1, [r0, #24]\n"
" ldr r2, handler2_address_const\n"
" bx r2\n"
" handler2_address_const: .word prvGetRegistersFromStack\n"
这些错误的原因是什么以及如何解决这些错误?仍然不知道是什么导致了对齐问题。
CM0 肯定不支持某些指令。但我不明白错误“Thumb 不支持条件执行”以及如何在没有条件执行的情况下生活。
此外,错误“不能接受寄存器宽度”是什么意思,以及在启用统一语法时为什么会发生这种情况。据我了解,这与 16/32 位指令有关。尝试添加 .W 后缀,但出现另一个错误。
【问题讨论】:
-
如果你不能断言指令,显而易见的选择是分支。您的
lsrs序列看起来不像它正确地实现了测试r0中的单个位。事实上,它甚至不再有r0作为输入。 -
@PeterCordes 为什么 lsrs 应该将 r0 作为输入? lr 移入 r1,r1 移位,结果存入 r0,与 1 进行比较。出了什么问题?
-
您原来的
tst r0, #4检查r0 & (1<<2)。你的替换应该检查同一个寄存器中的相同位,不是吗? -
@PeterCordes 哎呀。对不起,我的错。原始代码测试LR。现在我也看到 lsr 的移位错误。谢谢!
-
看一下arm文档,cortex-m0是armv6m,cortex-m4是armv7m。 armv7m 在 armv6m 上添加了大约 150 条新指令。根据您获得的文档,armv7m 文档将根据指令显示支持的架构(所有拇指变体或 armv6m、arvm7m 或仅 armv7m 等)。您正在使用这些文件吗?