begin process at 2012 05 25 05:14:26
  Trouver un code source :
 
dans
 
Accueil > Forum > 

Assembleur

 > 

Système d'exploitation

 > 

Linux

 > 

[linux] read and open


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

[linux] read and open

mardi 18 juillet 2006 à 01:14:51 | [linux] read and open

sheorogath

Membre Club Administrateur CodeS-SourceS
Bonjour,
je débute un peu en assembleur et j'essaie de faire un programme qui lit le début d'un fichier dont le nom est entré par l'utilisateur.

Voici le code :
; Instruction de compilation :
; nasm -f elf dcat.asm
; ld -o dcat dcat.o

segment .data                ; variables initialisées constantes
    buflen: dd 254
    readlen: dd 254
    err: dd 128

    error:     db 'error open',10   
    errorLen:  equ $-error   
segment .bss
    buf:        resb    254
    read:    resb    254
    lerr: resb 128
segment .text                ; équivalent de main() mais c'est pas une fonction
    global _start

errorf:        ;si on ne peut pas ouvrir le fichier
   
    mov eax,4                  ;syscall 4 => write
    mov ebx,1                  ;1 => STDOUT
    mov ecx,error            ;what ? error
    mov edx,errorLen     ;length? errorLen   
    int 80h                        ;execute

    mov eax,1                ;syscall 1 => exit
    mov ebx,0                ;error code => 0
    int 80h                     ;execute
    ret                            ;end

readf:        ;si on a ouvert le fichier
   
    mov ebx,eax            ; move file descriptor in ebx
    mov eax,3                ;syscall 3 => read
    mov ecx,read          ;put in read
    mov edx,readlen    ;length
    int 80h                    ;execute

    mov eax,4                ;syscall 4 => write
    mov ebx,1                ;where? STDOUT
    int 80h                ;execute
                                ;ecx , edx already defined
    mov eax,1                ;syscall 1 => exit
    mov ebx,0                ;error code
    int 80h                 ;execute
    ret                        ;exit


_start:                    ; programme en lui même
   
    mov eax,3               ;syscall 3 => read
    mov ebx,0               ; Where? STDIN
    mov ecx,buf            ;save in buf
    mov edx,buflen       ;length of buf
    int 80h                     ;execute

    mov eax,5                ;syscall 5 => open
    mov ebx,buf            ;open what ?buf
    mov ecx,0                ;flag => read only
    int 80h                     ;execute
   
    test    eax,-1             ; an error ?
    je    errorf                 ;yes jump to error
    jne    readf                ;no read file
   

Je n'ai aucune sortie comme quoi le fichier n'existe pas (qu'il existe ou pas d'ailleurs).
Enfin bref je ne sais pas où est mon erreur.
Pouvez-vous m'aider ou me mettre sur la voie ?

Merci
++

"n'est pas mort ce qui semble a jamais dormir et en d'etrange temps meme la mort peut mourrir"
mardi 18 juillet 2006 à 10:03:37 | Re : [linux] read and open

Nasman

Bonjour,

Je ne connais pas les fonctions système de linux, aussi juste une question.
Quels sont les registres modifiés par l'appel de la fonction système 3. En clair es tu sur que les registres ecx et edx contiennent toujours les bonnes valeur lors de l'appel à la fonction syscall 4.

Autre chose : utilisant Nasm pour windows je ne sais pas quelle est la déclaration pour linux pour indiquer le point d'entrée du programme. Est-ce que nasm reconnait _start:  comme point d'entrée ?

A+

mardi 18 juillet 2006 à 13:43:27 | Re : [linux] read and open

sheorogath

Membre Club Administrateur CodeS-SourceS
pour le point d'entree il n'y a pas de probleme
sinon pour les registre en fait quand je passe sur open eax a toujours la meme valeur 0xFFFFFFFe que le fichier existe ou pas dailleur et je ne vois pas pourquoi
"n'est pas mort ce qui semble a jamais dormir et en d'etrange temps meme la mort peut mourrir"
samedi 22 juillet 2006 à 18:11:55 | Re : [linux] read and open

