我正在使用适用于 ARM 6.50.4 功能安全版本 6.50 的 IAR Embedded Workbench 我似乎无法让汇编内联指令工作。
背景: 我正在尝试使用 PIT 中断在 ARM7TDMI 上实现上下文切换。 保存当前上下文时,我必须获取中断函数的堆栈地址,该地址保存在全局 C 变量中,该变量在同一个 c 文件中声明:
unsigned int* ptTask_CurrentTask;
__irq void SysIrqHandler( void )
{
// ... saving registers
__asm volatile( "LDR R0, %0\n\t" ::"r"(ptTask_CurrentTask) );
//... save the new top of stack
//select new task and restore associated registers
}
根据我从 EWARM_DevelopmentGuide.ENU.pdf 收集到的信息,上面的指令应该使用正确的语法。 我还尝试了不同的格式化指令的方法,但我得到的是:
错误[og006]:内联汇编中的语法错误:“错误[401]:操作数语法错误”
。
现在,当我将完整的上下文保存汇编例程导出到单独的 .s 文件并从 c 调用该函数时,以下指令工作正常。
LDR R0,=ptTask_CurrentTask
由于汇编指令本身有效,所以我执行内联汇编指令的方式肯定有问题,但我看不出有什么问题。
最佳答案
“r”约束表示通用寄存器,因此它最终会发出 LDR R0, Rx
这确实是无效语法。如果您确实想在汇编代码中执行实际的指针取消引用,请直接嵌入正确的语法:
__asm volatile( "LDR R0, [%0]\n\t" ::"r"(ptTask_CurrentTask));
或者,更好的是,使用适当的约束来指示它是内存操作数(指针)并将语法留给编译器:
__asm volatile( "LDR R0, %0\n\t" ::"m"(ptTask_CurrentTask));
或者浪费额外的指令并让编译器担心负载:
__asm volatile( "MOV R0, %0\n\t" ::"r"(*ptTask_CurrentTask));
无论哪种方式,直接接触 r0
而不在破坏列表中声明它可能是一个坏主意......
关于c - 使用全局 C 变量的 IAR 内联汇编,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28761599/