Hi guys,
I am trying to compile a CPUID console application using Visual Studio 2010. I have 2 files in my solution explorer. GetCpuId.asm and GetCpuId.cpp, which are like following.
;GetCpuId on x64 Window 7 Ultimate
.code
;void getcpuid(unsigned __int32* cpuinfo,char* vendorstr);
GetCpuId proc
push rbp
mov rbp,rsp
mov r8,rcx ; capture the first and second arguments into 1->r8 and 2->r9
mov r9,rdx ; cause cpuid will obliterate the lower half of those regs
;retrive the vendor string in its 3 parts
mov eax,0
cpuid
mov [r9+0],ebx
mov [r9+4],edx
mov [r9+8],ecx
mov eax,1
cpuid
mov [r8],eax
mov eax,0
leave
ret
GetCpuId endp
end
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include <iostream>
#include <conio.h>
using namespace std;
extern "C" int GetCpuId(unsigned __int32* cpuinfo, char* vendorstr);
int main(int argc,char **argv){
char vendor[13]={0};
unsigned __int32 flags;
if (!GetCpuId(&flags, vendor)){
cout << "CpuId values has been successfully retrieved from ASM file."
<< endl;
cout << "Those CpuID values comes from an external ASM file assembled with ml64.exe"
<< "linked and compiled with cl.exe within Visual Studio 2010 Ultimate Edition."
<< endl;
cout << "Flags: %u, Vendor: %s\n", flags, vendor;
}
else
{
cout << "CpuId values cannot be retrieved !!!" << endl;
}
_getch();
return 0;
}
----------------------------------------------------------------------------------------------------------------------
and ERRORS I SEE ON OUTPUT SCREEN
ml.exe /c /nologo /Zi /Fo"Debug\GetCpuId.obj" /W3 /errorReport:prompt /Ta"GetCpuId.asm"
1>
1> C:\Users\TrueFX\Documents\Visual Studio 2010\Projects\Deneme\Deneme>ml.exe /c /nologo /Zi /Fo"Debug\GetCpuId.obj" /W3 /errorReport:prompt /Ta"GetCpuId.asm"
1> Assembling: GetCpuId.asm
1>GetCpuId.asm(2): error A2013: .MODEL must precede this directive
1>GetCpuId.asm(5): error A2034: must be in segment block : GetCpuId
1>GetCpuId.asm(6): error A2034: must be in segment block
1>GetCpuId.asm(7): error A2034: must be in segment block
1>GetCpuId.asm(8): error A2034: must be in segment block
1>GetCpuId.asm(9): error A2034: must be in segment block
1>GetCpuId.asm(11): error A2034: must be in segment block
1>GetCpuId.asm(12): error A2034: must be in segment block
1>GetCpuId.asm(13): error A2034: must be in segment block
1>GetCpuId.asm(14): error A2034: must be in segment block
1>GetCpuId.asm(15): error A2034: must be in segment block
1>GetCpuId.asm(17): error A2034: must be in segment block
1>GetCpuId.asm(18): error A2034: must be in segment block
1>GetCpuId.asm(19): error A2034: must be in segment block
1>GetCpuId.asm(20): error A2034: must be in segment block
1>GetCpuId.asm(21): error A2034: must be in segment block
1>GetCpuId.asm(22): error A2034: must be in segment block
1>GetCpuId.asm(23): fatal error A1010: unmatched block nesting : GetCpuId
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\BuildCustomizations\masm.targets(49,5): error MSB3721: The command "ml.exe /c /nologo /Zi /Fo"Debug\GetCpuId.obj" /W3 /errorReport:prompt /Ta"GetCpuId.asm"" exited with code 1.
1>Done executing task "MASM" -- FAILED.
1>Done building target "_MASM" in project "Deneme.vcxproj" -- FAILED.
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:00.26
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
----------------------------------------------------------------------------------------------------------------------------------------
Any help ?
Thanks in advance,
Ok guys. I have tried to assemble GetCpuId.asm file using ml64.exe from command line. I have used same switches as in Visual Studio. Then its compiled and linked without error. But not in Visual Studio. I have realized that Visual Studio tries to compile asm file using ml.exe not ml64.exe. So I have changed project settings from Debug win32 to Debug x64. Now I have another problem probably related with my calling convention or something.
Here is the NEW ERROR MESSAGE I get in visual studio.
1> "x64\Debug\GetCpuId.obj"
1> "x64\Debug\GetCpuId.obj"
1>x64\Debug\GetCpuId.obj : warning LNK4042: object specified more than once; extras ignored
1>GetCpuId.obj : error LNK2019: unresolved external symbol GetCpuId referenced in function main
1>C:\Users\TrueFX\Documents\Visual Studio 2010\Projects\Deneme\x64\Debug\Deneme.exe : fatal error LNK1120: 1 unresolved externals
1> The command exited with code 1120.
1>Done executing task "Link" -- FAILED.
1>Done building target "Link" in project "Deneme.vcxproj" -- FAILED.
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:03.87
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
interesting to see 64-bit code for CPUID :U
the segment block errors are usually generated because you failed to open a .DATA/.DATA? segment for data or .CODE segment for code
because you have that, it is probably because you have failed to define a model and a processor, so the segment doesn't open
the first error in the list tells you where the trouble lies
1>GetCpuId.asm(2): error A2013: .MODEL must precede this directive
QuoteGetCpuId.asm and GetCpuId.cpp
Wouldn't you want to get more creative than that? Both of these would create a GetCpuId.obj
also:
ml.exe == 32Bit
ml64.exe == 64Bit
Quote from: clive on October 12, 2011, 06:01:10 PM
QuoteGetCpuId.asm and GetCpuId.cpp
Wouldn't you want to get more creative than that? Both of these would create a GetCpuId.obj
:) Thanks a lot. In fact I had just changed those file names to same thing and that produced an error in compilation. Anyway your sarcastic remark has helped me to remove this error immediately :). Now it works. Thanks again.
Regards,
Quote from: hasanbaciogluyour sarcastic remark
<G> That's my old cantankerous English side showing up.
not sarcastic at all....
for a Brit :P
your code destroys ebx...
get_cpu_vendor_information proc PUBLIC uses rax rbx rcx rdx rsi, bufferpointer:LPVOID
; assumption -> rcx = pointer to the buffer to store the data into
xor eax,eax
CPUID
mov rsi, [bufferpointer]
mov [rsi], eax
mov [rsi + 4], ebx
mov [rsi + 08h], edx
mov [rsi + 0ch], ecx
xor eax, eax
mov [rsi + 10h], eax
ret
get_cpu_vendor_information endp
is how i do it.. easy to maintain... works fine in masm32
Isn't there a cpuid intrinsic function. :eek