德爾福不生成功能的序言或結尾沒有參數和宣佈與註冊調用約定。如果你想要沒有序言的函數,把它們聲明爲零參數,register-calling-convention函數。此外,跳過begin
- end
區塊並直接進入裝配。
procedure SomeAssembly; // register; (implied)
asm
// ...
end;
由於您對功能的性質進行了有效的說明,調用它們可能會很棘手。如果您已經實現了一個函數,就像它接收到參數並使用了不同的調用約定,那麼您必須確保編譯器在調用站點上知道這一點。爲此,請聲明一個反映您的函數的「真實」類型而不是聲明類型的函數指針。例如,如果你的函數真的是兩個參數STDCALL功能,聲明是這樣的:
type
TSomeAssemblyFunc = function (Arg1: Integer; Arg2: PAnsiChar): Boolean; stdcall;
var
SomeAssemblyProc: TSomeAssemblyProc;
現在,所以它指向你的函數分配一個變量:
SomeAssemblyProc := TSomeAssemblyProc(@SomeAssembly);
if SomeAssembly(2, 'foo') then ...
除了跳繩序言和尾聲,編譯器將爲此函數生成不正確的RET
指令(因爲調用約定不同),所以您必須確保在代碼中說明ret 8
,而不是讓編譯器的默認ret
指令發生。
找到德爾福的開場白的長度是微不足道的,如果你有一個工作的調試器:
- 在函數的開始設置一個斷點。
- 調用該函數。
- 當調試器停在斷點處時,切換到CPU視圖。
- 看看組成序幕的指示。
- 計算這些指令旁顯示的字節數。
爲什麼所有人都不能這樣回答?非常有幫助,謝謝Rob。 – 2011-03-27 17:41:56
@K。 Charles:不同程度的專業知識?這是一個瘋狂的猜測,但沒有任何人打算冒犯任何人。 – 2011-03-27 17:53:43
當你有函數指針時,沒有額外的間接級別嗎?我個人認爲tasm會更適合。 – 2011-03-27 18:08:48