News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

pass by ref pascal inline myParam vs [myParam]

Started by John T, October 26, 2015, 12:41:51 PM

Previous topic - Next topic

John T

I'm doing some inline asm in FPC and have a (pascal) VAR param such as:

procedure foo( var myParam:QWORD );
begin
   asm
      mov edi, myParam
      mov edi, [myParam]
      mov edi, [ebp+8]
   end;
end;

I've tested all 3 of these methods (they all work fine) and I noticed, sure enough, they all set edi to the exact same thing.
I thought, however, that the second way would have turned out to be something different though.
edi is getting the address of the data, which is what I want - but it just seems like the second way should be using the 'data' itself as a  pointer to junk.
e.g. using the lo DWORD of the QWORD as a pointer to junk and loading the address of 'junk' into edi.

Can anyone help me understand why these all work - Is there a 'preferred' way it should be done?

Thanks, John T

hutch--

John,

ByRef usually means passing the ADDRESS of a variable, if its 32 bit code the "MyParam" should be a DWORD (32 bit) not a QWORD.

rrr314159

Hi John T,

Masm syntax treats [myParam] the same as myParam, in this case. You're right it seems that [myParam] should tell it to use the value as an address. However the processor can't use a memory variable for indirect addressing. It probably would make more sense for the statement to simply be illegal; instead the language designers decided to allow it, but just "ignore" the square brackets. AFAIK no one uses that form, it's confusing and redundant
I am NaN ;)

John T

Sweet!!!
I'm not losing my mind after all. I think without the brackets is less confusing so I'll go that route.
Thanks rrr314159

Btw Hutch - The myParam is a DWORD for a 32-bit ptr that points to the actual data (which is the QWORD)
Sorry I wasn't more clear on that - still learning to type english :)

Thanks again everyone, John T

jj2007

While you are at it, i.e. staring at the disassembly in your debugger, try also
  lea eax, myParam
  mov edi, [eax]

FORTRANS

Hi,

Quote from: rrr314159 on October 26, 2015, 01:32:19 PM
instead the language designers decided to allow it, but just "ignore" the square brackets. AFAIK no one uses that form,

   Oops.  I tend to like it.

Regards,

Steve

rrr314159

I am NaN ;)

John T

A related question as to VAR parameters..
Suppose the following:

type
   TComprPat : array of DWORD;

procedure foo();
   var
      arryX : TComprPat;
begin
   SetLength( arryX, 2 );
   DoSetUp( arryX );
end;

procedure DoSetUp( VAR arr : TComprPat );
begin
   asm
      mov  ebx, 35      // some arbitrary value
      mov  edi, arr
      mov DWORD [edi], ebx       // arr gets crashed by this
   end;
end;

When I try to move a value into an array element (0 in this case) it appears the allocation itself for the array is getting lost.
Should this be something like:

      lea  eax, arr
      mov  edi, [eax]
      mov [edi], ebx        // or  mov DWORD [edi], ebx

??
Also, any ideas as to how I could do the SetLength(...) from assembly in pascal
and perhaps arr.resize(...); for C++
I know these are containers/vectors in C++ but dont know anything about the actual internal storage scheme that
C++ uses (or for dynamic arrays in Pascal for that matter).
Anyone know of any good articles or books on this??

John T

John T

OK, I just discovered this:
instead of simply

   mov edi, arr
   mov DWORD [edi], ebx

whats needed is

   mov edi, arr
   mov edi, [edi]
   mov DWORD [edi], ebx

which is working fine.
using an LEA than has to be done as

   lea edi, arr
   mov edi, [edi]
   mov edi, [edi]       // again
   mov [edi], ebx

this works too.

I forgot that under FPC I'm using INTEL syntax, not MASM
and I'm wondering if MASM functions differently for these examples. I don't see how it should but I havent dug into
any disassembly of these yet and havent had the chance to set up an equivalent in MASM imbedded under C++.

Any ideas why the second dereference is needed here??
John T

jj2007

Quote from: John T on October 27, 2015, 05:28:32 PMAny ideas why the second dereference is needed here??

Some compiler developers believe that a pointer to a pointer to a pointer is better than only a pointer to a pointer 8)
Your usage of second dereference shows that you have read the FM, so you are on the right track ;)

Btw the lea example that I posted above has little actual value, it was just meant to enlighten you. Normally, a mov is more efficient.

TWell

This example works?
When it crash?program TestArr;
{$ASMMODE intel}

var
      arryX : array of DWORD;

procedure DoSetUp( VAR arr : array of DWORD );
begin
   asm
      mov  ebx, 35      // some arbitrary value
      mov  edi, arr
      mov  [edi], ebx       // arr gets crashed by this (DWORD removed, useless?)
   end;
end;

begin
   SetLength( arryX, 2 );
   DoSetUp( arryX );
   WriteLn('arryX[0]= ',arryX[0]);
end.

John T

Yes TWell it does seem to run ok - I must have changed something without paying attention. (sorry for that)

BTW, I also found out how to resize a dynamic array using
   call HeapReAlloc
and that's working great too. On this call I'm using HEAP_ZERO_MEMORY for the dwFlags value. It seems that I noticed
that if the array size was NOT changed then the original elements were not zeroed out (don't hold me to this - I only noticed
that happening once and haven't really investigated it because I'm setting all the elements to new fresh values anyway).

I'm just curious:
I'm not using HEAP_GENERATE_EXCEPTIONS in the dwFlags and was wondering if, on return, the eax (or something) might
hold a failure flag. Is there a way to know if HeapReAlloc fails, other than using exceptions or checking the size if the reallocation brute-force??

John T

jj2007

Quote from: John T on October 28, 2015, 08:15:37 AMIs there a way to know if HeapReAlloc fails

WinHelp32.hlp:
QuoteIf the function fails and you have not specified HEAP_GENERATE_EXCEPTIONS, the return value is NULL
If the function fails and you have specified HEAP_GENERATE_EXCEPTIONS, the function may generate the following exceptions:

Value   Meaning
STATUS_NO_MEMORY   The reallocation attempt failed for lack of available memory.
STATUS_ACCESS_VIOLATION   The reallocation attempt failed because of heap corruption or improper function parameters.


If the function fails, it calls SetLastError. An application can call GetLastError for extended error information.

John T

Hi again,
Can anyone help with the proto for HeapSize?
Or, if I use CALL, what are the stack parameters, and is the return in EAX?

Also, I've got Kip Irvines "Assembly language for x86 processors" book and wondered what other decent books there were as to assembly 'style' (common usage of registers and such), and win32 specific programming.

Thanks, John T