内联汇编程序存在一些我无法理解的问题。
我有一个内联汇编函数。在 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插件登录页面
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