patatalo

Membre Club Administrateur CodeS-SourceS
salut, test eax,-1 sera toujours vrai sauf si eax=0 (c'est un "et logique" sans modification des flags), tu devrais plutot faire: cmp eax,-1 je error jmp ok @++
dimanche 23 juillet 2006 à 12:29:11 | Re : [linux] read and open

sheorogath

Membre Club Administrateur CodeS-SourceS
ok merci beaucoup
un debut de reponse ;)

"n'est pas mort ce qui semble a jamais dormir et en d'etrange temps meme la mort peut mourrir"
jeudi 27 juillet 2006 à 14:32:16 | Re : [linux] read and open

_dune2_

Membre Club
Bon, aprés quelques essais, j'ai trouvé quelques points interessants :

1) lors du "open", 2 problèmes sont à signaler :
  1: le mode d'ouverture doit inclure O_CREAT en plus de O_RDWR pour créer le fichier s'il n'existe pas ce qui fait qu'il faut mettre 102 dans ECX (O_CREAT=100 | O_RDWR=2)
  2: en cas de création du fichier, il faut bien entendu spécifier les droits du fichier dans EDX, dans notre cas je suggère 0666 -rw-rw-rw- (attention à la notation Octal : 0666 et non 666).

2) lors de la saisie du nom de fichier, il faut retirer le "\n" ajouté au clavier lors de la saisie, sinon celui-ci fera parti du nom du fichier (ajout de "?" à la fin du nom du fichier, gênant pour toutes manipulations).

3) L'utilisation de "cmp" est destructif sur EAX, et le CPU crée un EAX_ORIG (registre temporaire pour sa sauvegarde) ce qui fait qu'on ne teste pas le registre EAX comme on s'y attend. Il faut donc utiliser l'instruction "test" non destructif, et se servir du flag "sign" pour detecter une valeur négative. ("test eax,eax ; js _failure").

4) Penser à faire un syscall à "close" pour bien terminer ;)

Voici le code (en asm AT&T) incorporant ces modifications et fonctionnel :

// compile with as :
// as readAndWrite.s -o readAndWrite.o ( add -g for debug)
// link with ld :
// ld readAndWrite.o -o readAndWrite ( add -g for debug )

.section    .data
inputname:    .string "Nom du fichier : "
errorstr:    .string "Unable to open file !\n"
puttext:    .string "Enter text now :\n"
filename:    .space  256
buffer:        .space    1024
fdfile:        .long    0

.section    .text
.global        _start
 
_start:
                                        // Write enter filename
    mov        $4,%eax;                    // syscall 4 = write
    mov        $1,%ebx;                    // filedesc 1 = STDOUT
    mov        $inputname,%ecx;            // @inputname
    mov     $(errorstr-inputname),%edx;    // strlen ( inputname )
    int        $0x80;                        // syscall

_readfilename:                            // read the filename
    mov        $3,%eax;                    // syscall 3 = read
    mov        $0,%ebx;                    // filedesc 0 = STDIN
    mov        $filename,%ecx;                // @filename
    mov     $(buffer-filename),%edx;    // strlen ( chaine )
    int        $0x80;                        // syscall

_removeCRonfilename:                    // we need to remove the CR of filename
    mov     $filename,%ecx;                // we know that read return number of characters in EAX
    add     %eax,%ecx;                    // so we use it to locate the CR
    dec        %ecx;                        // the character just before the end :)
    movb    $0,(%ecx);                    // put null character in place (carefull we put a byte,
                                        //  it is why we add 'b' to 'mov' -> 'move byte')

