Interface Python/Assembleur

Méthodes à employer ?

Le problème exposé dans ce sujet a été résolu.

Bonjour, zesteurs zé zesteuses !

C'est juste une petite question "conceptuelle" sur la manière de faire la chose en question. J'ai déjà touché (très légèrement) à l'interface bare-bone C/Python (autrement dit l'API C de Python). Par interface j'entends:

  • Embarquer l'interpréteur python
  • Ecrire un module dans le langage X exploitable par un programme python

Donc "dans les 2 sens". Et comme j'adore me compliquer la vie, j'aime bien faire "dans les 2 sens" dans un même programme. Bref, la question est:

Est-il possible de réaliser une telle interface, non pas entre le C/C++ et Python, mais entre l'assembleur et Python ?

Sachant que la méthode d'interfaçage proposée doit être:

  • relativement simple (relativement simple = au maximum 1.5x plus compliqué à mettre en oeuvre que l'interface C/Python)
  • dans ces solutions relativement simple, le plus bas-niveau possible (on parle quand même d'assembleur)

Ce à quoi j'ai déjà pensé, c'est:

  • Tout faire en assembleur avec les fonctions/objets de l'API C de Python.
    • trop complexe à mettre en oeuvre il me semble, dû aux spécificités propres à chaque compilateur (par exemple l'ordre de passage des paramètres aux fonctions, qui nettoie les arguments après …), et au boxon que ça risque d'être pour l'accès aux objets.
  • Avoir une couche intermédiaire en C qui appelle le code Python ou appelle le code asm.
    • ça revient à avoir un programme C avec Python et quelques trucs écrits en assembleur, finalement on perd le côté "Python et Asm", c'est un code C au final.

Vos idées ?

+0 -0

Je suis pas trop surs de voir ce que tu veux faire. En soit en C tu peux injecter autant d'ASM que tu veux (le mot clé asm est là pour ça). Après on peut envisager des trucs plus drôle. Par exemple certains font des modules permetant d'appeler du code ASM depuis Python ou compilent du Python en ASM. Enfin intégré l'interpréteur Python dans une "application asm" reviendra en gros à faire la même chose qu'en C et utiliser son API C depuis l'ASM.

Au passage :

  • Tout faire en assembleur avec les fonctions/objets de l'API C de Python.

    • trop complexe à mettre en oeuvre il me semble, dû aux spécificités propres à chaque compilateur (par exemple l'ordre de passage des paramètres aux fonctions, qui nettoie les arguments après …),

En réalité c'est plutôt spécifique à l'OS qu'aux compilateurs. Sur un OS donné, la très large majorité des compilateurs C ont des ABI compatibles.

+0 -0

En réalité c'est plutôt spécifique à l'OS qu'aux compilateurs. Sur un OS donné, la très large majorité des compilateurs C ont des ABI compatibles.

Oui c'est vrai, désolé grosse bourde.

Je suis pas trop surs de voir ce que tu veux faire.

Je vais tenter d'être plus clair, parce qu'en fait tes possibilités répondent à la question, mais pas à ce que je veux faire :euh: .

J'ai un module python, et un code asm. Les 2 sont dans des fichiers séparés, et je veux qu'ils "se causent" (dans les 2 sens si possible, si non c'est pas si grave). Donc l'asm dans le code C, ça ne me convient pas (je ne suis pas fan de la syntaxe AT&T, je préfère l'intel, avec un p'tit fasm), mais pour cette partie-là je sais faire.

Pyasm est intéressant (je suppose qu'il y a de quoi lire un fichier asm plutôt que le mettre direct dans le code python), mais je ne souhaite pas l'assembler run-time, je souhaite, comme avec l'API C, avoir un binaire que j'utilise comme module python.

Enfin intégré l'interpréteur Python dans une "application asm" reviendra en gros à faire la même chose qu'en C et utiliser son API C depuis l'ASM.

Oui, mais je crains de n'avoir ni les capacités cognitives ni la patience nécéssaire pour gérer les PyObject directement en assembleur. Donc je suis preneur de solutions plus intelligentes, même si elles sont un peu plus haut-niveau.

+0 -0

Donc il n'y a pas de solution diablement intelligente que j'aurais complètement loupé ?

Normalement tu dois pouvoir faire communiquer les deux sans grande difficultés en les liants.

Je vois ça comme ça : si on imagine un module Python écrit en assembleur, j'ai en C la constitution du module avec la fonction qui choppe l'appel de Python (avec les arguments à "dépiler"), et je rebalance le tout dans la fonction assembleur.

Question : je n'y connais franchement pas grand chose sur la surcharge de fonctions, la meta-programmation, les templates, bref les trucs évolués du C++.

Il y aurait il un moyen de faire correspondre la fonction vue par Python (celle qui "dépile" en C) avec la fonction en asm ? Je veux dire par là avoir un prototype générique de fonction qui "dépile" les arguments, puis appelle la fonction asm du même nom plus un préfixe/suffixe.

Un simple oui ou non suffit, après je me débrouille tout seul.

Merci !

+0 -0

:euh: Mince …

si tu peux le faire en C, tu le fera en asm.

Oui mais avec quelle difficulté ? C'est un peu ça le problème.

Exemple : pour afficher une chaîne de caractère.

J'ai 2 solutions:

  • fonctions C
  • appels système

Et bien, honnêtement, je trouve plus simple l'appel système, parce que je n'ai pas à me taper tout les passages d'arguments : en appel système, les args sont claqués dans les registres, pas dans la pile, donc je n'ai pas à me soucier de l'ordre d'empilement des arguments, ni (dans le cas de linux) du nettoyage des arguments par la suite.

Concernant ceci :

Il y aurait il un moyen de faire correspondre la fonction vue par Python (celle qui "dépile" en C) avec la fonction en asm ? Je veux dire par là avoir un prototype générique de fonction qui "dépile" les arguments, puis appelle la fonction asm du même nom plus un préfixe/suffixe.

Imaginons qu'il y ait 200 fonctions écrites en assembleur que je souhaites rendre accessible à Python.

Je ne me vois pas manipuler directement les PyObject et autre joyeuseté directement en assembleur. Du coup, en assembleur j'ai 200 fonctions qui prennent des arguments "normaux", donc des entiers, des chaînes de caractères, des entiers courts …

Du coup, dans le code C de l'interface, j'ai 200 déclarations de fonctions : celles faites en assembleur, et 200 autres fonctions, déclarées et définies, qui réalisent ces 3 seules actions:

  • décompacter l'objet Python passé par l'interpréteur, pour retrouver des arguments "normaux"
  • appeler la fonction assembleur avec ces arguments
  • recompacter le retour pour qu'il puisse être exploitable par l'interpréteur Python

Donc, ma question sur la fonction "générique" était : est-ce qu'il y a un moyen de passer de 200 définitions de fonctions à une seule ? Je suis d'accord que je peux factoriser le code de décompactage/compactage dans 2 fonctions qui sont appelées par toutes les autres, mais il reste le problème de l'appel à la fonction assembleur, et je ne sais pas s'il est possible de le factoriser.

Pour faire ça (tout faire en une seule fonction), on pourrait imaginer qu'on appelle en Python une fonction générique, à laquelle on passe en paramètre le nom de la fonction que l'on souhaite rééllement avoir.

Du coup, en C, j'ai une seule fonction définie qui décompacte les arguments, et appelle la fonction qui a pour nom le premier argument.

Sauf que voilà, je ne sais absolument pas s'il est possible de faire ce genre de choses (passer d'un chaîne de caractère à un appel dans le code) simplement (parce que faire 200 if …).

Pour revenir à ceci:

De façon général, si tu peux le faire en C, tu le fera en asm.

En gros, ce qui est faisable pour moi (vu mon niveau technique actuel), c'est d'appeler des fonctions C toutes bêtes, c'est-à-dire avec des arguments de type simple. Après, je ne l'ai encore jamais fait, mais je dois pouvoir me débrouiller pour aussi passer des structures (là aussi composées de types simples, des structures de structures n'est pas franchement envisageable). Mais s'il faut que je gère en plus des objets de taille variable, là je vais pleurer :lol: .

Kje, ça me va de faire un "traducteur" en C, mais je pensais qu'il y avait des solutions plus simples ou plus élégantes. Bon après, c'est sûr que du Python/Asm, ça vise un public restreint …

Il n'empêche que si je pouvais rendre ce "traducteur" le plus light possible, je serais heureux.

Et merci d'avoir pris le temps de me répondre !

+0 -0

J'ai pas le temps de répondre plus complètement, il faudrait que je relise ton message, mais en attendant j'ai l'impression que ce que tu veux faire c'est un truc qui ressemblerait, en python :

1
2
3
import monModule as m   # Ton module de glu

m.call_function("toto", 1, 2) # appel la fonction toto de ton module asm avec les arguments 1 et 2

si c'est ça, plusieurs solutions :

  • le module de glu tu le fais en C. Ça devient un problème de C et non de Python. Tu dois faire des appels de fonctions a partir d'un nom de fonction qui est une chaîne de caractère. Ça fait longtemps que j'ai pas fais ça mais si tout ton code assembleur est dans une bibliothèque dynamique (dll sous windows, so sous linux) et qu'il a une interface compatible C, tu devrais pouvoir t'en sortir avec dlsym sous linux (ou GetProcAddress sous windows).
  • Si ton module asm a une interface compatible C, en réalité ton module glu tu peux le faire en pur python avec ctypes qui contient tout pour appeler de tels bibliothèques et faire des conversions d'arguments (python <-> C).
+0 -0

En ayant lu rapidement les 2 liens que vous avez donné, j'allais éditer mon message, mais grillé :) .

A priori, je vais le faire avec ctypes dans un premier temps, puis ensuite avec une glu C, pour pouvoir embarquer l'interpréto python1. Avoir le code asm sans modifs pour les 2 versions, ça c'est le top !


  1. Ca fait un petit moment qu'un projet de programme (n'importe quoi en fait) modable me trotte dans la tête, et comme j'aime bien le python … 

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte