I believe this is more an ASM question than a Rust question; my interpretation from this page is that you can't use lock cmpxchg with registers. (I'm no expert in this area though.)
I change the first operand to a memory location, but the issue is still not solved. I find that save will be substituted with rax such that the first operation always be the value of expect, which is not a memory location. I don't know whether it's a bug or a feature of the compiler.
Yes. And that's violation of your binding promise.
Compiler doesn't look inside of your asm block (it counts instructions in there to know it's size, but that's it), it only looks on the operands you specified. You specified three registers which means you got to touch three registers (you can only touch memory by default in Rust, in С/C++ you would need to do that explicitly, too). If you need more you need to specify them as clobbered.