Jump to content
  • Advertisement
Sign in to follow this  
Programmer16

[solved]asm problem (C++)

This topic is 4706 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I got a code snippet out of "Tricks of the 3D Game Programming Gurus: Advanced 3D Graphics and Rasterization". It replaces memset(), but when I use it I access violations (I believe that I'm using it incorrectly). Its supposed to clear by QUADs instead of BYTEs (or something like that.) Here are the snippet and a second one that I made:
inline void SetMemory(void* pDest, UINT nData, int iSize)
{
	_asm
	{
		mov edi, pDest;
		mov ecx, iSize;
		mov eax, nData;
		rep stosd;
	}
}

inline void ClearMemory(void* pDest, int iSize)
{
	SetMemory(pDest, 0, iSize);
}


I then tested it with
WNDCLASS WndClass;
dftCommon::ClearMemory(&WndClass, sizeof(WNDCLASS));
Which clears the memory perfectly (just like ZeroMemory(), but after the app returns from main(), I get a large amount of access violations. After switching to ZeroMemory(), they go away. Any ideas? Thanks! [Edited by - Programmer16 on July 4, 2005 1:14:40 PM]

Share this post


Link to post
Share on other sites
Advertisement
Pardon my ignorance of asm, but what exactly is the difference? I suppose the brackets do something, but what is it that they do?

Share this post


Link to post
Share on other sites
As far as I remember, you need brackets around the variable names in assembler because the variable names WITHOUT brackets correspond to their address, not to the variables themselves. Don't know if it is the same in inline assembler.
Also, sizeof gives you the number of bytes, wheras you are trying to write that much dwords. Perhaps that is the error.

Share this post


Link to post
Share on other sites
is iSize in Bytes, or Words? if it is length in bytes try dividing it be 4 before clearing it, or use stosb instead (though stosd will be faster)

Share this post


Link to post
Share on other sites
I'm not sure but I think you should give the size in quad words. You use sizeof which returns the number of bytes so for example if WNDCLASS is 32 bytes it'll clear 32*4(128) bytes and therefore you get an access violation (access 96 bytes beyond the object).

Share this post


Link to post
Share on other sites
im not that capable with x86 these days, but have you tried saving the ecx,edi,asx registers on the stack before using them and then restoring them before you return?

Cheers
-Danu

Share this post


Link to post
Share on other sites
Yes, that fixed it. Thank you good people!

PS: In the appendix of the book, he defines a function like so:

_asm
{
mov edi, x;
mov ecx, 1000/4;
mov eax, 0;
rep stosd;
}



But when I tried to '/ 4', I get an error. Is this just a typo in the book?

The error is:
c:\documents and settings\programmer16\my documents\projects\dragonforge
technology\dftcommon.h(35) : error C2425: '/' : non-constant expression in
'second operand'


Again, thanks!

Share this post


Link to post
Share on other sites
If you're getting a compiler error complaining about that assembly statement, with 1000/4 in it, then something's amiss. Did you say iSize/4? If so, then yes, you will get an error. However, you can accomplish this with:

mov ecx, iSize
shr ecx, 2


As for the compiler saving registers, eax, ecx, and edx are caller saved, which means you can use them as you please, but remember to save them (the stack is the standard place) before you call any other functions if you want to be guaranteed to get your old value back. However, edi is a callee save register. I'd push it before changing the value and then pop it before you return.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!