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 :

[Linux x64, YASM] function equivalent a strlen


Sujet :

x86 32-bits / 64-bits Assembleur

  1. #1
    Rédacteur
    Avatar de eclesia
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    2 108
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 108
    Points : 3 203
    Points
    3 203
    Par défaut [Linux x64, YASM] function equivalent a strlen
    Bonjour,

    J'essai d'ecrire une fonction qui equivaut a 'strlen' pour connaitre la longue d'un des parametres donné a mon application.
    Malheureusement j'obtiens toujours une valeur de zero.
    Si quelqu'un a une petite idée de ce qui ne va pas dans ce morceau de code j'en serais reconnaissant.

    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
    75
    76
     
     
    section .data
    	message: 	db 'Eria Bootstrap',10,13,0
     
    section .bss
     
    section .text
    	global _start
     
     
    ;========================================== System functions =====================================================
     
    _system.quit:
    	mov 	rax, 60
    	mov 	rdi, 0
    	syscall
     
     
    _system.argumentLenght:
    	; function convention : enter ------------------------------------------+
    	push 	rbp     	; Save the old base pointer value.		|
    	mov 	rbp, rsp 	; Set the new base pointer value.		|
    	sub 	rsp, 0		; Make room for local variables.		|
    	push 	rbx		; \						|
    	push 	rcx		; | Save the values of registers which 		|
    	push 	rdx		; | might be modified.				|
    	push 	rdi		; |						|
    	push 	rsi		; /						|
    	; ----------------------------------------------------------------------+
     
    	mov 	rdi, 16
    	add	rdi, rbp	; ARG 0 -> argument pointer to measure
     
            mov     al, [rdi]	; first 8bit caractere
    	mov 	rax, 0		; counter
     
    	begin:
    		cmp	al, 0
    		je 	en
    		add 	rax, 1
    		mov 	al, [rdi+rax]
    		jmp	begin
    	en:
     
    	;result is in rax
     
    	; function convention : quit -------------------------------------------+
    	pop	rsi      	; \						|
    	pop	rdi		; |						|
    	pop	rdx		; | Restore registry values.			|
    	pop	rcx		; |						|
    	pop	rbx		; /						|
    	mov 	rsp, rbp 	; Deallocate local variables			|
    	pop 	rbp 		; Restore the caller's base pointer value	|
    	ret			; return					|
    	; ----------------------------------------------------------------------+
     
    ;======================================== Main application ========================================================
    _start:
    	;read arguments
    	pop 	rdi	;number of arguments
    	pop	rdi	;program name
    	pop	rdi	;first argument, we expect this to be the code to parse
     
    	push 	rdi
    	call _system.argumentLenght
    	add 	rsp, 16
    	mov	rdx, rax
     
    	mov 	rsi, rdi
    	mov 	rax, 1
    	mov	rdi, 1
    	syscall
     
    	call	_system.quit
    Systèmes d'Informations Géographiques
    - Projets : Unlicense.science - Apache.SIS

    Pour un monde sans BigBrother IxQuick ni censure RSF et Les moutons

  2. #2
    Membre confirmé
    Homme Profil pro
    .
    Inscrit en
    Juin 2002
    Messages
    239
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : .
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2002
    Messages : 239
    Points : 567
    Points
    567
    Par défaut
    Bonjour.

    L'erreur se trouve dans l'emploi simultané de al et de rax.
    Vu que al est l'octet de bas niveau de rax, il y a forcément un conflit ...

    La solution consiste a remplacer rax par rcx comme compteur, puis à ajouter un " mov rax,rcx " en face de l'étiquette " en: ".
    Ainsi le résultat se trouvera bien dans rax au retour de la fonction.

  3. #3
    Rédacteur
    Avatar de eclesia
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    2 108
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 108
    Points : 3 203
    Points
    3 203
    Par défaut
    merci, j'ai encore du mal a me rappeller que certain registres se chevauchent.

    par contre il doit y avoir encore un probleme car la longueur retournée semble s'arreter a 6. 1 a 6 caracteres dans le parametre c'est bon, au dela toujours 6.
    Systèmes d'Informations Géographiques
    - Projets : Unlicense.science - Apache.SIS

    Pour un monde sans BigBrother IxQuick ni censure RSF et Les moutons

  4. #4
    Membre confirmé
    Homme Profil pro
    .
    Inscrit en
    Juin 2002
    Messages
    239
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : .
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2002
    Messages : 239
    Points : 567
    Points
    567
    Par défaut
    Je ne connais rien à Linux, mais il me semble qu'il y a d'autres erreurs dans le code publié.

    La séquence figurant aux lignes 32 et 33, " mov rdi, 16 " et " add rdi, rbp ",
    a pour résultat de faire pointer edi sur l'argument de la fonction.
    Mais il faut distinguer le pointeur et l'objet pointé !
    A ce stade, rdi n'est pas l'argument de la fonction, et donc rdi ne pointe pas sur la chaine à examiner.
    Il faut encore faire " mov rdi,[rdi] " pour mettre l'argument de la fonction dans rdi et pour qu'enfin rdi pointe sur la chaine.

    Par ailleurs, l'instruction " add rsp, 16 " au retour de la fonction est bizarre.
    Si elle est destinée à supprimer le paramètre de la fonction qui figure encore sur la pile, elle est fausse : un registre 64 bits utilise 8 octets et non 16.
    Il faut donc la remplacer par " add rsp, 8 ".
    De toute façon, modifier ainsi la pile n'est pas judicieux, car source d'erreurs.
    Il vaut mieux faire un " pop rdi " qui est plus simple.
    Plus propre : dépiler les paramètres au moment de sortir de la fonction.
    Cela se fait ici par un " ret 8 ".
    Mais, normalement, tout ceci doit être laissé à la charge du compilateur.
    En effet, un bon compilateur se charge de modifier rbp et rsp à l'entrée de la fonction, puis de restituer rsp et rbp et dépiler les paramètres à la sortie, pourvu qu'on lui signale qu'il y a des paramètres.
    Voir le mode d'emploi du compilateur à ce sujet ...

  5. #5
    Rédacteur
    Avatar de eclesia
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    2 108
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 108
    Points : 3 203
    Points
    3 203
    Par défaut
    Citation Envoyé par Prof Voir le message
    Je ne connais rien à Linux, mais il me semble qu'il y a d'autres erreurs dans le code publié.

    La séquence figurant aux lignes 32 et 33, " mov rdi, 16 " et " add rdi, rbp ",
    a pour résultat de faire pointer edi sur l'argument de la fonction.
    Mais il faut distinguer le pointeur et l'objet pointé !
    A ce stade, rdi n'est pas l'argument de la fonction, et donc rdi ne pointe pas sur la chaine à examiner.
    Il faut encore faire " mov rdi,[rdi] " pour mettre l'argument de la fonction dans rdi et pour qu'enfin rdi pointe sur la chaine.
    décidement je suis encore loin . merci de l'avoir remarqué.

    Citation Envoyé par Prof Voir le message
    Par ailleurs, l'instruction " add rsp, 16 " au retour de la fonction est bizarre.
    Si elle est destinée à supprimer le paramètre de la fonction qui figure encore sur la pile, elle est fausse : un registre 64 bits utilise 8 octets et non 16.
    Il faut donc la remplacer par " add rsp, 8 ".
    De toute façon, modifier ainsi la pile n'est pas judicieux, car source d'erreurs.
    Il vaut mieux faire un " pop rdi " qui est plus simple.
    Plus propre : dépiler les paramètres au moment de sortir de la fonction.
    Cela se fait ici par un " ret 8 ".
    Mais, normalement, tout ceci doit être laissé à la charge du compilateur.
    En effet, un bon compilateur se charge de modifier rbp et rsp à l'entrée de la fonction, puis de restituer rsp et rbp et dépiler les paramètres à la sortie, pourvu qu'on lui signale qu'il y a des paramètres.
    Voir le mode d'emploi du compilateur à ce sujet ...
    Mon but est d'éviter le compilateur. c'est un petit programme de bootstrap que j'essai de réaliser.

    Je cherche a obtenir un minimum de fonctionnalité dont on pourra déduire les autres.

    types :
    - naturel (taille d'un registre)
    - bytearray ( 4Byte pour indiquer la taille puis la chaine

    logiques :
    - Not
    - Shift
    - And

    branchement :
    - jump
    - jump zero

    memoire :
    - allocation
    - desallocation

    tout ca pour ensuite faire un parser pour une sorte de langage qui ressemble a de l'assembleur mais serait cross-platform. bref le strict minimum pour obtenir quelque chose de portable.

    objectif final : (m'amuser) et faire le premier compilateur pour HelenOS
    Systèmes d'Informations Géographiques
    - Projets : Unlicense.science - Apache.SIS

    Pour un monde sans BigBrother IxQuick ni censure RSF et Les moutons

  6. #6
    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
    forth

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. asm Linux x64
    Par n5Rzn1D9dC dans le forum x86 32-bits / 64-bits
    Réponses: 3
    Dernier message: 22/08/2013, 18h15
  2. jdk-7u9-linux-x64.rpm centos 6.3
    Par Malatok dans le forum RedHat / CentOS / Fedora
    Réponses: 1
    Dernier message: 29/12/2012, 20h14
  3. [linux x64, NASM] erreur segfault sur tout les appels syscall
    Par eclesia dans le forum x86 32-bits / 64-bits
    Réponses: 6
    Dernier message: 15/01/2012, 11h50
  4. Build du package leaps LINUX X64
    Par statquant dans le forum R
    Réponses: 0
    Dernier message: 21/06/2010, 21h45
  5. Applicatifs equivalent MS exchange sous linux
    Par MarcG dans le forum Applications et environnements graphiques
    Réponses: 5
    Dernier message: 13/04/2004, 17h57

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