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

Assembleur Discussion :

[Nasm / Dos 16 bits] Problème d'affichage des chaînes de caractères


Sujet :

Assembleur

  1. #1
    Candidat au Club
    Inscrit en
    Septembre 2006
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 6
    Points : 2
    Points
    2
    Par défaut [Nasm / Dos 16 bits] Problème d'affichage des chaînes de caractères
    Bonjour, je programme donc en assembleur avec nasm sur une bien vieille machine (elle a mon âge), qui est en jeu d'instructions 80286. Sur cette machine, je tourne avec Ms-Dos .

    Mais j'ai quelques problèmes, notamment au niveau de l'affichage des chaînes de caractères qui ne posent pas de problème sur les 386 mais là ....

    Voici mon code:
    segment .data
    Message DB "hello", 0

    segment .bss

    segment .text
    global main
    main:
    enter 0,0
    mov dx,Message
    mov ah,09h
    int 21h
    leave
    ret
    Voici un code simple qui a pour but d'afficher hello.
    Seulement, ça n'affiche pas seulement hello, mais aussi un bon paragraphe de codes en caractères ascii.
    Quand il s'agit d'afficher un seul caractère avec 02h, ça marche bien. Et je ne peux pas utiliser offset, car lors de la compilation il intervient une erreur.

    Quand je mets 2 chaîne de caractères dans segment .data et que je ne demande d'en afficher qu'une seule lors de l'exécution du programme, le paragraphe de caractères ascii est bien plus important et les deux chaînes sont presentes côte à côte dans ce paragraphe.

    Voilà, je sais que peu de personne programment encore sur les 80286 car cela reduit bien la porté par rapport aux 80386, mais j'espère que certaines personnes pourront m'aider.

    Merci d'avance.

  2. #2
    Responsable Pascal, Lazarus et Assembleur


    Avatar de Alcatîz
    Homme Profil pro
    Ressources humaines
    Inscrit en
    Mars 2003
    Messages
    7 939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ressources humaines
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2003
    Messages : 7 939
    Points : 59 409
    Points
    59 409
    Billets dans le blog
    2
    Par défaut
    Bonjour !

    Au lieu de se terminer par 0, les chaînes à afficher doivent se terminer par le caractère $.
    Règles du forum
    Cours et tutoriels Pascal, Delphi, Lazarus et Assembleur
    Avant de poser une question, consultez les FAQ Pascal, Delphi, Lazarus et Assembleur
    Mes tutoriels et sources Pascal

    Le problème en ce bas monde est que les imbéciles sont sûrs d'eux et fiers comme des coqs de basse cour, alors que les gens intelligents sont emplis de doute. [Bertrand Russell]
    La tolérance atteindra un tel niveau que les personnes intelligentes seront interdites de toute réflexion afin de ne pas offenser les imbéciles. [Fiodor Mikhaïlovitch Dostoïevski]

  3. #3
    Candidat au Club
    Inscrit en
    Septembre 2006
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    mettre $ ne resoud pas le probleme. la même chose est affiché.

  4. #4
    Responsable Pascal, Lazarus et Assembleur


    Avatar de Alcatîz
    Homme Profil pro
    Ressources humaines
    Inscrit en
    Mars 2003
    Messages
    7 939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ressources humaines
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2003
    Messages : 7 939
    Points : 59 409
    Points
    59 409
    Billets dans le blog
    2
    Par défaut
    Ben pourtant, Ralf Brown dit la même chose : http://lrs.fmi.uni-passau.de/support...57/RB-2496.HTM
    Règles du forum
    Cours et tutoriels Pascal, Delphi, Lazarus et Assembleur
    Avant de poser une question, consultez les FAQ Pascal, Delphi, Lazarus et Assembleur
    Mes tutoriels et sources Pascal

    Le problème en ce bas monde est que les imbéciles sont sûrs d'eux et fiers comme des coqs de basse cour, alors que les gens intelligents sont emplis de doute. [Bertrand Russell]
    La tolérance atteindra un tel niveau que les personnes intelligentes seront interdites de toute réflexion afin de ne pas offenser les imbéciles. [Fiodor Mikhaïlovitch Dostoïevski]

  5. #5
    Candidat au Club
    Inscrit en
    Septembre 2006
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    J'ai essayé d'autres méthodes, mais sans succés.
    J'en ai une mais qui est plutot longue a effectuer, c'est simplement d'écrire les chaines de caracteres caractere par caractere. Mais le code source devient bien plus imposant , la compilation est un peu plus longue et c'est un peu lourd. Mais tand qu'il ne s'agit que de petite phrases ou simples mots ça va.

    J'ai un autre probleme, c'est quand je demande de rentrer un nombre, j'utilise :
    mov ah,00h
    int 16h

    mais en je reçoit la valeur du nombre par rapport a la table ascii. Je voudrait savoir s'il y a une methode pour avoir ce la valeur du nombre directement, au lieu d'enlever a chaque fois 48 pour partir de 0.
    Et de même pour si le nombre demandé dépasse 1 caractere (chaine de chiffre).

  6. #6
    Membre confirmé
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Mars 2006
    Messages
    400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Mars 2006
    Messages : 400
    Points : 562
    Points
    562
    Par défaut
    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
    INT 21 09-- - DOS 1+ - WRITE STRING TO STANDARD OUTPUT
     
    Category: D - DOS kernel
     
    Inp.:
    	AH = 09h
    	DS:DX -> '$'-terminated string
    Return: AL = 24h (the '$' terminating the string, despite official docs which
    		state that nothing is returned) (at least DOS 2.1-7.0 and
    		NWDOS)
    Notes:	^C/^Break are checked, and INT 23 is called if either pressed
    	standard output is always the screen under DOS 1.x, but may be
    	  redirected under DOS 2+
    	under the FlashTek X-32 DOS extender, the pointer is in DS:EDX
    SeeAlso: AH=02h,AH=06h"OUTPUT"
    INT 21
    Copied from Ralf Brown's Interrupt List
    Pour utiliser cette interruption, la chaîne doit se terminer par le caractaire $.

    Ensuite, le registre ds doit pointer vers le segment contenant la chaîne.
    Si ton programme n'affiche pas la chaîne demandée, c'est probablement parce que ds ne contient pas l'adresse du segment de données.

    Vérifie si quelque part dans ton code, tu as une ligne ressemblant à :

  7. #7
    Candidat au Club
    Inscrit en
    Septembre 2006
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    L'utilisation du ds me met une erreur lors de la compilation : "invalid combination of opcode and operands"
    C'est que je travail en dos 16bit et avec un processeur 80286. Sinon, sur 386, ce probleme ne se pose pas....

  8. #8
    Responsable Pascal, Lazarus et Assembleur


    Avatar de Alcatîz
    Homme Profil pro
    Ressources humaines
    Inscrit en
    Mars 2003
    Messages
    7 939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ressources humaines
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2003
    Messages : 7 939
    Points : 59 409
    Points
    59 409
    Billets dans le blog
    2
    Par défaut
    Et si tu postais un peu plus de code ?
    Règles du forum
    Cours et tutoriels Pascal, Delphi, Lazarus et Assembleur
    Avant de poser une question, consultez les FAQ Pascal, Delphi, Lazarus et Assembleur
    Mes tutoriels et sources Pascal

    Le problème en ce bas monde est que les imbéciles sont sûrs d'eux et fiers comme des coqs de basse cour, alors que les gens intelligents sont emplis de doute. [Bertrand Russell]
    La tolérance atteindra un tel niveau que les personnes intelligentes seront interdites de toute réflexion afin de ne pas offenser les imbéciles. [Fiodor Mikhaïlovitch Dostoïevski]

  9. #9
    Candidat au Club
    Inscrit en
    Septembre 2006
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    L'éscentiel du code est déjà mit.
    Je peu en remmettre un peu pour expliquer des methodes...


    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
    segment .data
     
    message1 "bonjour$" ; j'ai essayé de mettre plusieurs choses, avec le ", 0", ... etc et aussi avec ' au lieu de "
    message2 "tour le monde$"
     
    segment .bss
     
    segment .text
     
    global main
     
    main:
    enter 0,0
    pusha
     
    xor dx,dx
    mov dx,message1 
    mov ah,09h
    int 21h
     ; lors de l'exécution ceci affiche : " {des caractéres de la table ascii ...} bonjour tout le monde {des caractéres de la table ascii ...}"
     ; alors que je n'ai demandé d'afficher qu'une chaine, les deux sont affiché au millieu de tous ces caractéres.
     
    mov dx,'s'
    mov ah,02h
    int 21h
    mov dx,'a'
    mov ah,02h
    int 21h
    mov dx,'l'
    mov ah,02h
    int 21h
    mov dx,'u'
    mov ah,02h
    int 21h
    mov dx,'t'
    mov ah,02h
    int 21h
     ; ceci afiche bien "salut" sans defaut, mais c'est long d'écrire des phrases comme ça, et ça augmente conciderablement le code
     
    popa
    leave
    ret

  10. #10
    Membre confirmé
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Mars 2006
    Messages
    400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Mars 2006
    Messages : 400
    Points : 562
    Points
    562
    Par défaut
    Une autre solution consiste à placer les messages dans le segment .text
    puis à faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    push ds
    mov ax,cs
    mov ds,ax
     
    xor dx,dx
    mov dx,message1 
    mov ah,09h
    int 21h
     
    pop ds
    Cela consite à avoir le code et les données (le message) dans le même segment ( segment de code).
    On est donc sûr que le message à afficher se situe dans le segment de code (contenu dans cs).

    L'interruption nécessite que l'adresse du message soit contenue dans ds:dx
    Il faut donc mettre cs dans ds.
    Comme on ne peut pas transférer un registre de segment directement vers un autre registre de segment, on passe par l'accumulateur ax.
    Comme le registre ds est modifié, on commence par sauvegarder son contenu pour le restorer à la fin.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    push ds
    ... le code ici ...
    pop ds
    Si cette solution ne fonctionne toujours pas, essaye d'utiliser le registre es au lieu du registre ds.
    En effet, un certain nombre d'interruptions utilisent le registre es pour préserver ds.

  11. #11
    Nouveau membre du Club
    Inscrit en
    Août 2006
    Messages
    23
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 23
    Points : 28
    Points
    28
    Par défaut
    Le registre de segment par défaut pour le registre à usage général "dx" est "ds".
    Si tu veux que ton message soit correctement affiché il initialiser le registre "ds" avec la bonne valeur de segment. Celui où se trouve ta chaîne de caractères.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    push ds
    mov ax, SEG message1
    mov ds, ax
    mov ah, 9h
    mov dx, OFFSET message1 ; "ds:dx"
    int 21h
    pop ds
    avec le code ci-dessus "no problem"

Discussions similaires

  1. problème d'affichage des caractères spéciaux avec la console Dos
    Par javass dans le forum Débuter avec Java
    Réponses: 1
    Dernier message: 14/05/2008, 17h58
  2. Problème d'affichage des tables
    Par talere dans le forum Access
    Réponses: 6
    Dernier message: 24/10/2005, 13h02
  3. Problème d'affichage des caractères accentués
    Par ostaquet dans le forum JBuilder
    Réponses: 1
    Dernier message: 10/03/2005, 06h58
  4. [JTable] Problème d'affichage des données
    Par ddams dans le forum Composants
    Réponses: 2
    Dernier message: 15/09/2004, 17h07
  5. Réponses: 1
    Dernier message: 06/03/2003, 11h57

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