Sign in to follow this  
w00

[C++ / (inline)ASM]

Recommended Posts

w00    122
Just a quick question, how can i change a value with inline ASM in C++?? Suppose i have the following:
struct blaat
{
char name[128];
bool bWoot;
} BLA;

int main()
{
BLA bla;

__asm 
{
  mov [bla.bWoot], 1  //<-- this doesn't do the trick
  mov [bla.name], edx //<-- suppose edx contains a string, then this also doesn't work
}

return 0;
}
I can't change the values of my struct that way with asm. Anyone any idea how i can do it?

Share this post


Link to post
Share on other sites
Erik Rufelt    5901
Just mov bla.bWoot, 1 should work.

And I don't know what you mean with edx contains a string. It could contain the address of a string, but then that code won't put it into name. Perhaps you want char *name as an address to a string, if you want to use it that way. You can do mov bla.name[i], 'c' however.

Share this post


Link to post
Share on other sites
w00    122
I'm actually not sure what edx contains, but it must be some sort of string. I'll try to explain it a bit more.

I'm trying to find out if the CPU supports the SSE (SIMD technology).

When i call CPUID it automatically checks what number is stored in eax, then it returns new data about the CPU which is stored in other registers.

If you check my code below you'll see that i'm getting the vendorname of the CPU first. The name of the vendor is always 12 letters long. So this means it's stored in three different registers; ebx, edx and ecx.
I already knew how to put the result back into my struct. I'm declaring a char* which points to the char in my struct. But i was hoping that there was a direct way to set the value.

But that part isn't important right now, cause it does work.

What doesn't is setting the boolean. When i print out the boolean value i get '204' in console... Any idea why that is??

This is my code:

typedef struct CPUINFO_TYP
{
char cpuName[48];
bool bSSE;
} CPUINFO;

CPUINFO GetCPUInfo ( ) {
CPUINFO info;

char* pStr = info.cpuName; //address to vendor name

__asm
{
xor eax, eax

mov eax, 0
CPUID

//Get vendor name
mov esi, pStr
mov [esi], ebx
mov [esi+4], edx
mov [esi+8], ecx

//Check if the CPU supports SSE
mov eax, 1
test edx, 02000000h
jz __NOSSE //if negative jump
mov info.bSSE, 0 //else, set bool in struct to TRUE

__NOSSE:

}

pStr[12] = '\0';

return info;
}

int main ()
{
CPUINFO info = GetCPUInfo ( );
cout << info.cpuName << endl;

if ( info.bSSE )
cout << info.bSSE << endl;

system("pause");
return 0;
}


Share this post


Link to post
Share on other sites
Antheus    2409
Quote:
Original post by w00

I'm trying to find out if the CPU supports the SSE (SIMD technology).


If that is all, would an intrinsic help?

Quote:
When i print out the boolean value i get '204' in console... Any idea why that is??

The SSE support are single bits somewhere in there which need to be extracted. bool type is something else, so it cannot be used directly. See the example.

Share this post


Link to post
Share on other sites
w00    122
hmm, i don't get it. Because i'm using ASM to set the boolean, not SSE...

Also, putting the value 1 in a register doesn't work either. Then i get an error 'operand size conflict'

xor esi, esi
mov esi, 1
mov [info.bSSE], esi

Share this post


Link to post
Share on other sites
Washu    7829
As already linked, use the cpuid intrinsic and not raw assembly. There's no reason to use raw assembly to do what you're doing, since the intrinsic provides the behavior required already (and in a much cleaner package).

Share this post


Link to post
Share on other sites
w00    122
I don't think i can set a bool in my struct with SSE. I use the instrinct to check if SSE is availible, but to set a boolean value in my struct i really think i need ASM for that.

But fortunately i already have the answer. To set the contents of ebx, edx and ecx directly in my char i have to use lea instead of mov.

lea esi, [info.cpuName]

and for the boolean i have to use byte ptr.

mov byte ptr [info.bSSE], 1

This works perfectly.

Share this post


Link to post
Share on other sites
Evil Steve    2017
Quote:
Original post by w00
mov byte ptr [info.bSSE], 1

This works perfectly.
Only in an x86 build of course, and not x64, etc.

I don't understand what's wrong with info.bSSE = true; though? Why on earth are you using assembly at all?

Share this post


Link to post
Share on other sites
mattd    1078
Or just use the intrinsic and no assembly, even better:


struct CPUInfo
{
char name[13];
bool sse;
};

CPUInfo GetCPUInfo() {
CPUInfo result;

int buf[4];

__cpuid(buf, 0);
memcpy(&result.name[0], &buf[1], sizeof(int));
memcpy(&result.name[4], &buf[3], sizeof(int));
memcpy(&result.name[8], &buf[2], sizeof(int));
result.name[12] = 0;

__cpuid(buf, 1);
result.sse = (buf[3] & (1 << 25)) != 0;

return result;
}






[Edited by - mattd on February 17, 2010 11:03:45 AM]

Share this post


Link to post
Share on other sites
Washu    7829
Quote:
Original post by Windryder
To check for SSE and relatives use IsProcessorFeaturePresent().

No. As you may have noticed, there are several notes in that article about which particular flags are supported on which particular operating systems. Just because you are running on Windows 2000 does not mean that your machine does not have SSE2 support. The proper way to detect this, in an OS version independent manner, is to simply use the CPUID intrinsic, and check the flags.

The OP appears to be stuck in some sort of loop where he's ignoring everything not involving assembly, despite the fact that what he's attempting to achieve is documented in the link (an exact example of how to do it in fact).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this