Delphi register 約定下,EAX/ECX/EDX 為易失性寄存器 (可自由使用);EBX/ESP/EBP/ESI/EDI 為非易失性,**被調用者必須保存並恢復**。違規會導致難以除錯的隨機崩潰。
| 類別 | 寄存器 | 用途 | 保存責任 |
|---|---|---|---|
| 易失性 | EAX, ECX, EDX | 參數傳遞、返回值、暫存 | 調用者保存 |
| 非易失性 | EBX, ESI, EDI, EBP, ESP | 基址、變址、堆疊幀 | 被調用者保存 |
function Fun(x: Integer): Integer;
asm
push ebx { 入棧保存原值 }
mov ebx, x { 使用 EBX }
inc ebx
mov @Result, ebx
pop ebx { 出棧恢復原值 }
end;
procedure TForm1.Button1Click(Sender: TObject);
var i: Integer;
begin
i := Fun(8);
ShowMessage(IntToStr(i)); { 9 }
end;
asm
push ebx
push esi
push edi
{ 使用 EBX/ESI/EDI }
pop edi
pop esi
pop ebx { 逆序恢復 }
end;
Delphi 編譯器在函數序言/尾聲自動插入非易失性寄存器保存代碼。**手寫組合代碼時必須手動維護**,否則破壞調用約定。
RET 崩潰