gcc - ARM ;内联汇编;使用暂存器;

内联汇编程序存在一些我无法理解的问题。

我有一个内联汇编函数。在 ASM block 内,我需要使用一些临时寄存器来修改一些系统值。

void setHW(uint32_t val) {
    asm volatile (
        mrc 15, 0, r0, ...
        orr r0, r0, %0 
        mcr 15, 0, r0, ...
        : :"r"(val) :"r0"
    );
}

实际上函数是由编译器内联的,没关系,代码仍然可以正常工作。

当我尝试用一​​些 stub 变量替换硬编码的 r0 时出现问题,以便编译器可以选择最好的寄存器来使用。看起来像这样

void setHW(uint32_t val) {
    uint32_t reg;
    asm volatile (
        mrc 15, 0, %[reg], ...
        orr %[reg], %[reg], %0 
        mcr 15, 0, %[reg], ...
        :[reg]"=r"(reg) :"r"(val) :
    );
}

现在编译器自己选择寄存器但实际上破坏了 setHW 调用函数的值。 在反汇编器中它看起来像

        add r2, r4, r5       ; caller part, r2 contain some intermedia result
        mrc 15, 0, r2, ...   ; inlined setHW(), r2 is choosen as scratch reg
        orr r2, r2, r0 
        mcr 15, 0, r2, ...
        ; caller continue

如您所见,r2 已损坏,一切都崩溃了。

我应该如何定义临时寄存器以避免这种情况?

最佳答案

这样的事情怎么样:

void setHW(uint32_t val) {
    uint32_t reg;
    asm volatile (
        mrc 15, 0, %[reg], ...
        orr %[reg], %[reg], %[val] 
        mcr 15, 0, %[reg], ...
        :[reg]"=&r"(reg) :[val] "r"(val) :
    );
}

注意 =&r 以修复早期的破坏问题(有关 & 的说明,请参阅 https://gcc.gnu.org/onlinedocs/gcc/Modifiers.html)。

关于gcc - ARM ;内联汇编;使用暂存器;,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38493603/

相关文章:

angularjs - 工厂方法总是在 AngularJs 中返回 undefined

grails - 如何在grails中自定义spring security插件登录页面

shortcode - 如何获取联系表 7 的列表

zend-framework - 使用 OAuth2 和 ZF3-MVC 保护 REST API

javascript - 如何将 "this"传递给 setTimeout 回调?

xslt-2.0 - XSL :FO avoid Space between Table Cells

amazon-web-services - 如何重启 AWS Data Pipeline

c - 解释为什么 j 得出 150?

angularjs - 如何一起使用 select2 v4.03 和 AngularJS

solr - Sitecore 和 SolrCloud 开启重建