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 :

asm Linux x64


Sujet :

x86 32-bits / 64-bits Assembleur

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    397
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 397
    Points : 424
    Points
    424
    Par défaut asm Linux x64
    Salut,

    Je suis passé récemment à l'asm x64 sous Linux, et je remarque que ça n'a plus rien à voir.
    Par exemple, les call fonctionnent de la même façon qu'un syscall.. Il faut utiliser parfois plusieurs registres pour un simple call..
    Moi qui faisait toujours attention à économiser des registres en x32, jusqu'à faire plusieurs calculs dans un seul registre alors que d'autres personnes en auraient utilisé plusieurs.

    Pourquoi nous "forcer" à faire des call de la même façon qu'un syscall ?
    Quel est l'intêret ?

    Ensuite, je remarque que l'asm x64 ne pardonne pas. Je fais segfault toutes les deux minutes (alors que je n'en ai jamais fait un seul en x32..).

    Il y a des choses que je ne comprend pas du tout.
    Par exemple, pour empiler dans un registre.

    En x32 je peux faire ça:
    mov dword [eax+4],0x1
    mov dword [eax+8],0x1
    etc ..
    Mais en x64, en faisant ça je segfault:
    mov dword [eax+4],0x1
    En faisant ça, segfault également
    mov dword [rax+4],0x1
    Le seul moyen de ne pas segfault est de faire comme ça:
    mov rax,rsp
    mov dword [rax+4],0x1
    En déplaçant la pile dans rax ça fonctionne.

    Mais pourquoi je ne suis pas obligé de le faire en x32 ?
    Je n'ai jamais eu à déplacer la pile dans un registre pour pouvoir empiler sur ce registre, jamais.. Ca a toujours fonctionné tel quel, et parfaitement fonctionné.
    Est-ce que ça se faisait tout seul ?

    Si vous connaissez une bonne doc sur la pile et l'empilement dans un registre en x64, je suis preneur.
    Il y a vraiment très peu de doc pour l'asm Linux x64.

    Edit:
    Un autre problème que j'ai eu, avec les sockets.

    Avec ce code, "getaddrinfo" ne fonctionne pas:
    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
     
    	mov	rdx,IPPROTO_TCP
    	mov	rsi,SOCK_STREAM
    	mov	rdi,AF_INET
    	mov	eax,_socket
    	syscall
    	mov	[sock],rax
     
    	mov	rdx,rsp
    	mov	dword [rdx],0x0
    	mov	dword [rdx+4],AF_INET
    	mov	dword [rdx+8],SOCK_STREAM
    	mov	dword [rdx+12],IPPROTO_TCP
     
    	lea	rdx,[rdx]
    	lea	rsi,[port]
    	lea	rdi,[hote]
    	xor	eax,eax
    	call	[getaddrinfo]
    Avec celui là, il fonctionne:
    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
     
    	mov	rdx,rsp
    	mov	dword [rdx],0x0
    	mov	dword [rdx+4],AF_INET
    	mov	dword [rdx+8],SOCK_STREAM
    	mov	dword [rdx+12],IPPROTO_TCP
     
    	lea	rdx,[rdx]
    	lea	rsi,[port]
    	lea	rdi,[hote]
    	xor	eax,eax
    	call	[getaddrinfo]
     
    	mov	rdx,IPPROTO_TCP
    	mov	rsi,SOCK_STREAM
    	mov	rdi,AF_INET
    	mov	eax,_socket
    	syscall
    	mov	[sock],rax
    Et voilà l'erreur que j'obtiens avec mon debuggeur pour le segfault du premier code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    WSTOPSIG: 0Bh=SIGSEGV Segmentation fault
    00007F4219B3C6C4
    00007F4219B3C6C4  > mov [r13+00],rax ; [000000000040175E]=4800001040058948
    Pourquoi appeler les sockets avant getaddrinfo ne fonctionne pas ?
    Sachant que ça fonctionne parfaitement en x32 (je peux faire plusieurs call entre mon "socket"et mon "connect" sans problème).

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    397
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 397
    Points : 424
    Points
    424
    Par défaut
    Finalement j'ai codé plusieurs autres trucs depuis et n'ai rencontré aucun problème.
    A croire que le problème vient vraiment du faite d'appeler getaddrinfo après socket.
    J'ai eu la malchance de tomber sur ce plantage dès mon premier code x64 et du coup ça m'a perturbé.

    Pour les call qui appels les registres comme avec les syscalls, au final je trouve ça bien dans un sens.
    Ca respecte un standard et au moins on est sur que chaque numéro d'argument correspondra toujours au même registre.

  3. #3
    Membre confirmé Avatar de bifur
    passe le balais et l'aspirateur
    Inscrit en
    Mars 2008
    Messages
    314
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations professionnelles :
    Activité : passe le balais et l'aspirateur

    Informations forums :
    Inscription : Mars 2008
    Messages : 314
    Points : 550
    Points
    550
    Par défaut
    pour ton probleme de segfault est ce que par hasard il n'y aurait pas eu un probleme d'alignement? (cad lire un word sur une adresse non multiple de 2 ou un dword sur une adresse de adresse non multiple de 4) rsp doit naturellement être bien aligné (multiple de 8)

    et puis je demande ça par hasard, est ce que tu aurait une bonne doc qui m'expliquerait comment ouvrir des socket tcp sous linux sans passer par une biblotheque tiers

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    397
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 397
    Points : 424
    Points
    424
    Par défaut
    A priori non, j'avais testé vite fait. Je retesterais pour voir.
    En tout cas aucun autre problème. J'ai écrit 300 lignes d'api réseau sans aucun problème, sans avoir fait d'alignement.
    Je m'y repencherais plus tard.

    Pour les sockets tu as les pages de man.
    apt-get install manpages-dev

    Il y aussi la version française: manpages-fr-dev

    Ensuite tu fais simplement un man socket, il y a vraiment tout qu'il faut.

    Tu peux appeller les socket via la libc6, ou directement par les appels systêmes:
    - int 0x80 (en x32)
    - syscall (en x64)

    Les numéros des syscalls sont dans "unistd_32.h" et "unistd_64.h".

Discussions similaires

  1. 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
  2. [Linux x64, YASM] function equivalent a strlen
    Par eclesia dans le forum x86 32-bits / 64-bits
    Réponses: 5
    Dernier message: 13/03/2012, 20h54
  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. Conversion en asm sous Linux
    Par nelob dans le forum Assembleur
    Réponses: 1
    Dernier message: 30/08/2006, 12h59

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