Question

Je suis à l'aide de Delphi 2010.Est-il possible de dire à Delphes pour ne pas générer un prologue pour une fonction?Je suis en train d'écrire quelques pur assemblage de fonctions comme ceci:

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

et je voudrais dire à Delphi de ne pas générer un prologue et un épilogue pour cette fonction, comme le C++ __declspec(naked) fonctionnalité.

Et afin que personne ne perd leur temps, je n'ai pas besoin d'obtenir de l'aide de ces fonctions de travail avec le prologue;Je peux déjà le faire.C'est juste un gros inconvénient et faire de l'entretien un énorme problème.Je vais inspecter manuellement les prologues généré par le compilateur pour voir leur longueur, et si cela change, mon programme va planter.

Je sais aussi que je peux écrire la fonction comme une série d'octets dans un tableau d'octets, mais ce serait encore pire que de devoir aller trouver la longueur de Delphi prologue.

Était-ce utile?

La solution

Delphi ne génère pas de prologues ou epilogues pour les fonctions ayant pas d'arguments et déclarée auprès de la registre convention d'appel.Si vous voulez fonctions sans prologues, de les déclarer comme zéro argument, inscrivez-appel-convention de fonctions.Aussi, sautez la begin-end bloc et aller tout droit dans l'assemblée.

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

Depuis, vous êtes effectivement menti à propos de la nature des fonctions, les appelant peut être délicat.Si vous avez implémenté une fonction que si elle a reçu paramètres et utilisé une autre convention d'appel, alors vous devrez assurez-vous que le compilateur sait à ce sujet sur le site d'appel.Pour ce faire, déclarer un pointeur de fonction qui reflète le type "réel" de votre fonction au lieu de le type déclaré.Par exemple, si votre fonction est vraiment un deux-argument stdcall fonction, déclarer quelque chose comme ceci:

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

Maintenant, attribuer cette variable qui pointe à votre fonction:

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

En plus de sauter le prologue et l'épilogue, le compilateur va générer incorrect RET l'instruction de cette fonction (en raison des différences de convention d'appel), de sorte que vous aurez à vous assurer que vous dites ret 8 dans votre code, au lieu de laisser le compilateur par défaut ret l'instruction se produire.


Trouver la longueur de Delphi prologue est trivial, si vous avez un travail débogueur:

  1. Définissez un point d'arrêt au début de la fonction.
  2. Appel de la fonction.
  3. Lorsque le débogueur s'arrête au point d'arrêt, l'interrupteur de l'UC de vue.
  4. Regardez les instructions qui composent le prologue.
  5. Compter les octets affichés à côté de ces instructions.

Autres conseils

Selon l' cette embarcadero docwiki vous pouvez ignorer les environs begin et end et le compilateur va sauter certains de ses trucs.Mais si vous voulez vraiment de la pure assembleur, pourquoi ne pas mettre votre fonction dans un autre fichier assembleur, l'assembler avec tasm (l'exe est nommé tasm32) et un lien vers elle.Vous pourrez ensuite utiliser le assembler la directive dans le code delphi.

ne

procedure SomeAssembly; stdcall;
asm
    ...
end;

faire le tour?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top