I have this code below, and I want to translate it to ASM, to use in Delphi too.
var
FunctionAddressList: Array of Integer;
type TFunction = function(parameter: Integer): Integer; cdecl;
function Function(parameter: Integer): Integer;
var
ExternFunction: TFunction;
begin
ExternFunction := TFunction(FunctionAddressList[5]);
Result := ExternFunction(parameter);
end;
It works normaly, but when I try its Assembly version:
function Function(parameter: Integer): Integer; cdecl;
asm
mov eax, FunctionAddressList
jmp dword ptr [eax + 5 * 4]
end;
It is supposed to work, because, in C++ it works in both ways:
void *FunctionAddressList;
_declspec(naked) int Function(int parameter)
{
_asm mov eax, FunctionAddressList;
_asm jmp dword ptr [eax + 5 * 4];
}
typedef int (*TFunction)(int parameter);
int Function(int parameter)
{
TFunction ExternFunction = ((TFunction *)FunctionAddressList)[5];
return ExternFunction(parameter);
}
But it doesn’t work in Delphi.
In the Assembly version, it multiplies the array to 4, because it’s the offset size between each element of the array, so both versions are equivalent.
So, I want to know why it doesn’t work with Delphi. In Delphi, the offset size between Integer values in a array is different than C++?
I’ve already tried many offsets, as 1, 2, 4, 6, 8, etc. And many types of Array (Array of Pointer; only Pointer; Array of Integer, etc), and I’ve tried many calling conventions, and cdecl was the only that worked with the non-asm version, but with ASM, all the tests didn’t work.
Thanks.
First test app to reproduce error:
The Bar address is defined correctly, but the problem is that Delphi compiler generates prologue and epilog for Foo, so real Foo code is
As a result the stack is corrupted, the parameter is wrong and Bar return address is wrong. If you still want to do the trick, use