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 :
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;
}
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
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
pour la partie utile.
Chaque comparaison se fait - de ce que je comprends - en 4 instructions :

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
J'ai plusieurs questions à ce propos :

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 ?