【问题标题】:gcc optimize variable away before systemcallgcc 在系统调用之前优化变量
【发布时间】:2015-02-10 06:12:58
【问题描述】:

使用 Codesourcery arm-linux-eabi 交叉编译器并且编译器无法执行某些代码时遇到问题,因为它认为它没有被使用,尤其是对于系统调用。有没有办法解决这个问题?

例如这段代码没有初始化变量。

unsigned int temp = 42;
asm volatile("mov R1, %0 :: "r" (temp));
asm volatile("swi 1");

在这种情况下 temp 永远不会被初始化为值 42。但是,如果我在初始化后添加一个 printk,它会被初始化为正确的值 42。我尝试了

unsigned int temp __attribute__ ((used)) = 42;

仍然不起作用,但我收到一条警告消息:

'used' 属性被忽略 [-Wattributes]

这是在 linux 内核代码中。

有什么建议吗?

【问题讨论】:

    标签: c compiler-construction arm


    【解决方案1】:

    这不是使用内联汇编的正确方法。如所写,这两个语句是分开的,编译器没有理由必须保留两者之间的任何寄存器值。您需要将两个汇编指令放在 same 内联汇编块中,并具有适当的输入和输出约束,或者您可以执行以下操作以提高编译器的效率:

    register unsigned int temp __asm__("r1") = 42;
    __asm__ volatile("swi 1" : : "r"(temp) : "memory");
    

    (请注意,我在 clobber 列表中添加了内存;我不确定您正在执行哪个系统调用,但如果系统调用写入用户空间中的任何对象,则需要在 clobberlist 中列出“内存”。)

    【讨论】:

    • 添加重点:对内联 ASM 语句施加的任何约束仅适用于该语句。新的声明,编译器的新球赛。绝对对此 +1。
    • 谢谢,将“内存”添加到 clobber 列表似乎可以解决问题!
    猜你喜欢
    • 2020-07-09
    • 2013-10-13
    • 1970-01-01
    • 2014-12-23
    • 2018-07-08
    • 1970-01-01
    • 2013-05-07
    • 1970-01-01
    • 2017-09-20
    相关资源
    最近更新 更多