En regardant un code C décompilé, j'ai vu ceci :
movl -0xc(%rbp), %esi
movl %esi, -0x8(%rbp)
Cela correspond à ce code C :
x = y;
Cela m'a fait réfléchir : comment se fait-il que gcc déplace y
à %esi
et ensuite déplacer %esi
à x
au lieu de simplement bouger y
à x
directement ?
Voici l'intégralité du code C et décompilé, si cela a de l'importance :
C
int main(void) {
int x, y, z;
while(1) {
x = 0;
y = 1;
do {
printf("%d\n", x);
z = x + y;
x = y;
y = z;
} while(x < 255);
}
}
Décompilé
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movl $0x0, -0x4(%rbp)
movl $0x0, -0x8(%rbp) ; x = 0
movl $0x1, -0xc(%rbp) ; y = 1
; printf
leaq 0x56(%rip), %rdi
movl -0x8(%rbp), %esi
movb $0x0, %al
callq 0x100000f78
; z = x + y
movl -0x8(%rbp), %esi ; x -> esi
addl -0xc(%rbp), %esi ; y + esi
movl %esi, -0x10(%rbp) ; z = esi
; x = y
movl -0xc(%rbp), %esi
movl %esi, -0x8(%rbp)
; y = z
movl -0x10(%rbp), %esi
movl %esi, -0xc(%rbp)
movl %eax, -0x14(%rbp) ; not sure... I believe printf return value?
cmpl $0xff, -0x8(%rbp) ; x < 255
jl 0x100000f3d ; do...while(x < 255)
jmp 0x100000f2f ; while(1)
0 votes
Un transfert direct de mémoire à mémoire (s'il est possible dans le monde x86, je ne m'en souviens pas) nécessiterait toujours que le cœur du processeur stocke la valeur en interne d'une manière ou d'une autre dans le cadre de la lecture de la mémoire.
3 votes
Probablement parce que vous ne demandez pas au compilateur d'appliquer tout optimisations : godbolt.org/g/SKUrDo
5 votes
De plus, le code est-il construit avec ou sans optimisations ?
6 votes
Le x86 nécessite au moins une opérande de registre IIRC.
6 votes
Compiler avec les optimisations activées. Utiliser
-O2
ou-O3
0 votes
Il aide également le débogueur, de sorte que vous pouvez facilement vérifier la valeur des variables à chaque ligne de code. Avec un code optimisé, le débogueur n'a aucun moyen simple de savoir quelles variables sont stockées à quel endroit pendant le déroulement du calcul optimisé, jusqu'à ce qu'elles atterrissent dans une position cible "fixe", comme un tableau de mémoire. Mais c'est aussi un moyen assez simple (rapide) de produire un code machine fonctionnel pour une source C/C++, et si vous voulez que l'exécutable de débogage soit produit aussi rapidement que possible, il n'y a aucune raison de produire un meilleur code (en échange de la vitesse de compilation bien sûr, si c'est gratuit, alors c'est bon).
0 votes
@Someprogrammerdude oui c'est possible dans les cas comme
pop (%rax)
et évidemment avec les instructions de déplacement de la chaîne.3 votes
@StoryTeller : pas tout à fait vrai.
mov dword [mem], imm32
fonctionne, en utilisant lemov r/m, imm
codage. La limitation est que vous ne pouvez pas avoir deux modes d'adressage arbitraires (modr/m + ...) dans une instruction. Voir stackoverflow.com/questions/31904964/ . Mais vous pouvez fairepush [mem]
/pop [mem]
oumovs
pour copier de mémoire à mémoire.0 votes
Un passage direct de x à y serait impossible. Vous devez lire x et ensuite écrire y. Vous devez retenir ce que vous avez lu quelque part.
1 votes
DavidSchwartz Mauvaise couche d'abstraction. Il pourrait certainement y avoir une instruction qui effectue un transfert de mémoire à mémoire (et je peux penser à une poignée d'instructions qui font exactement cela). Le CPU pourrait avoir à le stocker dans un emplacement temporaire pour mettre en œuvre l'instruction, mais c'est un détail de mise en œuvre. De plus, grâce aux délais de propagation, il est tout à fait possible de lire et d'écrire dans un registre dans le même cycle.
0 votes
@Voo Bien sûr, il pourrait y avoir un instruction qui fait un transfert de mémoire à mémoire, mais alors quoi ? Cela nécessiterait toujours un stockage intermédiaire quelque part, et n'accomplirait toujours pas ce que le PO espère accomplir.
2 votes
@Charanor Je pense qu'il y a une erreur ici. Quand il est dit "Cela m'a fait réfléchir : comment se fait-il que gcc déplace x vers %esi puis déplace %esi vers y au lieu de déplacer x vers y directement ? devrait être "This got me thinking : how come gcc moves y to %esi and then move %esi to x instead of just moving x to y directly ?": x et y sont interchangés dans la première apparition.
0 votes
Le code que vous citez est démonté pas décompilé .