Domanda

Sto usando Delphi 2010. È possibile dire a Delphi di non generare un prologo per una funzione? Sto scrivendo alcune funzioni di assemblaggio puro come questa:

procedure SomeAssembly; stdcall;
begin
    asm
        ...
    end;
end;

E vorrei dire a Delphi di non generare un prologo ed epilogo per questa funzione, come C ++ __declspec(naked) caratteristica.

E quindi nessuno spreca il loro tempo, non ho bisogno di aiuto per far funzionare queste funzioni insieme a il prologo; Posso già farlo. È solo un grande inconveniente e renderà la manutenzione un enorme seccatura. Dovrò ispezionare manualmente i prologhi generati dal compilatore per vedere la loro lunghezza e, se questo cambia, il mio programma si schianterà.

So anche di poter scrivere la funzione come una serie di byte in un array di byte, ma sarebbe anche peggio che dover andare a trovare la lunghezza del prologo di Delphi.

È stato utile?

Soluzione

Delphi non genera prologue o epiloghi per le funzioni Nessun argomento e dichiarato con il Registrati Chiamare la convenzione. Se si desidera funzioni senza prologhi, dichiararle come funzioni di allegria a calo di registrazione. Inoltre, salta il begin-end Bloccare e andare direttamente in montaggio.

procedure SomeAssembly; // register; (implied)
asm
  // ...
end;

Dal momento che stai effettivamente mentendo sulla natura delle funzioni, chiamarle può essere complicato. Se hai implementato una funzione come se avesse ricevuto parametri e utilizzato una diversa convenzione di chiamata, dovrai assicurarti che il compilatore lo sappia nel sito di chiamata. Per fare ciò, dichiarare un puntatore di funzione che riflette il tipo "reale" della tua funzione anziché il tipo dichiarato. Ad esempio, se la tua funzione è davvero una funzione stdcall a due argomenti, dichiara qualcosa del genere:

type
  TSomeAssemblyFunc = function (Arg1: Integer; Arg2: PAnsiChar): Boolean; stdcall;
var
  SomeAssemblyProc: TSomeAssemblyProc;

Ora, assegna quella variabile in modo che punta alla tua funzione:

SomeAssemblyProc := TSomeAssemblyProc(@SomeAssembly);
if SomeAssembly(2, 'foo') then ...

Oltre a saltare il prologo e l'epilogo, il compilatore genererà il errato RET istruzioni per questa funzione (a causa della diversa convenzione di chiamata), quindi dovrai assicurarti di dire ret 8 nel tuo codice invece di lasciare il default del compilatore ret si verificano istruzioni.


Trovare la durata del prologo di Delphi è banale, se hai un debugger funzionante:

  1. Imposta un punto di interruzione all'inizio della funzione.
  2. Chiama la funzione.
  3. Quando il debugger si interrompe al punto di interruzione, passare alla vista CPU.
  4. Guarda le istruzioni che compongono il prologo.
  5. Contare i byte visualizzati accanto a quelle istruzioni.

Altri suggerimenti

Secondo il Questo Embarcadero Docwiki puoi saltare l'ambiente circostante begin e end E il compilatore salterà alcune delle sue cose. Ma se vuoi davvero un assemblatore puro, perché non inserire la funzione in un file di assemblatore separato, assemblalo con tasmo (l'EXE è chiamato TASM32) e collegarlo ad esso. Quindi userai il assembler Direttiva nel codice Delphi.

No

procedure SomeAssembly; stdcall;
asm
    ...
end;

fare il trucco?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top