很早之前Intel曾经提供过一个使用RDTSC在DOS下计算CPU频率的程序(在CPUID的Datasheet中)。简单的说就是延时一个固定的时间,然后看这个时间内经过了多少个指令周期,经过计算就能得到CPU的频率。下面的程序实现了在UEFI环境下计算频率的功能,同时也可以作为插入汇编指令的参考。需要注意,这是32位UEFI环境下,如果在64位的Shell环境下这样做是不行的。
//
// FreqCalc.C
//
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/ShellLib.h>
EFI_SYSTEM_TABLE *gST;
EFI_BOOT_SERVICES *gBS;
UINT64 rdtsc()
{
UINT64 value;
__asm
{
rdtsc
mov dword ptr value,eax
mov dword ptr [value + 4],edx
}
return value;
}
//
// Entry point function - ShowVersion
//
EFI_STATUS
EFIAPI
UefiMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
UINT64 elsp;
gST = SystemTable;
gBS = SystemTable->BootServices;
elsp=rdtsc();
gBS -> Stall(1000000);
Print(L"CPU Frequency: %ld \n", rdtsc()-elsp);
return EFI_SUCCESS;
}
程序运行的结果:
虚拟机中运行的CPUZ读取的结果:
代码下载
特别的,有资料指出在当前的多核环境下,这样的方法并不准确,具体的原因请参考下面的文章
1. http://blog.csdn.net/solstice/article/details/5196544 “多核时代不宜再用 x86 的 RDTSC 指令测试指令周期和时间”
2. http://blog.chinaunix.net/uid-24774106-id-2779245.html “使用rdtsc指令,测量程序的运行速度”


Hi Sir, 使用x64 , –> run “build -a X64 -p AppPkg\AppPkg.dsc” ,,,,無法build “__asm”
error message as below:
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(15) : error C4235:
nonstandard extension used : ‘__asm’ keyword not supported on this architecture
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(18) : error C2146:
syntax error : missing ‘;’ before identifier ‘mov’
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(18) : warning C4550
: expression evaluates to a function which is missing an argument list
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(18) : error C2065:
‘mov’ : undeclared identifier
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(18) : error C2146:
syntax error : missing ‘;’ before identifier ‘dword’
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(18) : error C2065:
‘dword’ : undeclared identifier
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(18) : error C2146:
syntax error : missing ‘;’ before identifier ‘ptr’
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(18) : error C2065:
‘ptr’ : undeclared identifier
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(18) : error C2146:
syntax error : missing ‘;’ before identifier ‘value’
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(19) : error C2065:
‘eax’ : undeclared identifier
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(19) : error C2146:
syntax error : missing ‘;’ before identifier ‘mov’
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(19) : error C2065:
‘mov’ : undeclared identifier
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(19) : error C2146:
syntax error : missing ‘;’ before identifier ‘dword’
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(19) : error C2065:
‘dword’ : undeclared identifier
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(19) : error C2146:
syntax error : missing ‘;’ before identifier ‘ptr’
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(19) : error C2065:
‘ptr’ : undeclared identifier
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(19) : error C2109:
subscript requires array or pointer type
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(20) : error C2065:
‘edx’ : undeclared identifier
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(20) : error C2143:
syntax error : missing ‘;’ before ‘}’
NMAKE : fatal error U1077: ‘”C:\Program Files (x86)\Microsoft Visual Studio 12.0
\Vc\bin\x86_amd64\cl.exe”‘ : return code ‘0x2’
Stop.
build…
: error 7000: Failed to execute command
C:\Program Files (x86)\Microsoft Visual Studio 12.0\Vc\bin\nmake.exe /no
logo tbuild [d:\src\eadk\20141115\Build\AppPkg\DEBUG_VS2012x86\X64\AppPkg\Applic
ations\FreqCalc\FreqCalc]
build…
: error F002: Failed to build module
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.inf [X64, VS2
012×86, DEBUG]
– Failed –
Build end time: 18:14:19, Feb.25 2015
Build total time: 00:00:20
我的实验是在 ia32下做的,x64http://www.lab-z.com/wp-admin/edit-comments.php#comments-form的话,不支持 asm 内嵌汇编了
感謝您的回覆!但是我的測試機台都是UEFI X64 system. 那請教您有什方法可以將asm code可以將它,,,build 成功且能RUN在X64 uefi Shell ?