2008-09-15 23 views
2

Vous écrivez une fonction et, en regardant l'assemblage qui en résulte, vous voyez qu'il peut être amélioré.Réorganisation du code dissemblé

Vous souhaitez conserver la fonction que vous avez écrite, pour plus de lisibilité, mais vous souhaitez remplacer votre propre assemblage par celui du compilateur. Y a-t-il un moyen d'établir une relation entre votre fonction de langage à haute affinité et la nouvelle assemblée?

Répondre

3

Si vous regardez l'assemblage, alors il est juste de supposer que vous comprenez bien comment le code est compilé. Si vous avez cette connaissance, alors il est parfois possible de «reverse engineering» les changements de sauvegarder dans la langue d'origine, mais il est souvent préférable de ne pas déranger.

Les optimisations que vous effectuez sont susceptibles d'être très petites par rapport au temps et à l'effort requis pour effectuer ces modifications. Je suggère que vous laissiez ce genre de travail au compilateur et que vous preniez une tasse de thé. Si les changements sont importants et que les performances sont critiques (comme dans le monde embarqué), vous pouvez mélanger le code normal avec l'assembleur, mais sur la plupart des ordinateurs et des puces, la performance est généralement suffisante pour éviter ce mal de tête.

Si vous vraiment besoin de plus de performances, puis optimiser le code pas l'ensemble.

2

Aucun, je suppose. Vous avez rejeté le travail du compilateur en faveur du vôtre. Vous pourriez aussi bien jeter la fonction que vous avez écrite dans le langage compilé, parce que maintenant tout ce que vous avez est votre assembleur dans cette plate-forme.

Je vous déconseillerais fortement de vous engager dans ce genre d'optimisation, car à moins d'être certain, grâce au profilage et à l'analyse, que vous faites réellement la différence.

1

Cela dépend de la langue dans laquelle vous avez écrit votre fonction. Certaines langues comme C sont de très bas niveau, traduisant chaque appel ou instruction de fonction vers des instructions d'assemblage spécifiques. Si vous avez utilisé C, vous pouvez remplacer votre fonction par un assemblage en ligne pour améliorer les performances.

D'autres langages de haut niveau peuvent convertir chaque instruction en macro-routines ou en d'autres appels plus complexes du côté de l'assemblage. Certaines optimisations (comme la récursivité de la queue, le déroulement de la boucle, etc.) peuvent être facilement implémentées du côté source, mais d'autres (comme utiliser plus efficacement le fichier registre) peuvent être impossibles (encore une fois selon le langage et le compilateur en utilisant).

1

Il est difficile de dire qu'il existe une relation entre l'assemblage modifié et la source qui a généré la version non modifiée. Il va certainement confondre les outils de débogage: le contenu du registre ne correspondra plus aux variables sources auxquelles ils étaient supposés correspondre.

Il y a un certain nombre d'endroits dans le code de traitement de paquets où j'ai examiné l'assemblage généré et je suis retourné pour changer le code source original afin d'améliorer le résultat. La réorganisation de la source peut réduire le nombre de branches, __attribute__ et les arguments du compilateur peuvent aligner les points de branchement et les fonctions pour réduire les échecs. Dans des cas désespérés, un petit assemblage en ligne peut être utilisé, de sorte que le binaire peut encore être compilé à partir de la source.

1

Quelque chose que vous pourriez essayer est de séparer votre fonction d'origine dans son propre fichier, et fournir une règle make pour construire l'assembleur à partir de là. Ensuite, mettez à jour le fichier assembleur avec votre version améliorée et fournissez une règle make pour créer un fichier objet à partir du fichier assembleur. Ensuite, changez vos règles de lien pour inclure ce fichier objet.

Si vous modifiez uniquement le fichier assembleur, celui-ci continuera à être utilisé.Si jamais vous modifiez le fichier de langue de niveau supérieur d'origine, le fichier assembleur sera reconstruit et le fichier objet sera créé à partir de la nouvelle version (non améliorée).

Cela vous donne une relation entre les deux; vous voulez probablement ajouter un commentaire d'avertissement en haut du fichier de langage de niveau supérieur pour avertir du comportement. L'utilisation d'une certaine forme de VCS vous donnera la possibilité de récupérer le fichier assembleur amélioré si vous faites une erreur ici.

1

Si vous écrivez une application native compilé dans Visual C++, il existe deux méthodes:

  1. Utilisez le bloc __asm { } et écrivez votre assembleur là-dedans.
  2. Ecrivez vos fonctions dans l'assembleur MASM, assemblez-les en .obj et liez-les en tant que bibliothèque statique. Dans votre code C/C++, déclarez la fonction avec une déclaration extern "C".

D'autres compilateurs C/C++ ont des approches similaires.

1

Dans cette situation, vous avez généralement deux options: optimiser le code ou réécrire le compilateur. Je ne peux pas voir où briser le lien entre la source et l'op va jamais être la bonne solution.