如何解决为什么内联汇编和优化会产生 rbit 问题
以下代码:
#include <cstdint>
uint8_t res{};
//__attribute__ ((noinline))
static uint8_t reverse_bits() {
uint32_t word = 10;
asm("rbit %1,%0" : "=r"(word) : "r"(word));
word >>= 24;
return word;
}
void calc() {
res ^= reverse_bits();
}
int main() {
calc();
return res;
}
在 GCC ARM 9.3 上使用 Os 编译时生成此汇编代码:
│0x8002a80 <main()> ldr r2,[pc,#16] ; (0x8002a94 <main()+20>) │
│0x8002a82 <main()+2> movs r0,#10 │
│0x8002a84 <main()+4> rbit r0,r3 │
│0x8002a88 <main()+8> ldrb r0,[r2,#0] │
│0x8002a8a <main()+10> eor.w r0,r0,r3,lsr #24 │
│0x8002a8e <main()+14> strb r0,#0] │
│0x8002a90 <main()+16> bx lr │
https://gcc.godbolt.org/z/96zjhr4hP
代码产生错误的运行时结果。 0 而不是 80。如果我强制没有内联,则输出是正确的。生成的程序集是:
│0x80003a2 <reverse_bits()> movs r0,#10 │
│0x80003a4 <reverse_bits()+2> rbit r0,r0 │
│0x80003a8 <reverse_bits()+6> lsrs r0,#24 │
│0x80003aa <reverse_bits()+8> bx lr
│0x8002a90 <main()> push {r3,lr} │
│0x8002a92 <main()+2> bl 0x80003a2 <reverse_bits()> │
│0x8002a96 <main()+6> ldr r3,#12] ; (0x8002aa4 <main()+20>) │
│0x8002a98 <main()+8> ldrb r2,[r3,#0] │
│0x8002a9a <main()+10> eors r0,r2 │
│0x8002a9c <main()+12> uxtb r0,r0 │
│0x8002a9e <main()+14> strb r0,#0] │
│0x8002aa0 <main()+16> pop {r3,pc} │
│0x8002aa2 <main()+18> nop │
│0x8002aa4 <main()+20> lsrs r4,r7,#16 │
│0x8002aa6 <main()+22> movs r0,#32
https://gcc.godbolt.org/z/G4Ex7rsbx
内联汇编有什么问题?
附言RBit 在某些地方真的很方便,因为它可以在单个指令中反转位。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。