免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 2880 | 回复: 14

[C] 内核源码中的汇编有一点不理解 [复制链接]

论坛徽章:
0
发表于 2013-10-25 12:18 |显示全部楼层
  1. asm(
  2.                 /* Store host registers */
  3.                 "push %%"R"dx; push %%"R"bp;"
  4.                 "push %%"R"cx \n\t"
  5.                 "cmp %%"R"sp, %c[host_rsp]([color=Red]%0[/color]) \n\t"
  6.                 "je 1f \n\t"
  7.                 "mov %%"R"sp, %c[host_rsp](%0) \n\t"
  8.                 __ex(ASM_VMX_VMWRITE_RSP_RDX) "\n\t"
  9.                 "1: \n\t"
  10.                 /* Reload cr2 if changed */
  11.                 "mov %c[cr2](%0), %%"R"ax \n\t"
  12.                 "mov %%cr2, %%"R"dx \n\t"
  13.                 "cmp %%"R"ax, %%"R"dx \n\t"
  14.                 "je 2f \n\t"
  15.                 "mov %%"R"ax, %%cr2 \n\t"
  16.                 "2: \n\t"
  17.                 /* Check if vmlaunch of vmresume is needed */
  18.                 "cmpl $0, %c[launched](%0) \n\t"
  19.                 /* Load guest registers.  Don't clobber flags. */
  20.                 "mov %c[rax](%0), %%"R"ax \n\t"
  21.                 "mov %c[rbx](%0), %%"R"bx \n\t"
  22.                 "mov %c[rdx](%0), %%"R"dx \n\t"
  23.                 "mov %c[rsi](%0), %%"R"si \n\t"
  24.                 "mov %c[rdi](%0), %%"R"di \n\t"
  25.                 "mov %c[rbp](%0), %%"R"bp \n\t"
  26. #ifdef CONFIG_X86_64
  27.                 "mov %c[r8](%0),  %%r8  \n\t"
  28.                 "mov %c[r9](%0),  %%r9  \n\t"
  29.                 "mov %c[r10](%0), %%r10 \n\t"
  30.                 "mov %c[r11](%0), %%r11 \n\t"
  31.                 "mov %c[r12](%0), %%r12 \n\t"
  32.                 "mov %c[r13](%0), %%r13 \n\t"
  33.                 "mov %c[r14](%0), %%r14 \n\t"
  34.                 "mov %c[r15](%0), %%r15 \n\t"
  35. #endif
  36.                 "mov %c[rcx](%0), %%"R"cx \n\t" /* kills %0 (ecx) */

  37.                 /* Enter guest mode */
  38.                 "jne .Llaunched \n\t"
  39.                 __ex(ASM_VMX_VMLAUNCH) "\n\t"
  40.                 "jmp .Lkvm_vmx_return \n\t"
  41.                 ".Llaunched: " __ex(ASM_VMX_VMRESUME) "\n\t"
  42.                 ".Lkvm_vmx_return: "
  43.                 /* Save guest registers, load host registers, keep flags */
  44.                 "xchg %0,     (%%"R"sp) \n\t"
  45.                 "mov %%"R"ax, %c[rax](%0) \n\t"
  46.                 "mov %%"R"bx, %c[rbx](%0) \n\t"
  47.                 "push"Q" (%%"R"sp); pop"Q" %c[rcx](%0) \n\t"
  48.                 "mov %%"R"dx, %c[rdx](%0) \n\t"
  49.                 "mov %%"R"si, %c[rsi](%0) \n\t"
  50.                 "mov %%"R"di, %c[rdi](%0) \n\t"
  51.                 "mov %%"R"bp, %c[rbp](%0) \n\t"
  52. #ifdef CONFIG_X86_64
  53.                 "mov %%r8,  %c[r8](%0) \n\t"
  54.                 "mov %%r9,  %c[r9](%0) \n\t"
  55.                 "mov %%r10, %c[r10](%0) \n\t"
  56.                 "mov %%r11, %c[r11](%0) \n\t"
  57.                 "mov %%r12, %c[r12](%0) \n\t"
  58.                 "mov %%r13, %c[r13](%0) \n\t"
  59.                 "mov %%r14, %c[r14](%0) \n\t"
  60.                 "mov %%r15, %c[r15](%0) \n\t"
  61. #endif
  62.                 "mov %%cr2, %%"R"ax   \n\t"
  63.                 "mov %%"R"ax, %c[cr2](%0) \n\t"

  64.                 "pop  %%"R"bp; pop  %%"R"bp; pop  %%"R"dx \n\t"
  65.                 "setbe %c[fail](%0) \n\t"
  66.               : : "c"(vmx), "d"((unsigned long)HOST_RSP),
  67.                 [launched]"i"(offsetof(struct vcpu_vmx, launched)),
  68.                 [fail]"i"(offsetof(struct vcpu_vmx, fail)),
  69.                 [host_rsp]"i"(offsetof(struct vcpu_vmx, host_rsp)),
  70.                 [rax]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RAX])),
  71.                 [rbx]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RBX])),
  72.                 [rcx]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RCX])),
  73.                 [rdx]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RDX])),
  74.                 [rsi]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RSI])),
  75.                 [rdi]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RDI])),
  76.                 [rbp]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RBP])),
  77. #ifdef CONFIG_X86_64
  78.                 [r8]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R8])),
  79.                 [r9]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R9])),
  80.                 [r10]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R10])),
  81.                 [r11]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R11])),
  82.                 [r12]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R12])),
  83.                 [r13]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R13])),
  84.                 [r14]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R14])),
  85.                 [r15]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R15])),
  86. #endif
  87.                 [cr2]"i"(offsetof(struct vcpu_vmx, vcpu.arch.cr2))
  88.               : "cc", "memory"
  89.                 , R"ax", R"bx", R"di", R"si"
  90. #ifdef CONFIG_X86_64
  91.                 , "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
  92. #endif
  93.               );
