IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

x86 32-bits / 64-bits Assembleur Discussion :

[MASM32] Comment utiliser la fonction printf


Sujet :

x86 32-bits / 64-bits Assembleur

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    217
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 217
    Par défaut [MASM32] Comment utiliser la fonction printf
    Bonjours à tous!
    Il y a certains points que je ne comprend pas au niveau de l'inclusion de librairies et de fonctions :

    Comment permettre l'utilisation d'une fonction C, comme par exemple printf dans un programme assembleur 32 bits?
    Je sais qu'il faut l'appeler : "call _printf", et je connait les conventions d'appel, mais comment indiquer au compilateur qu'il s'agit d'une fonction externe? Faut-il rajouter "extern _printf" dans le segment de code, ou bien inclure un prototype au début du fichier : "_printf proto ???"?

    Ensuite, comment me procurer le fichier .lib qui contient la fonction précompilée? J'ai regardé dans le dossier lib de mon compilateur C, il n'y a pas de fichier "stdio.lib".

    Ensuite, comment montrer au linker dans quel fichier il doit rechercher la fonction précompilée?


    Ensuite, j'ai essayé d'utiliser les fonctions que propose masm, le compilateur que j'utilise.
    Le programme suivant, qui doit afficher une chaîne sur la console, ne fait strictement rien!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    .486
    .model flat, stdcall
    option casemap:none
     
    include \masm32\include\windows.inc
    include \masm32\include\kernel32.inc
    includelib \masm32\lib\kernel32.lib
    include \masm32\m32lib\masm32.inc
    includelib \masm32\m32lib\masm32.lib
     
    .data 
    Message   db "Message à afficher.",0 
     
    .code
    start:
        invoke StdOut, addr Message
     
        invoke ExitProcess, 0
    end start
    Aidez-moi, s'il vous plais, je suis désespéré!!!

  2. #2
    Membre éprouvé
    Avatar de Stormy_Ordos
    Profil pro
    Expert sécurité informatique
    Inscrit en
    Mars 2005
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Expert sécurité informatique

    Informations forums :
    Inscription : Mars 2005
    Messages : 91
    Par défaut
    Bonjour,

    Pourquoi vouloir absolument utiliser Printf pour écrire du texte? tu peux utiliser les fonctions standard du SDK Windows (WriteConsoleW et WriteConsoleA si mes souvenirs sont corrects). Tu peux downloader le SDK gratuitement (incroyable ) et aller faire un tour du côté de MSDN (Microsoft Developer's Network) pour trouver les prototypes. Ces fonctions s'utilisent sans problèmes avec Kernel32.lib et User32.lib.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    217
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 217
    Par défaut
    Tout à fait d'accord, il est possible d'utiliser les fonctions de l'API Windows, mais c'est aussi utile de savoir comment exploiter les fonctions C à partir d'assembleur et vice-versa.
    En plus, il faut bien dire qu'il n'y a pas et il n'y aura jamais plus pratique que printf en matière de sortie de texte.

    Sinon, au passage, une petite question : pourquoi en assembleur on dispose des fonctions WriteConsoleA, WriteConsoleW, MessageBoxA, MessageBoxW, ... alors qu'en C par exemple on peut utiliser les fonctions WriteConsole, MessageBox, ... sans spécifier quel format de chaine on utilise?

  4. #4
    Membre éprouvé
    Avatar de Stormy_Ordos
    Profil pro
    Expert sécurité informatique
    Inscrit en
    Mars 2005
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Expert sécurité informatique

    Informations forums :
    Inscription : Mars 2005
    Messages : 91
    Par défaut
    Probablement parce que les bibliothèques C utilisent des macros texte qui font pointer un terme plus générique comme WriteConsole soit vers WriteConsoleA (pour Win9x) soit vers WriteConsoleW (systèmes NT). Je pense que c'est une question de simplicité.

    il n'y aura jamais plus pratique que printf en matière de sortie de texte
    Faut voir, Write/Writeln est très sympa aussi .

  5. #5
    Membre éprouvé
    Avatar de Stormy_Ordos
    Profil pro
    Expert sécurité informatique
    Inscrit en
    Mars 2005
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Expert sécurité informatique

    Informations forums :
    Inscription : Mars 2005
    Messages : 91
    Par défaut
    J'ai fait une recherche Google, juste pour voir (toujours penser à google avant de poster), et j'ai trouvé juste ce que tu cherchais :
    Utiliser PROTO et INVOKE pour appeler printf à partir de MASM

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    217
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 217
    Par défaut
    Moi aussi, j'avais fait une recherche, mais j'avais rien trouvé.
    Enfin bref, j'ai ajouté le prototype de printf dans mon programme, et j'ai essayer de compiler.
    Mais là, ça va pas du tous, parce que pour utiliser les prototypes avec VARARG, il faut utiliser les conventions d'appel C, or pour utiliser l'API Windows, il faut utiliser les conventions Pascal ("stdcall" après la directive ".model").
    En gros, on ne peut pas utiliser en même temps une fonctions C avec invoke (qui requière un prototype) et une fonction de l'API. Donc, à moins qu'on puisse changer au beau milieu du programme les conventions d'appel, il faut se résoudre à utiliser call avec les fonctions C.

    Sinon, j'ai parcouru un peu les fichiers d'en-tête C des fonctions de l'API Windows (windows.h, winuser.h, ...) et j'ai remarqué qu'à chaque début de prototype, il y a le mot WINAPI. Ce serais pas ce qui permet au compilateur C de savoir qu'il faut utiser les conventions d'appel Pascal lors de l'appel de ces fonctions?

  7. #7
    Membre chevronné Avatar de dapounet
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2007
    Messages
    469
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2007
    Messages : 469
    Par défaut
    Lis la partie de ce tutorial sur les sous-programmes, c'est assez complet.

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    217
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 217
    Par défaut
    Il se trouve que j'ai déjà ce tutorial, et il n'est pas vraiment assez complet puisqu'il n'explique pas comment utiliser autre chose que les macros fournis avec.

    J'ai recherché dans les header-files et j'ai trouvé que CALLBACK tout comme WINAPI ne servent qu'à informer le compilateur de la convention d'appel utilisé : stdcall.

  9. #9
    Membre éprouvé
    Avatar de Stormy_Ordos
    Profil pro
    Expert sécurité informatique
    Inscrit en
    Mars 2005
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Expert sécurité informatique

    Informations forums :
    Inscription : Mars 2005
    Messages : 91
    Par défaut
    En gros, on ne peut pas utiliser en même temps une fonction C avec invoke (qui requiert un prototype) et une fonction de l'API. Donc, à moins qu'on puisse changer au beau milieu du programme les conventions d'appel, il faut se résoudre à utiliser call avec les fonctions C.
    Essaie de ne pas déclarer de conventions d'appel au départ (à propos, STDCALL est la convention d'appel Win32, pas Pascal) et de déclarer tes prototypes avec EXTERN.
    PROTO utilise automatiquement la convention d'appel déclarée, mais je ne suis pas sûr pour EXTERN.
    Puis, tu empiles tes arguments dans l'ordre inverse et enfin CALL.

  10. #10
    Membre chevronné Avatar de dapounet
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2007
    Messages
    469
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2007
    Messages : 469
    Par défaut
    Citation Envoyé par _Michel
    Il se trouve que j'ai déjà ce tutorial, et il n'est pas vraiment assez complet puisqu'il n'explique pas comment utiliser autre chose que les macros fournis avec.
    Pourtant au 4.7 il explique tout ce qu'il te faut, les registres à préserver, l'ordre d'empilement des paramètres etc. à part qu'il utilise NASM donc la syntaxe doit changer.

  11. #11
    Membre éprouvé
    Avatar de Stormy_Ordos
    Profil pro
    Expert sécurité informatique
    Inscrit en
    Mars 2005
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Expert sécurité informatique

    Informations forums :
    Inscription : Mars 2005
    Messages : 91

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    217
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 217
    Par défaut
    Merci pour les conventions d'appel, je crois que je comprend mieux.
    Maintenant, j'ai réussi à compiler un fichier obj à partir de ce code source :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    .486
    .model flat, stdcall
    option casemap:none
     
    include \masm32\include\windows.inc
    include \masm32\include\kernel32.inc
    includelib \masm32\lib\kernel32.lib
     
    _printf    PROTO C arg1:Ptr Byte, printlist: VARARG
     
    .data 
    Message   db "Message à afficher.",0 
     
    .code
    start:
        invoke _printf, addr Message
        invoke ExitProcess, 0
    end start
    Mais pour en faire un executable, je ne sais pas avec quoi linker.

    J'ai essayer de l'associer avec un fichier obj contenant le code suivant (en C) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #include <stdio.h>
     
    void AffichageMessage (char *ptr)
    {
    	printf ("%s", ptr);
    }
    et en remplacant bien entendu la fonction printf par la fonction AffichageMessage dans le fichier assembleur.

    Voila ce que me donne ilink32 (linker de bcc55):
    "Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
    Error: 'C:\ASM\CPUID\CPUID2.OBJ' contains invalid OMF record, type 0x4c (possibly COFF)"

    Et voila ce que me donne link (linker de masm32) :
    "Microsoft (R) Incremental Linker Version 5.12.8078
    Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

    affichage.obj : warning LNK4033: converting object format from OMF to COFF
    LINK : fatal error LNK1221: a subsystem can't be inferred and must be defined"

    Apparement, ils n'aiment pas top les .obj des autres compilateurs, mais c'est pourtant un format standard, non?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Excel] Comment utiliser la fonction RECHERCHEV
    Par forsay1 dans le forum Macros et VBA Excel
    Réponses: 17
    Dernier message: 03/02/2006, 11h43
  2. Réponses: 3
    Dernier message: 31/12/2005, 23h09
  3. Comment utiliser la fonction NBR.JOURS.OUVRES?
    Par MEHCOOPER dans le forum Access
    Réponses: 9
    Dernier message: 20/10/2005, 12h50
  4. [MASM32] Comment utiliser md5()
    Par sefo dans le forum x86 32-bits / 64-bits
    Réponses: 14
    Dernier message: 13/12/2004, 00h29
  5. Réponses: 11
    Dernier message: 22/12/2003, 21h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo