【发布时间】:2021-06-06 11:42:15
【问题描述】:
我很难让它工作:
我尝试了以下方法:
uint32_t reverseBits(volatile uint32_t n) {
uint32_t i = n;
__asm__ (".intel_syntax\n"
"xor eax, eax \n"
"inc eax \n"
"myloop: \n"
"shr %0, 1 \n"
"adc eax, eax \n"
"jnc short myloop \n"
"mov %1, %0 \n"
: [i] "=r"(i), [n] "=r"(n));;
return n;
}
我会得到:
Line 11: Char 14: error: unknown token in expression
"shr %0, 1 \n"
^
<inline asm>:5:5: note: instantiated into assembly here
shr %edx, 1
^
显然编译器将%0 替换为%register,但仍保留'%'...
因此,我决定将%0 替换为edx,将%1 替换为ecx:
uint32_t reverseBits(volatile uint32_t n) {
uint32_t i = n;
__asm__ (".intel_syntax\n"
"xor eax, eax \n"
"inc eax \n"
"myloop: \n"
"shr edx, 1 \n"
"adc eax, eax \n"
"jnc short myloop \n"
"mov ecx, edx \n"
: [i] "=r"(i), [n] "=r"(n));;
return n;
}
并得到结果错误:
AddressSanitizer:DEADLYSIGNAL
=================================================================
==31==ERROR: AddressSanitizer: SEGV on unknown address 0x0001405746c8 (pc 0x00000034214d bp 0x7fff1363ed90 sp 0x7fff1363ea20 T0)
==31==The signal is caused by a READ memory access.
#1 0x7f61ff3970b2 (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
AddressSanitizer can not provide additional info.
==31==ABORTING
我怀疑编译器优化了一些东西并内联了被调用的函数(所以不是 ret),但我仍然不知道该怎么做。
注意:我无法将编译器从 clang 更改为 gcc,因为它不是我,而是使用 clang 11 的远程服务器。我也已经有 read this link,但它已经很老了(2013 年),如果有事情发生,我会感到惊讶从那以后就没有改变过。
编辑:按照 Peter Cordes 的出色回答,我能够让它工作得更好一点:
uint32_t reverseBits(volatile uint32_t n) {
uint32_t i = n;
__asm__ (".intel_syntax noprefix\n"
"xor rax,rax \n"
"inc rax \n"
"myloop: \n"
"shr %V0, 1 \n"
"adc eax, eax \n"
"jnc short myloop \n"
"mov %V0, rax \n"
".att_syntax"
: [i] "=r"(i));;
return i;
}
但是有两件事:
1/ 我不得不将 eax 更改为 rax,因为 %V0 占用 64 位 (r13),这很奇怪,因为 i 应该只占 32 位 (uint32_t)。
2/ 我没有得到想要的输出:
input is : 00000010100101000001111010011100
output is: 93330624 (00000101100100000001110011000000)
expected: 964176192 (00111001011110000010100101000000)
注意:我测试了 "mov %V0, 1 \n" 并正确地得到了1 作为输出,这证明了替换以某种方式起作用。
【问题讨论】:
-
Re:您的编辑:您使用 RAX 而不将其声明为 clobber。此外,
[i] "=r"(i)告诉编译器操作数是仅输出的,因此它可以优化掉任何会写入它选择的寄存器的东西。如果您坚持使用它,请参阅 stackoverflow.com/tags/inline-assembly/info 中的 inline-asm 指南以了解基础知识。
标签: x86 clang inline-assembly intel-syntax