_openfile:                                // open the filename
    mov        $5,%eax;                    // syscall 5 = open
    mov        $filename,%ebx;                // @filename
    mov        $102,%ecx;                    // flags O_RDWR=2 | O_CREAT=100 !!!
    mov     $0666,%edx;                    // mode default & open_mask
    int        $0x80;                        // syscall
   
_checkopen:                                // check if open is OK
    test    %eax,%eax;                    // check EAX sign
    js        _failure;                    // On error (sign flag) , go to _failure
    mov        %eax,fdfile;                // put fdfile at @fdfile

_writeokmessage:                        // Write input text
    mov        $4,%eax;                    // syscall 4 = write
    mov        $1,%ebx;                    // filedesc 1 = STDOUT
    mov        $puttext,%ecx;                // @chaine
    mov     $(filename-puttext),%edx;    // strlen ( chaine )
    int        $0x80;                        // syscall

_readstdin:                                // read stdin to buf
    mov        $3,%eax;                    // syscall 3 = read
    mov        $0,%ebx;                    // filedesc 0 = STDIN
    mov        $buffer,%ecx;                // @buffer
    mov     $(fdfile-buffer),%edx;        // strlen ( buffer )
    int        $0x80;                        // syscall

_writeinfile:                            // write buf in file
    mov        $4,%eax;                    // syscall 4 = write
    mov        fdfile,%ebx;                // get fdfile in EBX
    mov        $buffer,%ecx;                // @buffer
    mov     $(fdfile-buffer),%edx;        // strlen ( buffer )
    int        $0x80;                        // syscall

_closefile:                                // close file
    mov        $6,%eax;                    // syscall 6 = close
    mov        fdfile,%ebx;                // get fdfile in EBX
    int        $0x80;                        // syscall

_end:
    mov        $1,%eax;                    // syscall 1 = exit
    mov     $0,%ebx;                    // return code = 0
    int     $0x80;                        // syscall
   
_failure:                                // Write Failure
    mov        $4,%eax;                    // syscall 4 = write
    mov        $2,%ebx;                    // filedesc 2 = STDERR
    mov        $errorstr,%ecx;                // @chaine
    mov     $(puttext-errorstr),%edx;    // strlen ( chaine )
    int        $0x80;                        // syscall

_endfailed:
    mov        $1,%eax;                    // syscall 1 = exit
    mov     $-1,%ebx;                    // return code = -1
    int     $0x80;                        // syscall

   

L'ajout des labels à chaque opération m'ont permis de pouvoir mettre des breakpoints à chaque étape importante lors du débugage avec gdb et même Eclipse (qui supporte au passage la coloration syntaxique de AT&T ;) ).

NB: juste une petite explication sur les principales différences entre asm Intel et AT&T pour une meilleure compréhension:
- les opérandes sont inversées : la destination est toujours la dernière opérande en AT&T
- les registres sont toujours précédés par '%'
- les variables qui commencent par '$' sont des valeurs immédiates, sinon, ce sont des adresses qui pointent sur la valeur.
- les valeurs immédiates sont toujours précédés de '$' et la notation numérique est celle du C : $0x45 (hexa) $45 (decimal) $045 (octal)

Voilà .. je pense que ce doit être suffisent pour comprendre le source ...

Dune2.

Gentoo... que du bonheur ...
vendredi 28 juillet 2006 à 14:28:47 | Re : [linux] read and open

_dune2_

Membre Club
Salut tout le monde,



Je viens de trouver un détail sur le code précedent, sur la partie :

_readstdin:                                // read stdin to buf
    mov        $3,%eax;                    // syscall 3 = read
    mov        $0,%ebx;                    // filedesc 0 = STDIN
    mov        $buffer,%ecx;                // @buffer
    mov     $(fdfile-buffer),%edx;        // strlen ( buffer )
    int        $0x80;                        // syscall

