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
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.
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
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
While you are at it, i.e. staring at the disassembly in your debugger, try also
lea eax, myParam
mov edi, [eax]
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
I meant, "no one who counts" :biggrin: :biggrin:
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
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
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.
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.
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
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.
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
Quote from: John T on November 07, 2015, 08:44:11 PM
Can anyone help with the proto for HeapSize?
Step 7 (http://www.webalice.it/jj2006/Masm32_Tips_Tricks_and_Traps.htm)
MSDN info here (https://msdn.microsoft.com/en-us/library/windows/desktop/aa366706%28v=vs.85%29.aspx)SIZE_T WINAPI HeapSize(
_In_ HANDLE hHeap,
_In_ DWORD dwFlags,
_In_ LPCVOID lpMem
);
so simple proto for asmHeapSize PROTO STDCALL :DWORD,:DWORD,:DWORD
BUT
In Free Pascal inline asm don't accept proto's.
Free Pascal already have function definitions in Windows.ppufunction HeapSize(hHeap:HANDLE; dwFlags:DWORD; lpMem:LPCVOID):PTRUINT; external 'kernel32' name 'HeapSize';
inline use it too?
Bare Free Pascal ppc386.exe ftp://ftp.freepascal.org/pub/fpc/dist/2.6.4/bootstrap/
Minimal rtl in mrtl.zip for inline asm test.
;API heaapi.sdk XMASM 32 or QWORD if WIN64
HeapSize PROTO hHeap:HANDLE ,dwFlags:DWORD ,lpMem:XMASM