Вы можете увидеть, как это работает, в конце оператора asm
:
: : "c"(vmx), "d"((unsigned long)HOST_RSP),
[launched]"i"(offsetof(struct vcpu_vmx, launched)),
[fail]"i"(offsetof(struct vcpu_vmx, fail)),
[rax]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RAX])),
[rbx]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RBX])),
%3
(это %0
в моем исходном дереве) является ссылкой на локальную переменную vmx
, а %c[rax]
, %c[cr2]
и т. Д. Являются смещениями целочисленной константы соответствующих значений в struct vcpu_vmx
, что vmx
указывает на (%c
означает «постоянный»).
Итак, строка:
mov %c[cr2](%0), %%rax
перемещает содержимое vmx->vcpu.arch.cr2
в %rax
.