【问题标题】:Cortex-m4 asm vs cortex-m0 asmCortex-m4 asm 与 cortex-m0 asm
【发布时间】: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 &amp; (1&lt;&lt;2)。你的替换应该检查同一个寄存器中的相同位,不是吗?
  • @PeterCordes 哎呀。对不起,我的错。原始代码测试LR。现在我也看到 lsr 的移位错误。谢谢!
  • 看一下arm文档,cortex-m0是armv6m,cortex-m4是armv7m。 armv7m 在 armv6m 上添加了大约 150 条新指令。根据您获得的文档,armv7m 文档将根据指令显示支持的架构(所有拇指变体或 armv6m、arvm7m 或仅 armv7m 等)。您正在使用这些文件吗?

标签: assembly arm cortex-m


【解决方案1】:

Cortex-M0 显然根本不支持预测;没有条件执行。显而易见的选择是分支。

您的 lsrs 序列看起来没有正确实现测试正确位或测试 单个 位。看起来它取决于所有高位为零。

GCC 输出https://godbolt.org/z/aphU5G 展示了一种使用移位指令在单个位上进行分支的巧妙方法:lsls r3, r0, #29bpl .skip - 将该位移动到符号位,其中仅基于该位设置标志。 r3 目标可以是任何可编码的虚拟寄存器;你不在乎价值;你只需要标志设置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-19
    • 2020-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-07
    相关资源
    最近更新 更多