gcc - 从拇指内联汇编分支到交流符号
问题描述
我在 Cortex-M0+ 设备(仅限 Thumb)上,我试图在 ram 中动态生成一些代码,然后跳转到它,如下所示:
uint16_t code_buf[18];
...
void jump() {
register volatile uint32_t* PASET asm("r0") = &(PA->OUTSET.reg);
register volatile uint32_t* PACLR asm("r1") = &(PA->OUTCLR.reg);
register uint32_t set asm("r2") = startset;
register uint32_t cl0 asm("r3") = clears[0];
register uint32_t cl1 asm("r4") = clears[1];
register uint32_t cl2 asm("r5") = clears[2];
register uint32_t cl3 asm("r6") = clears[3];
register uint32_t dl0 asm("r8") = delays[0];
register uint32_t dl1 asm("r9") = delays[1];
register uint32_t dl2 asm("r10") = delays[2];
register uint32_t dl3 asm("r11") = delays[3];
asm volatile (
"bl code_buf\n"
: [set]"+r" (set) : [PASET]"r" (PASET), [PACLR]"r" (PACLR), [cl0]"r" (cl0), [cl1]"r" (cl1), [cl2]"r" (cl2), [cl3]"r" (cl3), [dl0]"r" (dl0), [dl1]"r" (dl1), [dl2]"r" (dl2), [dl3]"r" (dl3) : "lr"
);
}
code_buf 中的代码将使用通过寄存器传递的参数(这就是我强制使用特定寄存器的原因)。这段代码编译得很好,但是当我查看反汇编时,分支指令已更改为
a14: f004 ebb0 blx 0x5178
这会尝试将 cpu 切换到 ARM 模式并导致 HardFault。有没有办法强制汇编器将分支保持为简单的 bl?
解决方案
所以事实证明,我使用的工具链(gcc 4.8)有问题,并且犯了两个错误:它将 code_buf 解释为一个 arm 地址,并产生了一个blx label
在 cortex-m0+ 上甚至不合法的伪造。我将其更新为 6.3.1,并且内联 asm 已bl label
按预期转换为 a。
推荐阅读
- java - 导入时无法解析符号 TreeMap
- java - 反转数组的方法导致 StackOverflowError
- stripe-payments - Stripe:在期末取消订阅之前发送电子邮件/通知
- database - Oracle 10g 数据库恢复
- java - JPA/Hibernate 只加入一个选定的列
- php - How to insert data from html table to database using laravel
- jmespath - JMESPath - 无法查询另一个列表中的列表中的值
- visual-studio-2019 - 运行“Devenv.exe /setup”命令后 Devenv.exe 崩溃
- flutter - Dart 简单的字符串编码器/解码器
- nuget - Myget 服务器将 Nuget 包许可证显示为 UnKnown