ポインタを使用したコードは、パスカルで議会に、翻訳 - デルファイ

StackOverflow https://stackoverflow.com/questions/2173570

質問

私は以下のコードを持っている、と私はあまりにも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;を試してみてください。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top