Bonjour à tous,
je continue mon périple en x86-64. Actuellement, je cherche à traiter les if-then-else ainsi que les différentes boucles imaginables.
Je vois facilement comment traiter le flux via les sauts, mais mon problème se situe au niveau des comparaisons.
Prenons le code c suivant :
si j'utilise gcc pour voir l'assembleur correspondant, il me donne :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 int main(){ int x = 1; int y = 2; int z = 3; int a, b, c, d; a = x < y; b = x == y; c = x != z; d = x <= z; return a + b + c + d; }
pour la partie utile.
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 .globl main .type main, @function main: .LFB2: pushq %rbp .LCFI0: movq %rsp, %rbp .LCFI1: movl $1, -4(%rbp) movl $2, -8(%rbp) movl $3, -12(%rbp) movl -4(%rbp), %eax cmpl -8(%rbp), %eax setl %al movzbl %al, %eax movl %eax, -16(%rbp) movl -4(%rbp), %eax cmpl -8(%rbp), %eax sete %al movzbl %al, %eax movl %eax, -20(%rbp) movl -4(%rbp), %eax cmpl -12(%rbp), %eax setne %al movzbl %al, %eax movl %eax, -24(%rbp) movl -4(%rbp), %eax cmpl -12(%rbp), %eax setle %al movzbl %al, %eax movl %eax, -28(%rbp) movl -20(%rbp), %eax addl -16(%rbp), %eax addl -28(%rbp), %eax addl -24(%rbp), %eax leave ret
Chaque comparaison se fait - de ce que je comprends - en 4 instructions :
J'ai plusieurs questions à ce propos :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 1. movl -k1(%rbp), %eax | k1 étant l'index de l'élément à gauche sur la stack 2. cmpl -k2(%rbp), %eax | k2 étant l'index de l'élément à droite sur la stack 3. set{c} %eax | c étant l'opération voulue 4. movzbl %al, %eax
1 - en me basant sur http://www.fermi.mn.it/linux/quarta/x86/cmp.htm, j'ai l'impression qu'il n'y a pas de contrainte sur quel registre appliquer la comparaison, mais gcc utilise uniquement %eax (et push tout sur la stack). Y en a-t-il pour cmpl ?
2. set{c} modifie le registre sur lequel il est appliqué, n'est-ce pas ? y a-t-il des restrictions sur le registre ?
3. de http://www.fermi.mn.it/linux/quarta/x86/movzx.htm, il semble s'agir de la même opération que movzbl, mais à quoi correspond le spécifique bl dans le nom ?
En fait, je suis surtout étonné que gcc utilise uniquement %eax et passe tout dans la pile. Est-ce le choix par défaut ? Si on est en x86-64, on a plein de registres à disposition (avec des contraintes sur certains), pourquoi ne pas les utiliser ?
Partager