gcc 内联汇编中 %c 的用法
这几天看KVM代码的时候看到里面有个内联汇编的语法很陌生(下面的代码截取了部分内联汇编片段):
asm (
"mov %c[rax](%3), %%rax \n\t"
"mov %c[rbx](%3), %%rbx \n\t"
"mov %c[rdx](%3), %%rdx \n\t"
"mov %c[rsi](%3), %%rsi \n\t"
"mov %c[rdi](%3), %%rdi \n\t"
: "=q" (fail)
: "r"(vcpu->launched), "d"((unsigned long)HOST_RSP),
"c"(vcpu),
[rax]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_RAX])),
[rbx]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_RBX])),
[rcx]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_RCX]))
: "cc", "memory" );
stackoverflow上问了下才知道这是gcc的operand substitution语法,%c后面跟上常量名,就能在内联汇编中使用这个常量了。
以这段代码为例,vcpu是struct kvm_vcpu类型,[rax]“i”(offsetof(struct kvm_vcpu, regs[VCPU_REGS_RAX])这句话把vcpu->regs[VCPU_REGS_RAX]相对于vcpu的偏移赋值给了rax这一常量。接下来回到第一行mov %crax, %%eax,%c[rax]等于前面得到的偏移量,加上vcpu并取值后就是vcpu->regs[VCPU_REGS_RAX]中保存的值了,这个指令会把这个值保存在%rax寄存器中,从而完成了vcpu的rax寄存器恢复工作。
本作品采用知识共享署名-非商业性使用 3.0 版本许可协议进行许可,欢迎转载,演绎,但是必须保留本文的署名 zellux(包含链接),且不得用于商业目的。