首页 > 解决方案 > 从拇指内联汇编分支到交流符号

问题描述

我在 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?

标签: gccinline-assemblycortex-mthumb

解决方案


所以事实证明,我使用的工具链(gcc 4.8)有问题,并且犯了两个错误:它将 code_buf 解释为一个 arm 地址,并产生了一个blx label在 cortex-m0+ 上甚至不合法的伪造。我将其更新为 6.3.1,并且内联 asm 已bl label按预期转换为 a。


推荐阅读