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 :

Afficher le contenu d'un fichier à l'écran


Sujet :

x86 32-bits / 64-bits Assembleur

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    102
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 102
    Points : 44
    Points
    44
    Par défaut Afficher le contenu d'un fichier à l'écran
    Bonjour,

    Je veux afficher le contenu d'un fichier dont le nom a été entré par l'utilisateur, mais je dois entrer le nom du fichier lorsque je lance le programme (ex: ./monprogramme test.asm). J'aimerais ne pas avoir à spécifier le nom du fichier à chaque exécution, mais que ce soit à l'utilisateur de le faire lorsqu'il est invité à entrer le nom. Je précise que la lecture et l'affichage fonctionnement correctement. Voilà ce que j'ai fait jusqu'à maintenant :

    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
     
    segment .data 
    nom_fichier : db "Entrez le nom du fichier : ", 10
    nom_fichier_len equ $-nom_fichier
     bufsize dw      1024
     
    segment .bss
    fichier        resb 32
     buf     resb    1024
    ;; Message qui demande à l'utilisateur d'entrer un nom de fichier
    	mov eax, 4
    	mov ebx, 1
    	mov ecx, nom_fichier
    	mov edx, nom_fichier_len
    	int 0x80
     
    	;; Lecture nom du fichier
    	mov eax, 3
    	mov ebx, 0
    	mov ecx, fichier
    	mov edx, 32
    	int 0x80
     
      ; get the filename in ebx
    	pop   ebx
        pop   ebx               
        pop   ebx              
        pop   ebx    
     
      ; ouvrir le fichier
        mov   eax,  5           ; ouverture
        mov   ecx,  0           ;   lecture seulement
        int   80h               
      ; lire le fichier
        mov     eax,  3         ; lecture
        mov     ebx,  eax       ;   descripteur
        mov     ecx,  buf       ;   *buf,
        mov     edx,  bufsize   ;   *bufsize
        int     80h             
     
      ; afficher le contenu à l'écran
        mov     eax,  4         ; affiche à l'écran
        mov     ebx,  1         
        int     80h
    Merci de votre aide

  2. #2
    Membre émérite
    Avatar de supersnail
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 719
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 719
    Points : 2 793
    Points
    2 793
    Par défaut
    Bonjour,

    En gros, tu veux récupérer les arguments passés en ligne de commande, c'est ça?

    Ben ça marche comme pour n'importe quelle fonction, tes arguments sont situés sur la pile
    Toute question technique envoyée en MP ira directement à la poubelle

    Un code ne marchera jamais, il n'a jamais reçu la capacité de se déplacer.
    Inutile donc de dire "ça marche pas", donnez plutôt des informations précises afin de mieux pouvoir vous aider.


    Grand gourou de la -attitude

  3. #3
    Membre éclairé
    Avatar de edfed
    Profil pro
    être humain
    Inscrit en
    Décembre 2007
    Messages
    476
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : être humain

    Informations forums :
    Inscription : Décembre 2007
    Messages : 476
    Points : 701
    Points
    701
    Billets dans le blog
    1
    Par défaut
    la ligne de commande est passée dans un buffer.

    ce buffer est localisé à l'offset 81h
    l'octet 80h contient la taille du buffer.

    le premier octet du buffer est souvent egal à ' ' (espace), et ne permet donc pas l'utilisation directe avec les fonctions fichiers dos, il faut d'abord trouver le premier caractère affichable à partir de 81h, et de là, on à le nom du fichier passé en ligne de commande.

    une autre solution serait aussi d'avoir un nom de fichier predefini, et si la ligne de commande contient un nom, alors il sera pris, et si l'utilisateur entre un nom de fichier, il sera pris lui aussi.

    à terme, il faut aussi pouvoir manipuler des pointeurs vers nom de fichier plutot que directement les noms de fichiers. c'est plus rapide et efficace.

  4. #4
    Membre émérite
    Avatar de supersnail
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 719
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 719
    Points : 2 793
    Points
    2 793
    Par défaut
    Bonjour,

    Sauf que là le monsieur développe sous Linux (cf l'int 80h).
    Donc, pour le DOS, ça fonctionnera pas trop ici
    Toute question technique envoyée en MP ira directement à la poubelle

    Un code ne marchera jamais, il n'a jamais reçu la capacité de se déplacer.
    Inutile donc de dire "ça marche pas", donnez plutôt des informations précises afin de mieux pouvoir vous aider.


    Grand gourou de la -attitude

  5. #5
    Membre éclairé
    Avatar de edfed
    Profil pro
    être humain
    Inscrit en
    Décembre 2007
    Messages
    476
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : être humain

    Informations forums :
    Inscription : Décembre 2007
    Messages : 476
    Points : 701
    Points
    701
    Billets dans le blog
    1
    Par défaut
    il doit bien y avoir l'equivalent du psp sous linux, du type,

    mov eax,X
    int 80h..

    X étant les paramètres de la ligne de commande.

  6. #6
    Membre actif Avatar de golden boy
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2010
    Messages
    120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2010
    Messages : 120
    Points : 230
    Points
    230
    Par défaut
    Si on part du principe que main() est une fonction qui prend deux arguments (argc et argv) je crois, sans en être sûr (souvenir lointain), que argc est stocké sur la pile à [esp+4] et que argv est stocké à [esp+8].

    J'ai regardé vite fais avec gdb si c'était cohérent, mais sans tester, donc je ne garantis pas que c'est ok. Je pense que ça doit marcher aussi bien sur Linux que sur NT ou même un autre OS.

  7. #7
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 370
    Points : 23 625
    Points
    23 625
    Par défaut
    Citation Envoyé par golden boy Voir le message
    Si on part du principe que main() est une fonction qui prend deux arguments (argc et argv) je crois, sans en être sûr (souvenir lointain), que argc est stocké sur la pile à [esp+4] et que argv est stocké à [esp+8].
    Ça dépend de plusieurs choses, notamment de ton architecture (les chiffres sont différents si tu travailles en 64 bits) et de certains détails de compilation (les noyaux Linux récents permettent dans certaines conditions de stocker autant d'arguments que possible dans les registres du processeur).

    Mais d'une manière générale, il vaut mieux s'appuyer sur EBP plutôt qu'ESP.

  8. #8
    Membre éprouvé Avatar de orfix
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 707
    Points : 1 132
    Points
    1 132
    Par défaut
    Citation Envoyé par golden boy Voir le message
    J'ai regardé vite fais avec gdb si c'était cohérent, mais sans tester, donc je ne garantis pas que c'est ok. Je pense que ça doit marcher aussi bien sur Linux que sur NT ou même un autre OS.
    Je ne pense pas que se soit le cas sous Windows par exemple... sinon je confirme pour Linux argc et argv[] se trouvent sur la pile:

    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
    +---------+
    | argc    | <- ESP
    +---------+
    | argv[0] |
    +---------+
    | ...     |
    +---------+
    | argv[n] |
    +---------+
    | NULL    |
    +---------+
    | env[0]  |
    +---------+
    | ...     |
    +---------+
    | env[n]  |
    +---------+
    | NULL    |
    +---------+
    (Cela fait bien longtemps que je n'ai pas touché à l'assembleur, j'ai un peux perdu mes réflexes )
    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
    BITS 32
     
    SECTION .data
    	nl: 		db 10
    	sys_write: 	equ 4
    	sys_exit: 	equ 1
     
    SECTION .text
    	global _start
     
    _start :
    	pop ecx			; argc
    	pop ecx			; argv[0] program name
     
    .parse:
    	mov eax, sys_write
    	mov ebx, 1
    	call strlen
    	int 80h
     
    	mov eax, sys_write
    	mov ecx, nl		; new line
    	mov edx, 1
    	int 80h
     
    	pop ecx			; next argument
    	test ecx, ecx
    	jnz .parse
     
    .done :
    	mov eax, sys_exit
    	mov ebx, 0		; EXIT_SUCCESSFUL
    	int 80h	
     
    strlen:
    	push eax
    	mov edx, ecx
     
    .nextbyte:
    	mov al, [edx]
    	test al, al
    	jz .nullbyte
    	inc edx
    	jmp .nextbyte
     
    .nullbyte:
    	sub edx, ecx
    	pop eax
    	ret
    To start press any key. (reading screen) Where's the "any" key? I see Esc, Catarl, and Pig Up. There doesn't seem to be any "any" key. Wo! All this computer hacking is making me thirsty. I think I'll order a Tab. (presses TAB key). -- HOMER --

  9. #9
    Membre actif Avatar de golden boy
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2010
    Messages
    120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2010
    Messages : 120
    Points : 230
    Points
    230
    Par défaut
    En effet, j'aurais dû penser à le préciser : mon décalage dans la pile de 4 et de 8 ne fonctionne qu'en 32 bits.
    En 64 bits, je suppose qu'on a du [rsp+8] et [rsp+16], mais je n'ai pas de 64 bits, je ne peux pas savoir.

    Mais pourquoi utiliser BP au lieu de SP ici, le résultat ne sera pas le même ou c'est juste un question de sûreté ?

  10. #10
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 370
    Points : 23 625
    Points
    23 625
    Par défaut
    Avant tout, j'ai envie de dire qu'un petit « gcc -S » produit le code assembleur généré à partir du C et permet de voir comment un simple main(int argc,char ** argv) va effectivement être traduit.

    Pour EBP, il vaut mieux s'y fier plutôt qu'à ESP parce que tu as le droit d'utiliser la pile dans ta fonction, spécialement si tu codes en assembleur. « BP » signifie Base Pointer et c'est lui que l'on utilise, en général, quand on ouvre un cadre de pile. C'est-à-dire qu'en entrant dans la fonction, on empile EBP, puis on copie ESP dans EBP, puis, enfin, on retranche une valeur n à ESP pour réserver de la place aux variables locales. Comme ESP peut bouger, donc, on utilise EBP comme référence.

    Cette manière de faire a deux avantages :

    — En cas d'exception, ou de sortie « prématurée » de la fonction avec exit(), goto, ou même un simple return, tu peux immédiatement ramener le pointeur de pile à son état initial et, de là, dépiler les registres et remonter à la fonction précédente ;
    — Ça te permet de ne pas avoir à systématiquement ouvrir de cadre de pile, ce qui est particulièrement intéressant lorsque tu utilises des fonctions récursives.

  11. #11
    Membre actif Avatar de golden boy
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2010
    Messages
    120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2010
    Messages : 120
    Points : 230
    Points
    230
    Par défaut
    D'accord, convaincu. J'avoue ne jamais avoir trop compris dans le détail les prologues de fonctions, mais je vois pourquoi il est préférable de se servir de BP à présent.

Discussions similaires

  1. [Reseau]FTPClient pour afficher le contenu d'un fichier
    Par boxsters dans le forum Entrée/Sortie
    Réponses: 9
    Dernier message: 21/06/2006, 11h12
  2. Réponses: 2
    Dernier message: 20/11/2005, 18h54
  3. Afficher le contenu d'un fichier
    Par ginnielle dans le forum Assembleur
    Réponses: 12
    Dernier message: 10/12/2004, 10h46
  4. Afficher le contenu d'un fichier xls dans un DBgrid
    Par bianconeri dans le forum C++Builder
    Réponses: 5
    Dernier message: 03/09/2004, 16h35
  5. Réponses: 1
    Dernier message: 12/02/2003, 09h36

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