【发布时间】:2021-10-07 13:00:03
【问题描述】:
对于 ARM cortex M 使用 gcc/clang,有没有办法在带有 C 表达式操作数的汇编指令中将函数地址作为常量传递?更准确地说,我想用函数地址(存储在内存中)加载 R12:
ldr R12, =func
在 C 函数中,像这样的例子
// __attribute__((naked))
int loader(int fn)
{
__asm ("ldr R12, =%0"::??? (fn):"r12");
// ... then SVC #0, and the R0 is the return value
}
问题是我必须为输入操作数输入什么?
编辑:
感谢cmets!
实际上,我需要重新实现 KEIL 的 __svc_indirect(0),它使用函数地址加载 R12 并在 R0..R3 中传递最多四个参数(参见 __svc_indirect
【问题讨论】:
-
有什么原因你不首先要求寄存器中的函数地址吗?就像
(void*)fn将您的int转换为一个指针,或者只是要求寄存器中的int,例如"r"(fn)。您可以使用register int fn asm("r12")使“r”约束选择 r12。你希望你的代码如何编译?就像您希望将其内联到某个调用者中一样,int fn可以是编译器可以通过符号名称嵌入到指令中的链接时常量?但是裸函数不能内联。 -
请注意,
naked函数不能安全地使用 Extended Asm,只能使用 Basic(无约束/操作数)。他们需要手动返回(例如以bx lr结尾)gcc.gnu.org/onlinedocs/gcc/… -
非恶意函数返回
int值,应该将一些东西放入r0寄存器... -
@peter-cordes,我需要重新实现 KEIL 的 __svc_indirect(0) 函数地址加载 R12 并在 R0..R3 中传递最多四个参数
-
好的,那么您应该使用
"r"约束让GCC 为您执行ldr(使用register ... asm("r12")变量)。并且不要创建naked函数;这基本上相当于使用单独的.s文件,除了名称修改。
标签: c assembly arm inline-assembly cortex-m