News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Trouble with Pointers

Started by CSIRAC, November 19, 2009, 08:15:28 AM

Previous topic - Next topic

CSIRAC

Hi,

I'm trying to translate the following code to MASM:

Quote   
   if ((message == WM_NCCALCSIZE) && (wParam == TRUE)) // Handle the non-client size message.
   {
       // Calculate new NCCALCSIZE_PARAMS based on custom NCA inset.
       NCCALCSIZE_PARAMS *pncsp = reinterpret_cast<NCCALCSIZE_PARAMS*>(lParam); //lParam contains a pointer to a NCCALCSIZE_PARAMS structure

       pncsp->rgrc[0].left   = pncsp->rgrc[0].left   + 0;
       pncsp->rgrc[0].top    = pncsp->rgrc[0].top    + 0;
       pncsp->rgrc[0].right  = pncsp->rgrc[0].right  - 0;
       pncsp->rgrc[0].bottom = pncsp->rgrc[0].bottom - 0;

       lRet = 0;
       // No need to pass message on to the DefWindowProc.
       fCallDWP = false;


I tried to access the fields of the NCCALCSIZE_PARAMS structure by doing this:

Quote

MOV   [lParam].NCCALCSIZE_PARAMS.rgrc.left, [lParam].NCCALCSIZE_PARAMS.rgrc.left
; ect


Why won't this work? (I'm completely new to assembly, so please bear with me if I've done something dumb)















dedndave

you cannot move directly from memory to memory, unless you use a MOVS instruction
MOVS requires the ESI and EDI registers be set to the source and destination addresses
if it is a dword value (32-bits) or smaller, you can MOV it into one of the general registers, then to the destination from there
on a 64-bit machine with a 64-bit OS, you can MOV 64 bits
http://www.arl.wustl.edu/~lockwood/class/cs306/books/artofasm/Chapter_6/CH06-1.html

jj2007

Quote from: CSIRAC on November 19, 2009, 08:15:28 AM
MOV   [lParam].NCCALCSIZE_PARAMS.rgrc.left, [lParam].NCCALCSIZE_PARAMS.rgrc.left

Why won't this work?

As Dave rightly said, direct mem to mem is not possible. You need to get a pointer first, and then use either eax as an intermediate, or the stack. Here two examples assuming that you want to increase .left by 123:

mov edx, lParam
mov eax, [edx.NCCALCSIZE_PARAMS.rgrc.left]
add eax, 123
mov [edx.NCCALCSIZE_PARAMS.rgrc.left], eax

mov edx, lParam
push [edx.NCCALCSIZE_PARAMS.rgrc.left]
add dword ptr [esp], 123
pop [edx.NCCALCSIZE_PARAMS.rgrc.left]


If you use include \masm32\include\masm32rt.inc, you have access to the Masm32 macros. One of them is m2m or "mem to mem", and it does the push/pop thing in one line:

m2m [edx.NCCALCSIZE_PARAMS.rgrc.left], [edx.NCCALCSIZE_PARAMS.rgrc.top]

CSIRAC

Cheers dedndave and jj2007,

My bad for making such a simple error (and forgeting to add to [lParam].NCCALCSIZE_PARAMS.rgrc.left) :'(
I spent ages looking at it (I assumed I'd done something dumb with the lParam pointer). Oh well... I suppose
I'm glad that I don't have to learn another esoteric rule with pointers  :wink