accessing member vars in assembly

Started by
19 comments, last by Mulligan 21 years, 7 months ago
quote:Original post by _the_phantom_
I belive i see your problem (assuming that was a copy and paste)
in the first block you are moving eax into ebx but then mul eax by ecx, which is either gonna be zero or a random value depending

also, as a side note, isnt it good practise with asm routines to push onto the stack any registers you plan on using and then poping them off at the end, as the process or is probably using ''em to hold data




Yeah, normally it is good practice - but... in the VC++ help files it says (and i know these are not to be taken as gospel) that certain registers can be used without saving and restoring them. Obviously I know that under certain conditions, this does not hold true, but for his case i''m sure it''s fine.
Advertisement
quote:Original post by Mulligan
Thanks, explained much. Now I can do floating point arithmitic on 'float's but not 'double's. Any bigger better registers for that?
Anyway, this compiles bacause i changed everything to 'float':
__asm
{
mov eax, distx
mov ebx, eax
mul ecx
mov ebx, eax

mov eax, disty
mov ecx, eax
mul ecx
add ebx, eax

mov eax, distz
mov ecx, eax
mul ecx
add ebx, eax

mov dRadius, ebx
}

this block represents the C++ form of this:
dRadius = distx*distx + distz*distz + disty*disty;

...but it doesn't work. I'm still an seembly idiot, so let into me if im doing really stupid mistakes.

One last question, which may answer the question above, when I execute the command "mul eax" which registers are multiplied? The result is left in eax, correct?

[edited by - Mulligan on September 11, 2002 11:22:53 PM]




Ok - you are still missing the point. If you look at the numbers you are using, they are decimal values - regardless of wether they are doubles or floats. These values _cannot_ be stored in EAX, EBX, ECX etc etc. They can only be stored in the floating point unit's registers which I have already mentioned are ST0 - ST7 (or something similar at least).

The registers EAX, EBX, ECX etc can only be used for storing whole numbers like 4, 32, 65536 etc etc. The floating point registers are used for holding values like 3.14159, -0.910192 etc.

So....

Going back to my first answer - i'll comment the code a little more:

double distx = 5.0;double radius;__asm{         fld [distx]              ; this line loads your distx into ST0     fmul [distx]             ; this line multiplies distx by ST0 - or effectively, by itself - and stores the result back into ST0     fstp [radius]            ; this line takes the result from ST0 and puts it into radius     }  



Do you see?

Also - you can tell i'm using floating point instructions because they are all prefixed by the letter "f". For example "fmul" as opposed to the "mul" instruction you are using.

I thank the others for trying to help you, but the reason that your code doesn't work isn't that your using ecx by mistake or whatever - it's that your using the wrong registers all together.

Take a look at the post where i outline what registers to use for certain values. See where I say "use ST0 - ST7 for FPU registers"? That is what you need.....


I've really got to finish this article about assembly....

[edited by - Jx on September 11, 2002 12:07:40 AM]
quote:Original post by Jx
Yeah, normally it is good practice - but... in the VC++ help files it says (and i know these are not to be taken as gospel) that certain registers can be used without saving and restoring them. Obviously I know that under certain conditions, this does not hold true, but for his case i''m sure it''s fine.


I think, personaly, I''d push/pop ''em anyways, at least during testing.

That said, I personal wouldnt use assember any more (unless it was an small mircoprocessor) because i''m pretty certain the compiler can turn my C/C++ into better assembler than I could write

(that said, learning assembler is a nice exercise and does give you a better insight into how it all works and can help you write code a bit)
quote:Original post by _the_phantom_

That said, I personal wouldnt use assember any more (unless it was an small mircoprocessor) because i''m pretty certain the compiler can turn my C/C++ into better assembler than I could write



Most of the time, you may be right and I certainly wouldn''t advocate writing all your functions in assembly, BUT: according to my knowledge, my MSVC++ compiler doesn'' optimize for MMX, 3DNow!, SSE/SSE2 etc so the only way to use these powerful instructions is to hand code the functions. Not only that, but sometimes the compiler does make stupid decisions when optimizing functions - but you really should follow that age old phrase: "Profile before you optimize"

In other words: why spend time optimizing your opengl initialization code when it''s only going to get called once? take a look at which parts of the code get called most and a) see if any algorithmic changes could speed them up, and b) make sure you are not performing any unnecessary calculations or allocations within the loop. If you still have a bottleneck - think about breaking out the assembler....

_the_phantom: I know you probably know all this so it wasn''t aimed at you - more people like Mulligan who are new to assembly.
quote:according to my knowledge, my MSVC++ compiler doesn'' optimize for MMX, 3DNow!, SSE/SSE2 etc so the only way to use these powerful instructions is to hand code the functions

