前文所述,只是针对汇编格式的整理,本文将使用coreboot项目代码对其进行实例化。以方便、清晰了解到如何在C语言里使用内嵌汇编的方法。同样地,网络上也有众多文章涉及到这方面,所以本文更多是归纳总结。形成自己的学习笔记。
内嵌汇编一般格式如下:
1 2 3 4
| asm volatile("Instruction List" : Output : Input : Clobber/Modify);
|
注意,Output、Input、Clobber/Modify都是可选的,因为有的指令没有输入输出,有的指令只有输入或只有输出。
下面是来自coreboot代码读、写msr的函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| // msr,Model Specific Register,使用rdmsr、wrmsr分别读写MSR // rdmsr读取64比特MSR数据放到edx和eax (分别为高低32比特) wrms同理 // 寄存器索引在ecx中 static inline __attribute__((always_inline)) msr_t rdmsr(unsigned index) { msr_t result; __asm__ __volatile__ ( "rdmsr" : "=a" (result.lo), "=d" (result.hi) : "c" (index) ); return result; }
static inline __attribute__((always_inline)) void wrmsr(unsigned index, msr_t msr) { __asm__ __volatile__ ( "wrmsr" : /* No outputs */ : "c" (index), "a" (msr.lo), "d" (msr.hi) ); }
/* * Generic CPUID function */ static inline struct cpuid_result cpuid(int op) { struct cpuid_result result; asm volatile( "mov %%ebx, %%edi;" "cpuid;" "mov %%ebx, %%esi;" "mov %%edi, %%ebx;" : "=a" (result.eax), "=S" (result.ebx), "=c" (result.ecx), "=d" (result.edx) : "0" (op) : "edi"); return result; }
|
coreboot项目主页:http://www.coreboot.org/
CPUID的wiki:https://en.wikipedia.org/wiki/CPUID
http://blog.csdn.net/surfacedust/article/details/17138675