Advertisement

Why can't I use class members in __asm?

Started by February 20, 2001 08:37 PM
8 comments, last by gimp 23 years, 11 months ago
I''m betting that I need to reference the m_Data differently than just listing it''s name. Should I do something like this->m_Data?
Chris Brodie
You can''t do that due to the way data from pointers is read. You CAN read data from classes and structures as long as you''re not reading it from a pointer. Examples:

RECT Rect;
Rect.right = 640;
_asm
{
mov eax, Rect.right
}

But to read data from a RECT*, you''d need to say something like this:

RECT* Rect = new RECT;
Rect->right = 640;
_asm
{
mov ebx, Rect
mov eax, DWORD PTR [ebx+8]; // Skip left and top
}

The compiler might not allow you to put Rect in ebx, you might have to say dwRect = (DWORD)Rect and put that in ebx instead. It amounts to the same thing.

As for how Rect->right is read in the second example, a RECT structure contains four DWORDs (4 bytes each), in this order: left, top, right, bottom. ebx pointed to the beginning of the structure, which is Rect->left. We incremented it by 8 so it pointed to Rect->right.

~CGameProgrammer( );

~CGameProgrammer( ); Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.
Advertisement
In either case, you can do this (pointer/reference):
__asm{  mov ebx, qword ptr [rect];  mov ecx, [ebx].right;  ...} 
No you can''t. Both of those commands are wrong. You cannot move a QWORD into a DWORD register, so there goes the first command. As for the second, registers don''t have a parameter called ".right", only the RECT structure does. So there goes the second. Assembly is not like C++ so don''t make assumptions about it until you know what you''re doing =)

~CGameProgrammer( );

~CGameProgrammer( ); Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.
You can do...

  _asm{   mov   ebx,rect   mov   eax,[ebx].right}  


.right is an offset into the structure RECT. So it converts to [ebx+8]. So the second instruction was not wrong. I compiled it, I tested it and it moved the correct data in eax.
Keys to success: Ability, ambition and opportunity.
CGameProgrammer:

This is inline assembly, not processor assembly. It''s different from, let''s say, macro assembly, although minimally so in MSVC++. Both inline assembly and macro assembly are translated, because they are resolved by the compiler...
VK
Advertisement
Oh, my mistake. Does the compiler look up the last value placed in ebx to find out what .right is referencing? Because more than one structure can have a "right" member.

~CGameProgrammer( );

~CGameProgrammer( ); Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.
Excuse me... I hit the "q" when I should have hit the "d". I''m so sorry. But I know that it works, I use it in my vector class.

Anyway, to answer your latest question: I think so... The .right member must still be visible to the function (public - unless the function is a friend of the class). That doesn''t prevent you from doing:

mov ebx, rect; // Assume rect has private member here.
mov eax, [ebx+12]; // This will work but shouldn''t be done.

if the member variable at +12 is private or protected. But then there are some major assumptions being made... Not good to do.


Yeah, and technically you don''t even need to write assembly to do that. You can do that in C++ with int datum = *(int *)(DWORD(Rect) + 12). But that is clearly very evil code. Let us never speak of it again.

~CGameProgrammer( );

~CGameProgrammer( ); Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.
If the name isn''t unique then you would need to use...

      RECT *rect = new RECT;    WINDOWPLACEMENT *winplace = new WINDOWPLACEMENT;    asm    {        mov     ebx,rect        mov     eax,[(rect ptr ebx).right]        mov     ebx,winplace        mov     eax,[(winplace ptr ebx).rcNormalPosition.right]    }    if (rect)        delete rect;    if (winplace)        delete winplace;  
Keys to success: Ability, ambition and opportunity.

This topic is closed to new replies.

Advertisement