我有一个位扫描函数,它使用内联汇编,clang产生奇怪的输出
代码:
uint64_t bit_scan_forward(uint64_t input) {
uint64_t result;
asm("MOVQ %[immidiate], %[result];"
"BSF %[input], %[result];"
:[result] "=r" (result)
:[input] "r" (input)
,[immidiate] "N" (64));
return result;
}
输出:
sub rsp, 0x10
mov qword ptr [rsp+0x8], rcx
mov rax, qword ptr [rsp+0x8] //set input
mov rax, 0x40 //set result(which uses the same register as input for some reason)
bsf rax, rax //do bsf
mov qword ptr [rsp], rax
mov rax, qword ptr [rsp]
add rsp, 0x10
ret
它混淆了输入寄存器和结果寄存器,从而产生错误的结果。
第一次写内联汇编,我做错了什么吗?
假设它将使用不同的寄存器是否不安全?如果是这样的话。我如何告诉它使用不同的寄存器?
clang对内联asm遵循与gcc相同的规则:
在所有不能与输入重叠的输出操作数上使用
&
约束修饰符(参见修饰符)。否则,GCC可能会将输出操作数分配到同一个寄存器中,作为一个不相关的输入操作数,假设汇编代码在产生输出之前消耗了它的输入。
你能试试吗?
:[结果]"=,r"(结果)