class CCpuInfo
{
public:
/// constructor
CCpuInfo();
/// destructor
virtual ~CCpuInfo();
...
/// find supported features, mmx, sse, 3dnow!, ect..
void GetFeatures();
private:
BOOL supportSSE;
BOOL supportSSE2;
BOOL supportMMX;
...
};
//------------------------------------------------------------------------------
/**
*/
CCpuInfo::CCpuInfo() :
supportSSE ( FALSE ),
supportSSE2 ( FALSE ),
supportMMX ( FALSE ),
{
}
void CCpuInfo::GetFeatures()
{
BOOL *_supportSSE = &this->supportSSE;
BOOL *_supportSSE2 = &this->supportSSE2;
BOOL *_supportMMX = &this->supportMMX;
__asm {
mov eax, 1
CPUID
test edx, 02000000h
jz _NOSSE
mov [_supportSSE], 1
_NOSSE: test edx, 04000000h
jz _NOSSE2
mov [_supportSSE2], 1
_NOSSE2: test edx, 00800000h
jz _EXIT
mov [_supportMMX], 1
_EXIT:
}
}
Inline Assembler Issues
Hi all,
I am having trouble setting values of class memebers using the inline assembler if they have been previously initialized. I cant quite figure out what the problem is exactly, but I have a feeling it has to do with my lack of understanding how certain instructions, like mov, move data around. Here is some code to help illustrate my problem:
If I remove the intialization for the three BOOL's, the GetFeatures() function will set them properly, otherwise they will always be false. I am assuming in the code that the values are true as long as they are not equal to zero.
Are you sure it sets them properly if there's no initialization? I wonder if without initialization, they just happen to end up with nonzero values. Try this: remove the initialization code, and change the asm to set the values to 0 if the features are detected. I'm guessing they'll stay TRUE.
Quote:I wonder if without initialization, they just happen to end up with nonzero values.
Wow, I cant beleive I didnt notice that. Thanks!
Ive also noticed that if I move my data (one of the bools) into a register, and then operate on the data in that register instead of the data directly, it works - though, im still not sure why.
Here is an example of some working code. Ive split the previous function up, so here is the code to check for SSE support:
void CCpuInfo::CheckSupportSSE(){ int *tmp = &this->supportSSE; __asm { mov eax, 1 CPUID test edx, FLAG_SSE jz _EXIT mov edx, tmp mov [edx], 1_EXIT: }}
Hi luridcortex,
Your _supportSSE is a variable, holding an address to another variable where you would like to store some information. The name _supportSSE itself actually represents the memory location (a pointer) of the _supportSSE variable (which holds the value of a pointer). So what you really need to do is something like:
Hope that helps...
Your _supportSSE is a variable, holding an address to another variable where you would like to store some information. The name _supportSSE itself actually represents the memory location (a pointer) of the _supportSSE variable (which holds the value of a pointer). So what you really need to do is something like:
mov eax, [_supportSSE]mov [eax], 1
Hope that helps...
Here's a straightforward way to set member variables in an __asm block. (Note: I know this works with MSVC - can't vouch for other compilers.)
edit:
Also, to make it work the other way, it's:
Just remember that if you want to dereference an address with [], the address needs to be in a register. The "dword ptr" part lets the compiler know the size of the object - in this case 4 bytes.
[Edited by - LastUnicron on April 9, 2005 5:09:12 PM]
__asm{ mov ebx, this mov [ebx].supportSSE, 1}
edit:
Also, to make it work the other way, it's:
__asm{ mov ebx, _supportSSE mov dword ptr[ebx], 1}
Just remember that if you want to dereference an address with [], the address needs to be in a register. The "dword ptr" part lets the compiler know the size of the object - in this case 4 bytes.
[Edited by - LastUnicron on April 9, 2005 5:09:12 PM]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement