4

Visual C++ 2012 で記述されたプログラムがあり、Delphi で記述された関数 (ソース コードはありません) を呼び出そうとしました。Visual C++ のコードは次のとおりです。

int (_fastcall *test)(void*) = (int(_fastcall *)(void*))0x00489A7D;

test((void *)0x12345678);

しかし、コンパイルされたコードでは、実際には次のようになりました。

.text:1000113B                 mov     eax, 489A7Dh
.text:10001140                 mov     ecx, 12345678h
.text:10001145                 call    eax

そして、私が例外としているのは:

.text:1000113B                 mov     ebx, 489A7Dh
.text:10001140                 mov     eax, 12345678h
.text:10001145                 call    ebx

「fastcall」がパラメータとして EAX、ECX、EDX を使用することは知っていますが、Visual C++ コンパイラが EAX をエントリ ポイントとして使用する理由がわかりません。EAX を最初のパラメーター (12345678h) にするべきではありませんか?

アセンブリ コードで delphi 関数を呼び出そうとしましたが、機能しますが、アセンブリを使用せずにそれを行う方法を本当に知りたいです。

Visual C++ コンパイラに、私が例外としてコードを生成させることは可能ですか? はいの場合、それを行う方法は?

4

1 に答える 1

13

x86 での Delphi のレジスタ呼び出し規約は、Borland fastcall とも呼ばれ、 EAX、EDX、および ECX レジスタをこの順序で使用します。

ただし、Microsoft の fastcall 呼び出し規則では、異なるレジスタが使用されます。EAX をまったく使用しません。代わりに、ドキュメントで説明されているように、最初の 2 つのパラメーターに ECX および EDX レジスターを使用します。

したがって、その情報を使用して、パラメータをレジスタregisterに移動することにより、C++ からDelphi 関数呼び出しを行うアセンブラをおそらく作成できます。EAXただし、Delphi コンパイラに任せたほうがはるかに簡単です。特に、あなたの本当の問題には複数の関数と複数のパラメーターが関係していると思います。

stdcallと の間で適応する Pascal コードを作成することをお勧めしますregister

function FuncRegister(param: Pointer): Integer; register; external '...';

function FuncStdcall(param: Pointer): Integer; stdcall;
begin
  Result := FuncRegister(param);
end;

exports
  FuncStdcall;

次にFuncStdcall、C++ コードから呼び出して、Delphi コンパイラにパラメータの受け渡しを処理させることができます。

于 2013-03-11T15:22:18.790 に答える