gcc 在内联asm(linux内核)中阅读CPSR时出现“cc”乱码的原因

oxalkeyp  于 2022-11-12  发布在  Linux
关注(0)|答案(1)|浏览(163)

我注意到,所有读取“arch/arm/include/asm/irqflags.h”中的CPSR(或仅修改F/I标志)的内联asm宏都使用"memory", "cc"乱码。
例如:https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/arch/arm/include/asm/irqflags.h?h=v6.0.2#n155

#define IRQMASK_REG_NAME_R "cpsr"

static inline unsigned long arch_local_save_flags(void)
{
    unsigned long flags;
    asm volatile(
        "       mrs     %0, " IRQMASK_REG_NAME_R "      @ local_save_flags"
        : "=r" (flags) : : "memory", "cc");
    return flags;
}

我认为这个乱码会阻止编译器在周围的代码中移动这些宏的任何使用。
有人能详细解释一下这是怎么回事吗?
我(认为我)理解“内存”部分,但我对“cc”感到困惑,因为阅读CPSR IMHO不会更改条件码寄存器(更改F/I标志也不会更改真实的状态标志)?
我提出这个问题的原因是我想学习如何正确地编写这样的宏。
非常感谢!

v8wbuo2f

v8wbuo2f1#

也许是徒劳地试图停止编译器生成的修改标志的代码的重新排序?(对于+编译为add,没有明确定义的语义,更不用说adds了。而且编译器总是可以将标志设置和用法放在asm语句的两侧。)
也许我错过了一些关于其他inline-asm hack可能发生在附近使用的其他函数中的东西,这里面有一些重要的东西。
"memory" clobber至少有助于控制操作相对于非局部变量的内存访问的位置,它使编译器假设任何全局可访问的内存都已被读取和/或修改。
对于 * 设置 * CPSR,我认为使用"memory" clobber来确保它是按顺序访问内存的,如果这可能是启用或禁用中断,或者其他可能影响内存访问的东西,这将是非常有意义的。

相关问题