_writeinfile:                            // write buf in file
    mov        $4,%eax;                    // syscall 4 = write
    mov        fdfile,%ebx;                // get fdfile in EBX
    mov        $buffer,%ecx;                // @buffer
    mov     $(fdfile-buffer),%edx;        // strlen ( buffer )
    int        $0x80;                        // syscall


En effet, lorsqu'on écrit dans le fichier, on écrit une taille $(fdfile-buffer) qui correspond à la taille du buffer. Quand on fait un 'cat fichier.txt' on ne s'en rend pas compte car le caractère null termine la chaine, mais la taille du fichier trahit cette anomalie de taille d'écriture.

Pour résoudre cette anomalie, on peut utiliser le retour de "
_readstdin:" qui renvoie le nombre d'octets lus, et permettre une écriture dans le fichier de la partie saisie au clavier uniquement. Le code de retour étant dans EAX, il s'agira donc de copier EAX dans EDX avant d'écraser EAX par le syscall 4 :

_writeinfile:                            // write buf in file
    mov     %eax,%edx;            // copy the character count of read(STDIN) in size of write(FILE)
    mov        $4,%eax;              // syscall 4 = write
    mov        fdfile,%ebx;         // get fdfile in EBX
    mov        $buffer,%ecx;      // @buffer
    int        $0x80;                    // syscall


Ainsi, on crée un fichier ayant la taille de ce qui a été pris sur STDIN et non la taille du buffer.

dune2.

Gentoo... que du bonheur ...


Cette discussion est classée dans : mov, error, read, eax, ebx


Répondre à ce message

Sujets en rapport avec ce message

Différences ??? [ par Arecibo ] Voila je debute en assembleur et j'aimerais savoir quelles sont les différences entre :-> mov eax, ebx et mov eax, [ebx]-> mov esi, eax et mov [esi], j'ai un prob avec mon buffer ; ya pas d'amuses gueules (masm32) [ par papiboff ] bj si je mets le buffer "somme " en dd avec charge eax et que j'ajoute deux 'dec ebx ' , ben , marche pas correctement ; (pêrqué ???? = en french) sv inverser une chaine [ par MrdJack ] salut, je suis sur un projet de calculatrice me permettant de faire des calculs avec des nombres tres grands. chaque nombre est stocké dans la memoire Petit problème pour comparer (cmp) [ par smok1360 ] Bonjour à tous,Pour commencer, j'espère de ne pas avoir choisis le mauvais lieu pour poster, j'ai un petit peu hésité Donc, j'ai décidé d'apprendre l' Aligner des données pour le SSE [ par epineurien ] Bonjour à tous !J'ai un petit problème avec du code dont je mesure la vitesse: suivant la compilation, la vitesse varie du simple au double .J'expliqu nombre premier en nasm [ par YAWLY ] MED.MERZOUG salut tout le monde vous pouvez m'aider si j le compile sa affiche chaque fois le nbr est non premeir > le code est : Section .date ch un énorme travail de votre part [ par mana ] bonjour, voici un programme écrit en c++ (il permet de passer d'une image en couleur 24bits(ARGB) a une image en 256 niveaux de gris(toujours sur 24bi Resultat de la vitesse des : Registre, instruction, calcul, et mémoire ! ! ! [ par rebixav ] Voici la liste que j'ai créé : asm : ( inc ) = 0.065 asm : ( and ) = 0.08 asm : ( or ) = 0.08 asm : ( xor ) = 0.08 asm : ( not ) conversion en syntaxe intel [ par marooh ] bonjour, j'ai un code écrit en syntaxe at&t et je veux le rendre en syntaxe intel.si vous pouvez bien m'aider... voici le code Project title : m Proj Comment utiliser une variable ?! lorsque l'on utilise déjà ESI et EDI dans la PROC. [ par rebixav ] Voilà mon problème, je débute en assembleur et je l'utilise essentiellement pour créer des procédure pour visual basic ou C voici une de mes procédure


Nos sponsors


Sondage...

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 1,061 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales