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 :

[NASM 64 bits][Linux] Soucis de récupération d'arguments en ligne de commande


Sujet :

x86 32-bits / 64-bits Assembleur

  1. #1
    Membre averti

    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2012
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2012
    Messages : 313
    Points : 354
    Points
    354
    Par défaut [NASM 64 bits][Linux] Soucis de récupération d'arguments en ligne de commande
    J'ai ceci, mais le compilateur m'a envoyé peté à la ligne 2

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    recupererarguments:
    	pop DWORD [ArgPtrs + edx*4]			; récupérer les arguments et les placer dans ArgPtrs
    	inc edx
    	cmp edx,ecx
    	jb recupererarguments
    ArgPtrs était à la base défini comme étant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    MAXARGS		equ		3
    ArgCount	resd	1
    ArgPtrs		resd	MAXARGS
    ArgLens		resd	MAXARGS
    Le message d'erreur était: "instruction not supported in 64-bit mode"
    Du coup, je me suis dit bin il faut tout mettre en QWORD...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    MAXARGS		equ		3
    ArgCount	resd	1
    ArgPtrs		resq	MAXARGS
    ArgLens		resd	MAXARGS
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    recupererarguments:
    	pop QWORD [ArgPtrs + edx*8]			; récupérer les arguments et les placer dans ArgPtrs
    	inc edx
    	cmp edx,ecx
    	jb recupererarguments
    ...et bin non, le compilateur ne bronche plus mais ArgPtrs pointe sur rien de valide...

    En me documentant un peu, il semblerait que "les choses aillent changé" avec le 64-bit mode... concernant le passage de paramètres en ligne de commande.
    Cependant je n'arrive pas du tout à capter comment procéder avec rsi comme dans l'exemple donné ici:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    mov   rdi, [rsi] ; copier un argument dans rdi
    add    rsi,8  ; passer à l'argument suivant
    dec    rdi ;
    ...apparemment les arguments sont passés via rsi en 64-bit mode, ecx contient toujours le nombre de paramètres (argc).
    Cependant j'aimerais "sauvegarder" les différents paramètres en vue d'opérer quelque chose comme atoi() sur ceux-ci pour les convertir en entiers.

  2. #2
    Membre averti

    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2012
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2012
    Messages : 313
    Points : 354
    Points
    354
    Par défaut
    Voilà ce que j'ai pour le moment... je tripatouille un peu avec EBP mais sans obtenir de succès...

    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
    ; ecx devrait contenir le nombre d'arguments
     
    	pop rcx
    	cmp rcx,MAXARGS
    	ja fin
    	cmp rcx,0
    	jz ErrorNoParams
     
    	mov DWORD [ArgCount],ecx
    	xor edx,edx
     
     
    recupererarguments:
    	; pop QWORD [ArgPtrs + edx*8]			; récupérer les arguments et les placer dans ArgPtrs
     
    	pop rsi
    	;sub rsp,8
     
    	mov rdi,ArgPtrs
     
    	; rsi contient la chaîne que l'on va copier
     
    	push rdx
    	push rcx
     
    	xor rcx,rcx
    	mov ecx,0000ffffh
    	cld
    copierdatas:
    	lodsb											; va charger un byte de rsi et le mettre dans al
    	stosb											; on va mettre le caractère de al dans ArgPtrs
     
    	cmp al,0	
    	jne copierdatas						; tant que '\0' pas trouvé on continue...
     
    	pop rcx
    	pop rdx
     
    	; ici j'ai des données correctes mais je n'arrive pas à faire un déplacement 
    	; en mémoire du style C --> ArgPtrs[edx] (edx*8)
    	; la prochaine boucle va ECRASER le contenu de ArgPtrs :{
     
    	inc edx
    	mov ebp,[ArgPtrs+edx*8]
    	mov [ArgPtrs],ebp
     
    	cmp edx,ecx
    	jb recupererarguments
     
    	xor eax,eax
    	xor ebx,ebx

  3. #3
    Membre régulier
    Homme Profil pro
    retraité
    Inscrit en
    Avril 2019
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : retraité

    Informations forums :
    Inscription : Avril 2019
    Messages : 49
    Points : 70
    Points
    70
    Par défaut
    Bonjour.
    Normalement on n'utilise pas les instructions pop et push pour manipuler les données de la pile, on les réserve pour sauvegarder les registres.
    Il est préférable d'utiliser le registre de base rbp comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    _start:
        mov rbp,rsp
        mov rdx,[rbp]     ; récup du nombre de paramètre
        cmp rdx,2         ; < à 2
        jl .A3            ; erreur
        mov rsi,[rbp+16]  ; récup adresse du premier paramètre
    Et à mon avis il est inutile de recopier les paramètres ailleurs car on peut les utiliser directement.

  4. #4
    Membre averti

    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2012
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2012
    Messages : 313
    Points : 354
    Points
    354
    Par défaut
    Un bien grand merci... je ne maîtrise pas du tout l'Assembler et quand je voudrais faire quelque chose comme:

    + récupérer des paramètres en ligne de commande
    + les convertir en entiers positifs (pour le moment)
    + diviser un nombre par l'autre
    + afficher le résultat de l'opération avec une certaine précision

    ...j'ai un peu de mal.

    Pour l'instant je n'ai que la division, et encore, elle est limitée à 16bits ^^

    Merci Vincent ^^

  5. #5
    Membre régulier
    Homme Profil pro
    retraité
    Inscrit en
    Avril 2019
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : retraité

    Informations forums :
    Inscription : Avril 2019
    Messages : 49
    Points : 70
    Points
    70
    Par défaut
    Re bonjour.
    Pourquoi une division en 16 bits ? Une simple division 64 bits fonctionne aussi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
        mov rax,12345678912345678
        mov rbx,11
        mov rdx,0
        div rbx
    donne le résultat dans rax : 1122334446576879

    Pour la conversion d'une chaine de caractères en nombre il faut :
    initialiser nombre à 0
    debutboucle:
    lire un octet de la chaine (c'est un code ascii)
    le convertir en nombre1 en enlevant 48
    Multiplier nombre par 10
    ajouter nombre1
    octet suivant
    et boucler tant que le zero binaire de fin de chaine n'est pas trouvé

    Il faut aussi vérifier que la multiplication n'est pas en overflow au cas ou le contenu de la chaine est très important (> à 2 puissance 63)
    Et vérifier que chaque octet lu est dans la tranche 0-9 sinon la saisie de 123AB5678 entraine un résultat faux.

    Bon courage.

Discussions similaires

  1. [NASM 64 bits] Problèmes d'assemblage de code 32 bits
    Par Jordy89 dans le forum x86 32-bits / 64-bits
    Réponses: 8
    Dernier message: 14/01/2009, 21h22
  2. Souci avec récupération données ds DTPicker
    Par Aless75 dans le forum Macros et VBA Excel
    Réponses: 13
    Dernier message: 24/09/2008, 11h59
  3. [DB2 64-bit Linux] souci avec l'utilitaire db2cc ?
    Par cyberioio dans le forum DB2
    Réponses: 1
    Dernier message: 14/04/2006, 09h48
  4. Réponses: 10
    Dernier message: 13/03/2006, 14h30
  5. Soucis de récupération de code
    Par sheira dans le forum ASP
    Réponses: 16
    Dernier message: 06/12/2004, 11h42

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