内联汇编在不应该的时候重用相同的寄存器
Inline assembly reusing same register when it shouldn't
我有一个使用内联汇编的位扫描功能,但 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
它混淆了输入寄存器和结果寄存器,从而产生了错误的结果。
第一次写内联汇编,我是不是做错了什么?
假设它将使用不同的寄存器是不是不安全?如果是这样。我如何告诉它使用不同的寄存器?
可以试试吗?
:[结果] "=&r" (结果)
clang 遵循与 gcc 相同的 rules for inline asm:
Use the &
constraint modifier (see Modifiers) on all output operands that must not overlap an input. Otherwise, GCC may allocate the output operand in the same register as an unrelated input operand, on the assumption that the assembler code consumes its inputs before producing outputs.
我有一个使用内联汇编的位扫描功能,但 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
它混淆了输入寄存器和结果寄存器,从而产生了错误的结果。
第一次写内联汇编,我是不是做错了什么?
假设它将使用不同的寄存器是不是不安全?如果是这样。我如何告诉它使用不同的寄存器?
可以试试吗?
:[结果] "=&r" (结果)
clang 遵循与 gcc 相同的 rules for inline asm:
Use the
&
constraint modifier (see Modifiers) on all output operands that must not overlap an input. Otherwise, GCC may allocate the output operand in the same register as an unrelated input operand, on the assumption that the assembler code consumes its inputs before producing outputs.