It provides relatively high-level class wrappers for the MMX/SSE/SSE2/3DNow! packed datatypes, which may do the job for you.
char a[99999],*p=a;int main(int c,char**V){char*v=c>0?1[V]:(char*)V;if(c>=0)for(;*v&&93!=*v;){62==*v&&++p||60==*v&&--p||43==*v&&++*p||45==*v&&--*p||44==*v&&(*p=getchar())||46==*v&&putchar(*p)||91==*v&&(*p&&main(0,(char**)(--v+2))||(v=(char*)main(-1,(char**)++v)-1));++v;}else for(c=1;c;c+=(91==*v)-(93==*v),++v);return(int)v;}  /*** drpizza@battleaxe.net ***/
quote:Original post by Jx
I''ve really got to finish this article about assembly....

Please do! =) I used to write EVERYTHING in assembly back in the DOS days. Then I started using C++ to create the main structure of the program. Then I started writing most of my functions in C++. Then CPU power boomed, I got lazy and stopped using ASM altogether. Now, we''re several processors in the future, using 32-bit values AND addressing and I''m completely lost now that I want to get back into using assembly.

Not only that, but just UNDERSTANDING assembly is important for programmers. There''s another thread here titled "Are recursive functions limited? Yes." The poster didn''t know that the stack was being used in every function call and thus crashing their machine. An article on this topic would greatly help a lot of people since not many people really know what''s going on under the hood.

- Jay

"I have head-explody!!!" - NNY

Get Tranced!
Quit screwin' around! - Brock Samson
quote:Original post by coderx75
Please do! =)


I''ve started it, but it''s coming along rather slowly at the moment as I''ve got a lot of other stuff to do right now.


By the way - your music is good! I''ve been listening to it for a little while now, even before I saw the link in your posts. I didn''t realise that "coderx75" and "Jay Flaherty" were the same person until now
No $hit?! COOL! =) And thanks, you''re the first here to mention it. Yes, my sig is a shameless plug =)

Where did you originally find my music if not here in the forum? It''s strange but I keep running into people that know who I am from the music. I dig it! =D

- Jay

"I have head-explody!!!" - NNY

Get Tranced!
Quit screwin' around! - Brock Samson
Erm - not sure, but I think you remixed someone else I listened to on MP3.com or something... if not then i probably just got your name of the charts at mp3.com...

[edited by - Jx on September 12, 2002 2:46:26 PM]
quote:Original post by Jx
The registers EAX, EBX, ECX etc can only be used for storing whole numbers like 4, 32, 65536 etc etc. The floating point registers are used for holding values like 3.14159, -0.910192 etc.
The type of data should be pretty irrelevant. You should be fine putting floats, ints, strings, pointers, and whatever in e(a|b|c|d)x as long as they are 32 bits. Although, one should be careful what operations you do to them

quote:Original post by _the_phantom_
That said, I personal wouldnt use assember any more (unless it was an small mircoprocessor) because i'm pretty certain the compiler can turn my C/C++ into better assembler than I could write

??? I highly doubt that, not knowing your assembly skills though. MSVC++ seems to have extremely bad common sense, escpecially when it comes to utilizing registers and hold their values. Instead it constantly "resolves" indirections etc.

This piece of crap came to mind now. It is a part of my line routine for drawing a horizontal line. The first column is the C code, second the assembly MSVC++ produced, the third is how I would have implement it in Motorola 680x0 assembly. If I tried, I'm sure could reduce the x86 assembly a lot.
if(nPixelCountY == 0)				[4] cmp		DWORD PTR _nPixelCountY$[ebp], 0	[2] tst.l  d1						[2] jne		SHORT $L667				[2] bne.b  .type2	while(nPixelCountX--)			[3] mov		edx, DWORD PTR _nPixelCountX$[ebp]						[3] mov		eax, DWORD PTR _nPixelCountX$[ebp]						[3] sub		eax, 1						[3] mov		DWORD PTR _nPixelCountX$[ebp], eax						[2] test	edx, edx						[2] je		SHORT $L670		*pAddress++ = dwColorARGB32;	[3] mov		ecx, DWORD PTR _pAddress$[ebp]						[3] mov		edx, DWORD PTR _dwColorARGB32$[ebp]						[2] mov		DWORD PTR [ecx], edx			[2] move.l d2,(a0)+						[3] mov		eax, DWORD PTR _pAddress$[ebp]						[3] add		eax, 4						[3] mov		DWORD PTR _pAddress$[ebp], eax						[2] jmp		SHORT $L669				[4] dbra   d0,.type1_loop  
EDIT: The number inside the brackets are the instruction size. And the labels I've used: .type2 is somewhere after this stuff, and .type1_loop is pointing to the previous move.l instruction

EDIT 2: The disgusting part of this is that this routine should be able to run without any memory access but when putting the pixel there. Instead it is 5 read accesses and 3 writes (including the pixel putting).

[edited by - CWizard on September 12, 2002 5:23:32 PM]

This topic is closed to new replies.

Advertisement