Visual Studio Inline Assembler x86
I've finally come back to experiment with the inline assembler within visual studio. Mainly because I am needing an extremely fast random number generator as a lot of my future code will be working with procedural content. Now that I've got a complete but very simple random number generator working I thought I'd post it.
When using the inline assembler from within visual studio you are free to use
EAX, EBX, ECX, EDX, ESI, and EDI registers. Anything that's left in
EAX will be the return value.
Why the inline assembler?
Because inline assembler code is extremely fast! Simple...
Inline assembler example code
I've left some of the old code commented out so you can see where I started with this.
// inline assembler is free to use EAX, EBX, ECX, EDX, ESI, and EDI
// a standard asm function returns eax
__declspec(naked)
int frandasm(int seed)
{
static int rnd_seed; // never re-defined on subsequent calls (static)
//if (seed != -1) {
__asm {
;push edx // the registers don't need preserving
mov eax, [seed]
jns set_seed; // if signed flag set
mov eax,[rnd_seed]
mov edx, 0019660dh // mix its value up
mul edx
add eax, 3c6ef35fh
mov [rnd_seed], eax
;pop edx
ret // returns eax as the int
set_seed:
mov [rnd_seed],eax // store new seed value
ret
};
//} else rnd_seed = seed;
// return rnd_seed;
}
You may note the '//' in the above code, that's because whilst I was learning the inline assembler I originally mixed it within C++ itself, but at the end of the day I wanted just a pure inline assembler function.
The above function is defined as:
int frandasm(int seed = -1);
Which will allow for two types of call, one to set the seed and with just empty braces will return a random number value.
Using the inline assembler it is going to be so much faster than using:
// returns a 32 bit unsigned random number
#define rand32() ( ( (unsigned int)rand() << 16 ) + (unsigned int)rand() )
To test whether this inline assembler function did actually work I threw a simple test in using Pure GDK (can use GDK too of course):
void test4() {
// test the asm random number generator
int v;
while (windowEvent() != WM_CLOSE && dbEscapeKey() == 0) {
//
dbClearScreen(); // GDK use dbCLS()
frandasm(1); // init the seed
for (v=0; v < 40; v++) {
itoa(frandasm(),gstring,10); // global string pointer
dbText(0,v*12,gstring);
}
dbSync();
}
}
As I experiment as well as re-learn assembler programming I will post more examples up and hopefully others will find them useful too.
Warning! May contain Nuts!