c - GCC 内联汇编常量 (ARM)

标签 c gcc inline-assembly

有没有一种好方法可以将常量作为“参数”提供给内联汇编代码? 我正在尝试制作协处理器访问功能。 我尝试了两种方法:宏替换和扩展。

使用方法是这样的:

unsigned int read_ID_PFR1()
{
    READ_CP15(0, 0, 1, 1);
    return cp_reg_val;
}

宏观方法:

#define READ_CP15(opc, crn, crm, opc2) \
asm volatile (\
    "push {r0, r1}\n\t"\
    "mrc p15, opc, r0, crn, crm, opc2\n\t"\
    "ldr r1, =cp_reg_val\n\t"\
    "str r0, [r1]\n\t"\
    "pop {r0, r1}\n\t"\
    )

我认为参数(opc,crn,...)没有扩展,因为它们是 在引号内使用。

扩展方法如下所示:

#define WRITE_CP15(opc, crn, crm, opc2) \
    asm volatile (\
        "push {r0, r1}\n\t"\
        "ldr r1, =cp_reg_val\n\t"\
        "ldr r0, [r1]\n\t"\
        "mcr p15, %[op], r0, c%[rn], c%[rm], %[op2]\n\t"\
        "pop {r0, r1}\n\t"\
        ::[op]"I"(opc), [rn]"I"(crn), [rm]"I"(crm), [op2]"I"(opc2):\
    )

除了“#”标记之外,这似乎做得更好。 (c%[rn] 扩展为 c#0)

最佳答案

不要将push/pop放入内联asm中。这不仅意味着您在 asm 中编写了比应有的更多的垃圾;而且还意味着您在 asm 中编写了更多的垃圾。它还排除使用“m”类型输入/输出约束,因为有效地址可能是堆栈指针相关的。相反,使用类似的东西:

asm volatile ("mrc p15, opc, %0, crn, crm, opc2" : "=r"(cp_reg_val));

关于c - GCC 内联汇编常量 (ARM),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30608826/

相关文章:

c++ - 摆脱编译器警告 "warning: result of call is not used"

c++ - gcc 中非 MoveConstructible 函数对象的 std::function

gcc - printf 在使用较旧 gcc 的 x86-64 Linux 上陷入 AL = 10 的无限循环

gcc - 帮助构建 16 位操作系统

c - PIC/PIE 二进制文件中全局符号表 (GOT) 的地址

c - undefined variable 和编译器优化

C矩阵函数分割错误

从新的 mac 机器为旧 mac 创建应用程序?

c - ELF 如何填充它的 `short`?

c - 在 ubuntu 终端窗口中运行文件之前如何消除使用 "./"的需要?