ポインタを使用したコードは、パスカルで議会に、翻訳 - デルファイ
質問
私は以下のコードを持っている、と私はあまりにもDelphiで使用するために、ASMにそれを翻訳したい。
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;
それはnormaly動作しますが、私はそのアセンブリのバージョンをしようとすると:
function Function(parameter: Integer): Integer; cdecl;
asm
mov eax, FunctionAddressList
jmp dword ptr [eax + 5 * 4]
end;
、C ++で、それは両方の方法で動作するため、はそれは、仕事になっています:
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);
}
しかし、それはないんDelphiで仕事ます。
は、配列の各要素間のオフセットサイズなので、両方のバージョンが等価であるので、アセンブリのバージョンでは、それは、4にアレイを乗算します。
だから、私はそれがDelphiで動作しない理由を知りたいです。 Delphiで、アレイ内の整数値の間のオフセットの大きさは、C ++
とは異なりますは、私はすでに多くのオフセットを試し、1、2、4、6、8、など、アレイの多くの種類(ポインタのアレイとポインタのみ、整数のアレイ、等)として、私は多くを試みました呼び出し規約、およびCDECLは、非ASMのバージョンで働いていただけということだったが、ASMで、すべてのテストが動作しませんでした。
感謝します。
解決
再生エラーへの最初のテストアプリます:
var
FunctionAddressList: Array of Integer;
function Bar(parameter: Integer): Integer; cdecl;
begin
ShowMessage('Bar '+IntToStr(parameter));
end;
function Foo(parameter: Integer): Integer; cdecl;
asm
mov eax, FunctionAddressList
jmp dword ptr [eax + 5 * 4]
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
SetLength(FunctionAddressList, 6);
FunctionAddressList[5]:= Integer(@Bar);
Foo(25);
end;
はバーアドレスが正しく定義されているが、問題は、実際のFooのコードは
であるので、Delphiコンパイラは、Fooのためのプロローグとエピローグを生成していることです0046CD30 55 push ebp
0046CD31 8BEC mov ebp,esp
Unit1.pas.46: mov eax, FunctionAddressList
Unit1.pas.47: jmp dword ptr [eax + 5 * 4]
0046CD3B 5D pop ebp
0046CD3C C3 ret
は、スタックが破損している結果として、パラメータが間違っているとバーのリターンアドレスが間違っています。あなたはまだトリックを行いたい場合は、使用
function Foo(parameter: Integer): Integer; cdecl;
asm
pop ebp
mov eax, FunctionAddressList
jmp dword ptr [eax + 5 * 4]
end;
他のヒント
Array of Integer
は、あなたがそれだと思うものではありません。これは、自動的に管理動的配列です。
あなたはそれを用いFunctionAddressList: ^Pointer;
を試してみてください。
所属していません StackOverflow