begin process at 2008 07 20 23:40:04
1 213 505 membres
406 nouveaux aujourd'hui
14 167 membres club

Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum.
Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

[LINUX] LIRE CLAVIER ET ECRIRE CONSOLE


Information sur la source

Catégorie :Application Unix Classé sous : clavier, syscall, nasm, linux, console Niveau : Débutant Date de création : 16/07/2006 Date de mise à jour : 16/07/2006 20:22:10 Vu / téléchargé: 3 440 / 131

Note :
Aucune note

Commentaire sur cette source (17)
Ajouter un commentaire et/ou une note


Description

je vais certainement me faire lynché de poster un code aussi basic mais je prend le risque pour ceux qui comme moi
on decidé d'essayer de comprendre l'asm
ce code lit ce que vous entrez et l'affiche ensuite

Source

  • ; Instruction de compilation :
  • ; NASM -f elf hello_world.asm
  • ; ld -o hello_world hello_world.o
  • segment .data ; variables initialisées constantes
  • buflen: db 1024 ; taille du buffer
  • segment .bss
  • buf: resb 1024 ; buffer
  • segment .text ; équivalent de main() mais c'est pas une fonction
  • global _start
  • _start: ; programme en lui même
  • mov eax,3 ;syscall 3 => read
  • mov ebx,0 ; 0 => lit le clavier
  • mov ecx,buf ;dans quoi on stock
  • mov edx,buflen ;taille du buffer
  • int 80h ;on execute en appelant la syscall
  • mov eax,4 ;syscall 4 => write
  • mov ebx,1 ;1 => STDOUT
  • mov ecx,buf ; ecrire quoi ? buf
  • mov edx,buflen ;taille
  • int 80h ;appel de syscall
  • mov eax,1 ; 1 => exit
  • mov ebx,0 ; 0 code de sortie
  • int 80h ;fin ^^
 ; Instruction de compilation : 
; NASM -f elf hello_world.asm
; ld -o hello_world hello_world.o

segment .data				; variables initialisées constantes
	buflen: db 1024                 ; taille du buffer
segment .bss
	buf:		resb	1024    ; buffer
segment .text				; équivalent de main() mais c'est pas une fonction
	global _start

_start:					; programme en lui même
	
	mov eax,3			;syscall 3 => read
	mov ebx,0			; 0 => lit le clavier
	mov ecx,buf			;dans quoi on stock
	mov edx,buflen			;taille du buffer
	int 80h				;on execute en appelant la syscall
	mov eax,4			;syscall 4 => write
	mov ebx,1			;1 => STDOUT
	mov ecx,buf			; ecrire quoi ? buf
	mov edx,buflen			;taille
	int 80h				;appel de syscall
	mov eax,1			; 1 => exit
	mov ebx,0			; 0 code de sortie
	int 80h				;fin ^^

Conclusion

petite note :
voila pour certain cela paraitra logique mais bon ....
eax => syscall appelé
ebx => argument 1
ecx => argument 2
edx => argument 3
Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

