この質問はpreviousに基づいて、それはちょうどFYIですされています。私はそれが働いて得ることができました呼び出しオブジェクトメソッドASMを使用 - パート2
、しかし、私は私にははっきりしていない何かを見つけたので、誰もが次の動作を説明することができれば、それは素晴らしいだろう。
私は次のクラスがあります。
type
TMyObj = class
published
procedure testex(const s: string; const i: integer);
end;
procedure TMyObj.testex(const s: string; const i: integer);
begin
ShowMessage(s + IntToStr(i));
end;
と次の2つの手順:作業バージョンをテストするために
procedure CallObjMethWorking(AMethod: TMethod; const AStrValue: string; const AIntValue: Integer);
begin
asm
PUSH DWORD PTR AIntValue;
PUSH DWORD PTR AStrValue;
CALL AMethod.Code;
end;
end;
procedure CallObjMethNOTWorking(AInstance, ACode: Pointer; const AStrValue: string; const AIntValue: Integer);
begin
asm
MOV EAX, AInstance;
PUSH DWORD PTR AIntValue;
PUSH DWORD PTR AStrValue;
CALL ACode;
end;
end;
を、一つは次のようにコールする必要があります。
procedure ...;
var
LObj: TMyObj;
LMethod: TMethod;
LStrVal: string;
LIntVal: Integer;
begin
LObj := TMyObj.Create;
try
LMethod.Data := Pointer(LObj);
LMethod.Code := LObj.MethodAddress('testex');
LStrVal := 'The year is:' + sLineBreak;
LIntVal := 2012;
CallObjMethWorking(LMethod, LStrVal, LIntVal);
finally
LObj.Free;
end; // tryf
end;
とテストするためにNOTイオン:
procedure ...;
var
LObj: TMyObj;
LCode: Pointer;
LData: Pointer;
LStrVal: string;
LIntVal: Integer;
begin
LObj := TMyObj.Create;
try
LData := Pointer(LObj);
LCode := LObj.MethodAddress('testex');
LStrVal := 'The year is:' + sLineBreak;
LIntVal := 2012;
CallObjMethNOTWorking(LData, LCode, LStrVal, LIntVal);
finally
LObj.Free;
end; // tryf
end;
そして最後の質問:なぜ作業をCallObjMethNOTWorkingないされ、CallObjMethWorkingがありながら?私は、コンパイラがTMethodをどのように処理するかについて特別なことがあると推測しています...しかし、アセンブリの知識は限られているので、理解できません。
誰かが私にこのことを説明できるかどうか非常に感謝します、ありがとう!
3つのパラメータがレジスタに渡されます。スタックがどこにあるのか分かりません。あなたは、デルファイ言語ガイドのプログラムコントロールセクションを読んだことがありますか? –
@David、私はちょうど、それは私がPUSH EAX、MOV EDX、DWORD PTR AStrValueと呼ぶと思われます。 MOV ECX、DWORD PTR AIntValue; ACodeを呼び出します。 (実行後の)例外を発生させることを除いては、完全に動作します...文字列はすでに参照渡しと値渡しの整数になっていますが、まだ取得できません。 – ComputerSaysNo
なぜあなたは押していますかEAX?なぜメソッドを呼び出すためにasmを使用する必要がありますか? –