覚書き。
Delphiでインラインアセンブラを使うときの呼出規約と引数のレジスタへの格納について。
試したのはDelphi2009。
デフォルトがfastcallなのは知ってたけど、それ以外をよく知らなかったので調べてた。
calling_convention.dpr
program calling_convention; {$APPTYPE CONSOLE} (* fastcall(register) Delphiの場合は最初の3つの引数はEAX, EDX, ECXレジスタに格納される 戻り値はEAX *) function Sub1(a, b: Integer): Integer; asm SUB EAX, EDX end; (* cdecl スタックに引数は右から順に格納される 戻り値はEAX *) function Sub2(a, b: Integer): Integer; cdecl; asm PUSH EBP MOV EBP, ESP MOV EAX, DWORD PTR [EBP + 12] SUB EAX, DWORD PTR [EBP + 16] POP EBP end; (* stdcall 呼び出し側がスタックに引数を格納する 戻り値はEAX *) function Sub3(a, b: Integer): Integer; stdcall; asm MOV EAX, DWORD PTR [EBP + 8] SUB EAX, DWORD PTR [EBP + 12] end; (* 7 - 3の計算 *) begin WriteLn(Sub1(7, 3)); WriteLn(Sub2(7, 3)); WriteLn(Sub3(7, 3)); end.
実行結果
C:\work\_sandbox\calling_convention>dcc32 calling_convention.dpr CodeGear Delphi for Win32 コンパイラ version 20.0 Copyright (c) 1983,2008 CodeGear calling_convention.dpr(39) 40 行, 0.03 秒, コード 13216 バイト, データ 13036 バイト C:\work\_sandbox\calling_convention>calling_convention 4 4 4