16 juillet 2006 20:22:10 :
zip
  • signaler à un administrateur
    Commentaire de sheorogath le 16/07/2006 20:34:53 administrateur CS

    je suis ouvert a tout commentaire/blame/eloge/question
    si vous voulez la liste des interruption linux j'ai un pdf (envoyez moi un mp avec votre mail)

    je sais que le code est simple mais impossible de trouver un equivalent sur le net donc voila ^^

  • signaler à un administrateur
    Commentaire de patatalo le 17/07/2006 01:21:50 administrateur CS

    salut,


    c'est de l'asm 32, et en plus, il y a peu de code linux, c'est donc toujours interessant ne serait-ce que pour les débutants.

    une petite erreur qui doit je pense se corriger toute seule grace a l'alignement DWORD:
    mov edx,buflen -> movzx edx,byte buflen (tu déclare un db et pas un dd)

    @++

  • signaler à un administrateur
    Commentaire de patatalo le 17/07/2006 01:30:21 administrateur CS

    re,


    a moins que la valeur a mettre dans edx ne soit un pointeur vers la taille mais je pense que la valeur devrait etre en dword et pas en byte à ce moment, c'est corrigé grace a l'alignement mais si tu met une autre déclaration dans le segment data, ça ne marche plus.

    @++

  • signaler à un administrateur
    Commentaire de patatalo le 17/07/2006 10:16:58 administrateur CS

    re,




    je ne devais pas etre réveillé hier soir, un db avec une valeure de 1024 c'est impossible (0..255). Ce code ne doit pas se compiler sans generation d'une erreur.

    @++

  • signaler à un administrateur
    Commentaire de sheorogath le 17/07/2006 10:20:30 administrateur CS

    merci je regarde le tout merci bcp
    ca va peut etre m'aider pour le probleme sur mon nouveau prog
    asm :p

    allez merci je regarde

    ++

  • signaler à un administrateur
    Commentaire de sheorogath le 17/07/2006 11:52:35 administrateur CS

    re, ^^
    si j'ai bien compris (ne pouvant tester de suite :() il faut que je remplace mon db par dd ?

  • signaler à un administrateur
    Commentaire de necromagik le 25/07/2006 12:18:00

    Salut

    Pas forcément un dd, un dw peut aller.

    Voilà les correspondances (je te met aussi l'équivalent en C..)

    (unsigned char) - db: 1 octet - 256 valeurs
    (unsigned short int) - dw: 2 octets - 65535 valeurs
    (unsigned int) - dd: 4 octets - 4 milliards et quelques

  • signaler à un administrateur
    Commentaire de sheorogath le 25/07/2006 19:45:40 administrateur CS

    ok merci de ton aide ^^
    actuellement je bosse pendant mon temps libre sur une autre source linux qui seras poster mais je galere
    je prendrais en compte tes conseil
    merci

  • signaler à un administrateur
    Commentaire de _dune2_ le 25/07/2006 23:08:15

    bonjour,
      je confirme le raisonnement de Patalo ainsi que de Necromagik.
    Je souhaite juste apporter une précision au message de Necromagik :
    edx est un registre 32bits. Pour cette raison, l'utilisation de "dd" pour reserver la variable semble plus adapté. Mais l'utilisation de "dw" reste possible, à la différence que c'est une reservation d'un mot 16bits et qu'il faudra utiliser l'intruction "movzx" comme le mentionnait Patalo pour 'étendre' (movzx = mov with zero extension) ta variable 16bits en 32bits dans le registre "edx" en complétant avec des zéro.

    une autre solution à ton exemple pour se passer du stockage de la longueur est d'utiliser la soustraction de 2 pointeurs pour calculer la taille de celui-ci dans ton code au moment de la compilation :

    ; Instruction de compilation :
    ; NASM -f elf hello_world.asm
    ; ld -o hello_world hello_world.o
    ;segment .data ;               ; variables initialisées constantes
    ;   buflen: db 1024 ; taille du buffer
    segment .bss
       buf:        resb    1024 ; buffer
       buflen:
    ; on utilisera la soustraction des 2 pointeurs buf et buflen pour calculer
    ; la taille de buf au moment de la compilation, ce qui évite tout risque
    ; de modification inattendu de buflen en mémoire
    segment .text           ; équivalent de main() mais c'est pas une fonction
                            ;   global _start
    _start:                 ; programme en lui même
       mov eax,3            ;syscall 3 => read
       mov ebx,0            ; 0 => lit le clavier
       mov ecx,buf          ;dans quoi on stock
       mov edx,buflen-buf   ;taille du buffer calculé à la compilation
       int 80h              ;on execute en appelant la syscall
       mov eax,4            ;syscall 4 => write
       mov ebx,1            ;1 => STDOUT
       mov ecx,buf          ; ecrire quoi ? buf
       mov edx,buflen-buf   ;taille du buffer calculé à la compilation
       int 80h              ;appel de syscall
       mov eax,1            ; 1 => exit
       mov ebx,0            ; 0 code de sortie
       int 80h              ;fin

    dune2.

  • signaler à un administrateur
    Commentaire de _dune2_ le 25/07/2006 23:23:39

    Ooops :)
    Y-a un warning à la compilation du à la ligne :
    ;   global _start

    Il faut retirer le point-virgule de commentaire ... bon ceci dit, y-a qu'un seul _start et le compilo s'en sort plutot bien tout seul :)

    dune2

    PS: je tiens à exprimer quand même un doute, si quelqu'un peut confirmer, sur la ligne "mov edx,buflen" du code original. En effet, pour moi, ceci aurait pour effet de charger l'adresse "buflen" et non contenu 1024. Pour charger la valeur "1024", j'écrirais plutot : "mov edx,[buflen]" pour charger le contenu de l'adresse buflen (avec les apports de commentaires concernant l'utilisation de movzx bien entendu).

  • signaler à un administrateur
    Commentaire de patatalo le 26/07/2006 15:49:32 administrateur CS

    salut,




    un dd est obligatoire dans le code de sheorogath étant donné qu'apparement, edx est un pointeur vers la taille.

    si c'est la taille qui doit etre dans edx, il faut faire
    mov edx,[buflen] ou comme precedement mov edx,buflen-buff avec le code donné par _DUNE2_

    faudrait dejà connaitre les paramètres à passer a la fonction systeme eax=4, ensuite, faut voir...

    @++

  • signaler à un administrateur
    Commentaire de _dune2_ le 26/07/2006 16:57:47

    salut,
      les arguments à passer en parametres sont :
    eax: N° du syscall (4 pour le write)
    ebx: N° du filedescriptor (1 pour stdout)
    ecx: Pointeur vers le buffer de la chaine
    edx: taille de la chaine à afficher

    Donc, Patalo confirme bien la nécessité d'utiliser "mov edx,[buflen]" si buflen est déclaré en "dd",
    ou alors "movzx edx,byte[buflen]" dans le cas où buflen est déclaré "db".

    Suite à des essais de compilations suivi de désassemblage, j'ai constaté la chose suivante :
    l'utilisation de label pour réaliser un adressage indirect ne fonctionne pas.
    Je m'explique :

    "mov edx,[buflen]" donne le même résultat que "mov edx,buflen", or ce n'est pas ce que l'on souhaite !
    Dans notre cas, c'est le contenu de l'adresse buflen que nous voulons mettre dans edx, il faut donc proceder
    en 2 étape :

    "mov edx,buflen"
    "mov edx,[edx]"

    Ainsi, aprés désassemblage, le résultat est correct :)

    et pour le cas de buflen en "db"
    "mov edx,buflen"
    "movzx edx,byte[edx]"

    Ce qui change quelque peu le source original :) Mais, me dira-t-on, pourquoi alors ça fonctionnait ???
    Tout simplement car à la place de la taille, nous avions une adresse qui est largement plus grand que la taille de la chaine, mais que la fonction write s'arrête aussi au 1er caractere null de fin de chain, donc bien avant notre taille de chaine éronée.

    dune2.

  • signaler à un administrateur
    Commentaire de sheorogath le 26/07/2006 20:57:54 administrateur CS

    woaw merci a tous !!!
    je vais tout reprendre alors :s

    merci encore
    bonne soiree

  • signaler à un administrateur
    Commentaire de patatalo le 27/07/2006 00:22:11 administrateur CS

    re,



    c'est bien de nasm que l'on parle ?

    mov edx,buflen -> edx = adresse de la variable buflen
    mov edx,[buflen] -> edx = valeur dword a l'adresse buflen

    si tu obtient la meme chose au desassemblage, verifie que tu n'ai pas compilé deux fois la meme chose.

    tiré de la doc de nasm (Writing 32bits code):

    At the other end of the process, to call a C function from your assembly code, you would do something like this:


    extern  _printf

            ; and then, further down...

            push    dword [myint]   ; one of my integer variables
            push    dword mystring  ; pointer into my data segment
            call    _printf
            add     esp,byte 8      ; `byte' saves space

            ; then those data items...

    segment _DATA

    myint       dd   1234
    mystring    db   'This number -> %d <- should be 1234',10,0

    @++

  • signaler à un administrateur
    Commentaire de _dune2_ le 27/07/2006 13:55:18

    re :)

    Aprés plusieurs essais, ... je reste perplexe :)
    Je ne sais plus vraiement où se cache la vérité ....
    Je m'explique :
    - Code d'exemple :

    monadresse: dd 0
    _start:
            mov edx,monadresse
            mov edx,[monadresse]

            mov edx,monadresse
            mov edx,[edx]

            mov eax,1
            mov ebx,0
            int 80h

    Et voilà le désassemblage de nasm (ndisasm -b32) :

    00000083  00BA80800408      add [edx+0x8048080],bh  <- décalage de 1 byte ....
                                                           démarrage @00000084 = "mov edx,0x8048080"
    00000089  8B1580800408      mov edx,[0x8048080]
    0000008F  BA80800408        mov edx,0x8048080
    00000094  8B12              mov edx,[edx]
    00000096  B801000000        mov eax,0x1
    0000009B  BB00000000        mov ebx,0x0
    000000A0  CD80              int 0x80

    Ce qui semble tout à fait exact.
    Maintenant avec objdump :

    8048084:       ba 80 80 04 08          mov    $0x8048080,%edx   <- @ de départ correct
    8048089:       8b 15 80 80 04 08       mov    0x8048080,%edx
    804808f:       ba 80 80 04 08          mov    $0x8048080,%edx
    8048094:       8b 12                   mov    (%edx),%edx
    8048096:       b8 01 00 00 00          mov    $0x1,%eax
    804809b:       bb 00 00 00 00          mov    $0x0,%ebx
    80480a0:       cd 80                   int    $0x80

    Mais à priori une subtilité dans la notation porte à confusion, l'absence de '$' devant une adresse semble indiquer la présence d'un pointeur vers la valeur ....

    Ceci explique ma confusion ... et donc confirme que l'utilisation de "mov edx,[buflen] est tout à fait correct, et j'en prend note ;)

    Merci pour cette mise au point ;)

  • signaler à un administrateur
    Commentaire de patatalo le 27/07/2006 14:26:13 administrateur CS

    salut,



    le probleme est que tu dois specifier l'offset de debut de desassemblage avec ndisasm car sinon, il commence a 0x00000080 au lieu de 0x00000084.

    etant donné que tu a un dword data a 0x00000080, ndisasm le prends comme faisant partie du code si non spécifié et tu te retrouve avec:
    00000080 000000       add truc,bidule
    00000083 00BA80800408 add [edx+0x8048080],bh
    00000089 8B1580800408 mov edx,[0x8048080]

    ce code serait correctement désassemblé par ndisasm:
    _start:
            mov edx,monadresse
            mov edx,[monadresse]

            mov edx,monadresse
            mov edx,[edx]

            mov eax,1
            mov ebx,0
            int 80h

    monadresse: dd 0

    je me rappelle plus l'option pour specifier l'offset ou commencer le desassemblage, "ndisasm" tout court dans une console doit te l'afficher.

    @++

  • signaler à un administrateur
    Commentaire de _dune2_ le 27/07/2006 14:44:47

    salut,
      merci pour cette précision.
    En fait j'ai oublié de mettre les indicateurs de segment, c'est pourquoi les data se trouve en début du segment de code (et c'est pas beau du tout !! :) surtout si on gère le bit de protection d'écriture et execution des zones mémoires !!!).

    Mais je garde l'astuce de mettre les variables en fin de code, pour des embryons de test.

    dune2.

Ajouter un commentaire

Pub



Appels d'offres

Dessins techniques
Budget : 60€
Animation Flash - Doma...
Budget : 370€
Application flash medi...
Budget : 1 000€

CalendriCode

Juillet 2008
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

VS Express FR Gratuit !

VS Express en français et 100% gratuit !

Téléchargements

Boutique

Boutique de goodies CodeS-SourceS