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:
Mais en x64, en faisant ça je segfault:mov dword [eax+4],0x1
mov dword [eax+8],0x1
etc ..
En faisant ça, segfault égalementmov dword [eax+4],0x1
Le seul moyen de ne pas segfault est de faire comme ça:mov dword [rax+4],0x1
En déplaçant la pile dans rax ça fonctionne.mov rax,rsp
mov dword [rax+4],0x1
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:
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,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]
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
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
Pourquoi appeler les sockets avant getaddrinfo ne fonctionne pas ?
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
Sachant que ça fonctionne parfaitement en x32 (je peux faire plusieurs call entre mon "socket"et mon "connect" sans problème).
Partager