【问题标题】:How to pass function address to Assembler Instructions with C Expression Operands如何使用 C 表达式操作数将函数地址传递给汇编程序指令
【发布时间】: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


【解决方案1】:

使用i 约束并手动添加= 字符:

__asm ("ldr r12, =%0" :: "i"(fn) : "r12");

请注意,由于其他原因,内联汇编语句仍然不正确,其中一些原因已在您的问题的 cmets 中进行了概述。还可以考虑对这类事情使用寄存器约束变量:

register int fn asm("r12");
__asm ("" :: "r"(fn));

【讨论】:

    猜你喜欢
    • 2020-01-09
    • 1970-01-01
    • 2011-07-08
    • 1970-01-01
    • 2011-04-17
    • 2019-07-26
    • 1970-01-01
    • 2011-08-06
    • 1970-01-01
    相关资源
    最近更新 更多