繁体   English   中英

IAR汇编程序BKPT立即作为输入操作数

[英]IAR assembler BKPT immediate as input operand

我正在为Cortex M4设备编写Flashloader,我想使用断点指令的立即值“返回”驱动PC应用程序的值。

虽然对立即数进行硬编码可以很好地工作:

__asm("bkpt 0x70");
__asm("bkpt %0" : : "i" (0x70));

我想“返回”运行时相关的东西

uint8_t status = Flash_EraseAll();
__asm("bkpt %0" : : "i" (status));

编译失败并显示

错误[Ta090]:立即操作数不是常数

我尝试将预处理器宏用于不同的串联设置,但无济于事。

有谁知道如何将运行时相关的状态标志作为立即输入到IAR中的__asm()块? 根据我在这里阅读的内容,这并非完全可能,但是可能有一种巧妙的方法。

PS:是的,作为一种解决方法,我可以使用switch语句,在其中列出所有可能的状态并对其进行硬编码,但这很丑陋而且很长。

我会将值压入堆栈,然后使用具有定义编号的bkpt指令,以便调试器可以在堆栈中查看此状态。

这样的东西(伪代码):

__asm("push %0" : : "i" (status));
__asm("bkpt %0" : : "i" (0x70));

当然,您不应该忘记随后清理堆栈。

由于bkpt仅使用立即bkpt进行编码,因此您显然不能在运行时更改它,因为必须修改代码。

基于@Devolus的想法,我得出以下结论

    uint32_t status = Flash_EraseAll();
    __asm volatile ("str %0, [sp, #-4]!\n\t"   // Push to stack
                    "bkpt 0x0\n\t"             // Halt CPU
                    "add sp, sp, #4\n\t"       // Restore SP
                    : : "r"(status));          // status as input to __asm()

汇编指令告诉编译器将状态变量放入方便的寄存器“ r”,并将该寄存器的内容存储在堆栈指针的递减地址下,然后以立即数0暂停CPU的执行。

如果目标被停止(击中目标),则驾驶应用程序将轮询目标。 如果暂停,则通过读取当前PC下的16位数据(__asm(“ bkpt 0x00”)-> 0xbe00-> #imm = 0xbe00&0x00ff = 0),应用程序可以确保执行在右侧停止地点。 然后它将读取最终SP地址下的32位数据,以获取嵌入式代码执行的状态。

这样,人们可以动态地将更多的东西“报告”给外界(而不是bkpt的静态8位代码)(在这种情况下为32位)。

正如@PeterCordes强调的那样,push和bkpt语句必须在同一行内联汇编指令中,否则编译器可能决定在这些语句之间插入代码。 另外,由于编译器仅对SP进行控制,因此必须将SP恢复为__asm()之前的值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM