【发布时间】:2013-03-25 10:13:53
【问题描述】:
ARM Cortex-M3 的 IAR 编译器提供内联汇编。如何将特定函数的地址存储到堆栈上的某个位置?
C 代码会这样
void tick();
void bar()
{
int x;
// modify a value on stack
(&x)[4] = &tick;
}
虽然这通常有效,但编译器在发布版本中对其进行了优化。我尝试使用内联汇编对其进行编码
void bar()
{
int x;
asm("ldr r0,%0" : : "i" (&tick));
asm("str r0,[sp+#0x10];
}
IAR 编译器不接受ldr 指令。问题是这条指令需要一个带有寄存器和偏移量的寻址模式。函数tick 的实际地址存储在函数后面,ldr 指令仅保存到保存实际地址的内存位置的偏移量。反汇编类似这样:
ldr r0,??tick_address
str r0,[sp+#0x10]
bx lr ; return
??tick_address dd tick
如何立即将tick 的地址保存到寄存器中以用于堆栈操作?
【问题讨论】:
-
那是 GCC 内联汇编语法吗?我相信 IAR 允许在内联汇编中直接引用符号,而无需任何额外的繁文缛节。 IE。类似
asm("ldr,=tick"); -
它看起来类似于 GCC 语法。但正如我的编辑所示,LDR 需要一个非直接参数。
-
IAR 汇编器手册将
LDR Rd,=immed32列为受支持的伪指令。他们不支持内联汇编似乎很奇怪。 -
@Michael 看来是的。 “i”导致立即数-# 被添加到符号前面。但这需要将实际值放置在函数末尾的代码中,以便在 [PC+offset] 处访问它。在内联汇编中这可能有点复杂。
-
你想在这里实现什么 - 分配函数指针的任务可以在纯 C 中完成,根本不需要汇编。如果有的话,
asm("" : "=r"(foo) : "0"(tick))将“分配”它。请您提供更多背景信息吗?
标签: inline-assembly iar