复制代码
里面出现了非常多的%0,"mov %%r9,  %c[r9](%0),这里的%0是什么意思?看起来明显不像是用第0个参数。

论坛徽章:
5
双鱼座
日期:2013-11-26 17:56:26狮子座
日期:2013-11-29 15:41:32处女座
日期:2014-02-21 11:59:07技术图书徽章
日期:2014-03-06 15:33:53技术图书徽章
日期:2014-03-06 15:39:30
发表于 2013-10-25 14:20 |显示全部楼层
以我比较菜的水平我认为这是个placeholder.
look at the definition:

the extended asm format provides placeholders that can be used to reference input and
output values within the inline assembly code. This enables you to declare input and output values in
any register or memory location that is convenient for the compiler.
The placeholders are numbers, preceded by a percent sign. Each input and output value listed in the inline
assembly code is assigned a number based on its location in the listing, starting with zero. The placeholders
can then be used in the assembly code to represent the values.

and here are one example.

For example, the following inline code:
asm (“assembly code”
: “=r”(result)
: “r”(data1), “r”(data2));
will produce the following placeholders:
❑ %0 will represent the register containing the result variable value.
❑ %1 will represent the register containing the data1 variable value.
❑ %2 will represent the register containing the data2 variable value.

论坛徽章:
0
发表于 2013-10-25 14:56 |显示全部楼层
回复 2# bottles


    不是这段文字所表示的意思,在这段文字里,%0,%1,%2表示的是参数,

论坛徽章:
5
双鱼座
日期:2013-11-26 17:56:26狮子座
日期:2013-11-29 15:41:32处女座
日期:2014-02-21 11:59:07技术图书徽章
日期:2014-03-06 15:33:53技术图书徽章
日期:2014-03-06 15:39:30
发表于 2013-10-25 15:54 |显示全部楼层
回复 3# 李营长


    我认为,这个列表里面output没有%0最有可能代表的是第1个参数vmx

论坛徽章:
0
发表于 2013-10-25 16:05 |显示全部楼层
回复 4# bottles


    我已经写代码验证了,确实%0指的就是第0个参数,你说的是对的。

论坛徽章:
0
发表于 2013-10-25 16:08 |显示全部楼层
另一个问题是
               /* Enter guest mode */
                "jne .Llaunched \n\t"
                __ex(ASM_VMX_VMLAUNCH) "\n\t"  //执行vmlaunch
                "jmp .Lkvm_vmx_return \n\t"
                ".Llaunched: " __ex(ASM_VMX_VMRESUME) "\n\t" //执行vm resum
                ".Lkvm_vmx_return: "

看手册,vm launch和vm resume只是讲了一系列的条件较验,难道这两条指令会一直卡住直到vm exit才会执行到kvm_vmx_return?)

论坛徽章:
4
戌狗
日期:2013-08-15 18:22:43技术图书徽章
日期:2013-08-21 13:48:45巨蟹座
日期:2013-09-26 17:06:39处女座
日期:2013-12-25 11:26:10
发表于 2013-10-25 16:16 |显示全部楼层
%0是vmx,作为基址。
r1等是vmx内的字段,作为偏移。

vmlaunch或vmresume后,就进入guest os了。直到guest os触发vm exit。

论坛徽章:
0
发表于 2013-10-25 16:24 |显示全部楼层
回复 7# 塑料袋


    这样的话,就没问题了。

论坛徽章:
17
处女座
日期:2013-08-27 09:59:352015亚冠之柏太阳神
日期:2015-07-30 10:16:402015亚冠之萨济拖拉机
日期:2015-07-29 18:58:182015年亚洲杯之巴勒斯坦
日期:2015-03-06 17:38:17摩羯座
日期:2014-12-11 21:31:34戌狗
日期:2014-07-20 20:57:32子鼠
日期:2014-05-15 16:25:21亥猪
日期:2014-02-11 17:32:05丑牛
日期:2014-01-20 15:45:51丑牛
日期:2013-10-22 11:12:56双子座
日期:2013-10-18 16:28:17白羊座
日期:2013-10-18 10:50:45
发表于 2013-10-25 17:56 |显示全部楼层
回复 1# 李营长


    格式:asm(code : output operand list : input operand list : clobber list);
    在这个调用里output operand list 被忽略,表达式mov %%r9,  %c[r9](%0)中%0在这里实际上是指"c"(vmx)中的vmx这个C中的变量。%c[r9]是指[r9]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R9]))这个直接量,%c在这里表示常量(constant),%c[r9](%0)表示vms->vcpu.arch.regs[VCPU_REGS_R9]。VCPU_REGS_R9 = 9,在x86系统下regs的定义是unsigned long regs[NR_VCPU_REGS];

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2013-10-28 16:58 |显示全部楼层
@李营长验证代码是如何写的?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

SACC2021中国系统架构师大会

【数字转型 架构重塑】2021年5月20日-22日第十三届中国系统架构师大会将在云端进行网络直播。

大会为期3天的议程,涉及20+专场,近120个主题,完整迁移到线上进行网络直播对会议组织来说绝非易事;但考虑到云端会议的直播形式可以实现全国各地技术爱好者的参与,也使ITPUB作为技术共享交流平台得到更好的普及,我们决定迎难而上。
http://sacc.it168.com/


大会官网>>
  

北京盛拓优讯信息技术有限公司. 版权所有 16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP