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 16-bits Assembleur Discussion :

Code asm à lier à un programme C [FAQ]


Sujet :

x86 16-bits Assembleur

  1. #1
    Futur Membre du Club
    Inscrit en
    Mai 2004
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 6
    Points : 7
    Points
    7
    Par défaut Code asm à lier à un programme C
    Bonjour je travaille sur des fichiers ASM qui ont un lien avec mon code en C dans mon programme. Et il y a certaine instructions que je ne comprend pas.

    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
     ;---------------------------------;
    ; Initialisation 8254 : It 10 ms  ;
    ;---------------------------------;
     
    ;
    ; Initialisation des timers
    ;  Appel De La Procedure En C :
    ;     void Init8254s ();
    ;
     
        PUBLIC _Init8254s
     
    _Init8254s proc near
     
    	mov	dx,TMR_CWR
    	mov	al,36h
    	out	dx,al
     
    	mov	cx,10
    	loop	$	
     
    	mov	dx,TMR_CNT0	; timer 0 = pulse 1 microsec.
    	mov	al,08
    	out 	dx,al
     
    	mov	cx,10
    	loop	$	
     
    	mov	al,00
    	out 	dx,al
    ;
    	mov	cx,10
    	loop	$	
     
    	mov	dx,TMR_CWR
    	mov	al,74h
    	out	dx,al
     
    	mov	cx,10
    	loop	$	
     
    	mov	dx,TMR_CNT1	; timer 1 = pulse 10 millisec.
    	mov	al,10h
    	out 	dx,al
     
    	mov	cx,10
    	loop	$	
     
    	mov	al,27h
    	out 	dx,al
    ;
    	mov	cx,10
    	loop	$	
     
    	mov	dx,TMR_CWR
    	mov	al,0B7h
    	out	dx,al
     
    	mov	cx,10
    	loop	$	
     
    	mov	dx,TMR_CNT2	; timer 2 = pulse 10 millisec.
    	mov	al,10h
    	out 	dx,al
     
    	mov	cx,10
    	loop	$	
     
    	mov	al,27h
    	out 	dx,al
     
      ret
     
    _Init8254s endp
    Je ne vois pas à quoi correspondent les "$" ainsi que PUBLIC _Init8254s et _Init8254s proc near

    Merci de bie vouloir m'éclairer.

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    842
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 842
    Points : 696
    Points
    696
    Par défaut
    Ce code définit une fonction _Init8254s, qui est destinée à être utilisée dans un code C. Concrètement, et techniquement pour que la fonction puisse être exportée et utilisée dans un code C, il n'y a juste qu'a dire au lieur, "voilà, c'est ici que la fonction commence". A la liaison du programme C avec le prog asm, le lieur remplacera toutes les références à la fonction Init8254s par l'adresse de cette fonction. Pour dire au lieur que la fonction Init8254s existe et qu'elle doit être exportée, on utilise le mot clé PUBLIC, ce qui est fait au début du programme. Mais le mot clé publique attend comme objet une fonction. Ici ca n'a pas d'interet particulier que ce soit une fonction puisqu'elle n'a pas de paramètre, mais elle doit être déclarée comme telle. La déclaration de la fonction est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    _Init8254s proc near 
     
    ...
     
    _Init8254s endp
    de manière générale la déclaration d'une fonction est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    NomFonction proc [conventions d'appel et paramètres]
     
    Corps de la fonction
     
    endp

    En ce qui concerne les $ je pense que ce sont des référence au compteur d'adresse, c'est à dire à l'adresse de l'instruction en cours, ou de la donnée en cours. Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    AdresseVariable dd $ + 4
    Variable        dd ?
    ou encore

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
      jmp PlusLoin
      jmp EncorePlusLoin ; 2 octets
      dw ?               ; 2 octets
     
    PlusLoin:
      jmp $ - 4 ; Saut vers l'instruction EncorePlusLoin (4 octets avant)
     
    EncorePlusLoin:
    Suis pas sûr que ce code fonction mais c'est une illustration. Dans ton programme, c'est un

    ce qui veut dire une boucle qui reste sur place. L'instruction loop effectue un saut sur elle même. cx est mis à 10 avant. L'instruction doit servir à attendre quelques cycles. C'est relativement courant lors de la communication avec le matériel, puisque ce dernier ne répond pas aussi vite que le processeur peut lui communiquer les informations.

    Si tu as des problèmes avec les PUBLIC et proc, renseigne toi sur les mécanismes des lieurs.

  3. #3
    Futur Membre du Club
    Inscrit en
    Mai 2004
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 6
    Points : 7
    Points
    7
    Par défaut
    Comme je ne savais pas si je pouvais linker (et que je ne l'ai jamais fait), j'ai effectué une autre manoeuvre. J'ai copié mon code ASM que j'ai ensuite collé en C dans mon compilateur de la manière suivante.

    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    / Procedure de saisie d'un caractere au clavier :
    //  _ Appel procedure en c 5.1 Microsoft
           int saisie_car (unsigned int *ptr_car )
    {
    //  _  le retour se fait dans le registre AL
    //         _ AX = 0 , pas de caractere recu
    //         - AX = 1 , un caractre recu
    //  _ Definition du caractere envoye
    //         _ 0    < car < 0x100 : codes ascii standart + codes ascii
    //           etendu
    //         _ 0xFF < car < 0x1FF : codes des cles IBM etendu ,
    //           code de la cles + 0x100
     
     
     
    //          PUBLIC  _saisie_car
     
    //_saisie_car  proc near
    // sauvegarde du contexte
    asm    {
           push bp
           mov  bp,sp
           push si
     
    //pointe l'adresse du caractere a metre a jour
           mov si,4[bp]
     
    //saisie du caractere
           mov ah,6
           mov dl,0x0ff
           int 0x21
           jz  err          //pas de caractere recu
    //un caractere est recu test si sequence escape(code cles IBM etendu)
           cmp al,0
           jz  etendu       //sequence caractere escape
    //mise a jour du carractere recu : codes standarts et etendu ascii
           xor ah,ah
           mov [si],ax
           mov al,byte ptr 1
           jmp fin
    //saisie du second caractere
    etendu:
           mov ah,6
           mov dl,0x0ff
           int 0x21
           jz  err          //pas de second caractere
    //pointe le caractere
           mov ah,al
           xor al,al
           mov [si],ax
           mov al,byte ptr 1
           jmp fin
    //pas de caractere recu , retourne faux et code nul
    err:   xor al,al
           xor ah,ah
           mov [si],ax
    //restitution du contexte
    fin:   pop  si
           pop  bp
           ret
           }
    }
    //_saisie_car  endp
    Après cela j'ai mis ce nouveau fichier C dans mon projet (sous Borland 5.02) et j'ai appellé le prototype de la fonction dans un fichier .H

    Est ce que cela va marcher ainsi ou faut-il que je link mes fichiers ASM avec les PUBLIC et proc. Si oui serait-il possible de m'indiquer quel logiciel utiliser.

    Merci beaucoup pour toute l'aide apportée.

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    842
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 842
    Points : 696
    Points
    696
    Par défaut
    Citation Envoyé par Condor7
    Après cela j'ai mis ce nouveau fichier C dans mon projet (sous Borland 5.02) et j'ai appellé le prototype de la fonction dans un fichier .H
    C'est plutôt bien. Petite correction, on ne dit pas appelé. Dans le fichier .h tu déclare la fonction. Le lieur se fiche de la déclaration du .h et s'interessera à la fonction qu'a partir du moment ou elle est appellée dans un module quelconque. Pour approfondir encore, quand une fonction est définie en C, de la même manière, quand une variable est définie en C, elle est exportée automatiquement. C'est comme si il y avait le mot clé PUBLIC explicitement. On restreint cette exportation en C par le mot clé static.

    Maintenant, il y un petit problème. Les fonctions C, ont des épilogues / prologues. Ceux-ci s'interessent généralement à la pile. C'est abordé sur un autre sujet de ce forum que tu as toi même crée ^^

    http://www.developpez.net/forums/viewtopic.php?t=189925

    Donc, si tu regardes avec la fenêtre de débuguage de la console tu devrais voir avant que ton prog ne plante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
           push ebp
           mov ebp, esp
           push bp 
           mov  bp,sp
    Les deux premières instructions auraont été rajoutées. Comme je l'ai précisé dans l'autre post, il faut rajoutter : __declspec(naked) devant la déclaration de la fonction.

    Autre gros gros problème. Borland 5.02 est un compilateur 32 bits pour Win32. Or tu lui donnes du codes DOS. Donc à la première int 21h tu vas avoir un plantage. Outre cela, tu vas avoir un problème de pile puisqu'en 32 bits esp et ebp sont utilisés alors que tu ne te sers que de la moitié, sp et bp.


    Enfin pour répondre à ta dernière question, c'est très simple, tu demandes la compilation de ton programme asm, mais pas la liaison. LE compilateur va te donner un fichier .obj, que tu pourras lier avec ton programme C. Pour Borland, il suffit d'ajouter le .obj au projet. Mais le problème est le même, Borland est un compilateur Win32, pas DOS.

Discussions similaires

  1. interfacer un code asm en programme en C
    Par ifdo7a dans le forum C
    Réponses: 2
    Dernier message: 25/01/2011, 20h37
  2. Lier du code C optimisé et du code ASM non optimisé
    Par garybaldi dans le forum x86 32-bits / 64-bits
    Réponses: 3
    Dernier message: 07/09/2005, 17h22
  3. Probleme code asm dans .c
    Par sorry60 dans le forum C
    Réponses: 5
    Dernier message: 18/04/2005, 14h15
  4. [commande DOS] Récupérer le code retour d'un programme
    Par bobunny dans le forum Scripts/Batch
    Réponses: 8
    Dernier message: 04/06/2004, 16h51
  5. [TP]code asm dans une procedure
    Par M.Dlb dans le forum Turbo Pascal
    Réponses: 3
    Dernier message: 17/08/2002, 21h43

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