	.file	"seconddegre.c" #nom du fichier C
	.section	.rodata
.LC1:
	.string	"entrez a\n:" 
.LC2:
	.string	"%d"
.LC3:
	.string	"entrez b\n:"
.LC4:
	.string	"entrez c\n:"
.LC5:
	.string	"Delta:%f \n"
.LC6:
	.string	"sqrt(delta): %f \n"
	.align 8
.LC7:
	.string	"les deux solution sont:%f et %f"
.LC8:
	.string	"pas de solution\n"
	.text
	.globl	main
	.type	main, @function
main:
.LFB0:
	.cfi_startproc #début de la fonction main
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp #on met %esp et %ebp au même niveau de la pile (dans ce programme %rsp = %esp et %rbp = %ebp car j'ai fais le programme sur mon ordinateur portable)
	.cfi_def_cfa_register 6
	subq	$64, %rsp
	movl	%edi, -36(%rbp)
	movq	%rsi, -48(%rbp)
	movl	$1, -20(%rbp)
	movl	$0x00000000, %eax
	movl	%eax, -16(%rbp) 
	
	movl	$.LC1, %eax #on insère le contenu de l'étiquette .LC1 dans %eax
	movq	%rax, %rdi #on envoit le contenu de %rax dans %rdi
	movl	$0, %eax # on remet %eax à 0
	call	printf #cette ligne appelle la fonction printf
	#ces lignes correspondent au printf("entrez a\n:");
	
	movl	$.LC2, %eax #on insère le contenu de l'étiquette .LC2 dans %eax
	leaq	-32(%rbp), %rdx #On ne veut pas le contenu de %ebp à l'adresse -32 de la pile mais son adresse, d'ou l'instruction leaq (%rdx est le registre utilisé pour afficher ou saisir)
	#... qui copiera alors l'adresse -32 de %rbp dans %rdx
    movq	%rdx, %rsi #on insère le contenu de %rdx dans %rsi
	movq	%rax, %rdi # #on envoit le contenu de %rax dans %rdi
	movl	$0, %eax # on remet %eax à 0
	call	__isoc99_scanf #appel de la fonction scanf
	#correspond à scanf("%d", &a);
	
	movl	$.LC3, %eax  #on insère le contenu de l'étiquette .LC3 dans %eax
	movq	%rax, %rdi  #on envoit le contenu de rax dans rdi	
	movl	$0, %eax # on remet %eax à 0
	call	printf #appel de la fonction printf
	#correspond à printf("entrez b\n:");
	
	movl	$.LC2, %eax #on insère le contenu de l'étiquette .LC2 dans %eax
	leaq	-28(%rbp), %rdx #ici on dit que le registre rdx utilisé pour les affichages et les saisis est associé en position -28 de %rbp	
	movq	%rdx, %rsi #on insère le contenu de rdx dans rsi
	movq	%rax, %rdi # on insère le contenu de rax dans rdi
	movl	$0, %eax # on remet eax à 0
	call	__isoc99_scanf #appel de la fonction scanf
	# correspond à scanf("%d", &b)
	
	movl	$.LC4, %eax #on insère le contenu de l'étiquette .LC4 dans %eax 
	movq	%rax, %rdi #on insère le contenu de %rax dans %rdi
	movl	$0, %eax #on remet %eax à 0
	call	printf # appel de la fonction printf
	#ce bloc d'instruction correspond à printf("entrez c\n:");
	
	movl	$.LC2, %eax # on insère le contenu de l'étiquette .LC2 dans %eax
	leaq	-24(%rbp), %rdx #ici on dit que le registre rdx utilisé pour les affichages et les saisis est associé en position -24 de %rbp	
	movq	%rdx, %rsi #on insère le contenu de rdx dans rsi
	movq	%rax, %rdi # on insère le contenu de rax dans rdi
	movl	$0, %eax # on remet eax à 0
	call	__isoc99_scanf # appel de la fonction scanf
	# correspond à scanf("%d", &c);
	
	movl	-28(%rbp), %edx #on insère le contenu de l'adresse -28 du registre %rbp dans le registre edx (on met la valeur de b dans edx)
	movl	-28(%rbp), %eax #on insère le contenu de l'adresse -28 du registre %rbp dans le registre eax (on met la valeur de b dans edx) 
	imull	%eax, %edx #on multiplie eax par edx (b*b) le résultat est copié dans edx
	movl	-32(%rbp), %ecx #idem ,on insère la valeur de c dans ecx
	movl	-24(%rbp), %eax #idem, on insère la valeur de a dans eax
	imull	%eax, %ecx #on multiplie a*c le résultat est copié dans ecx
	movl	$0, %eax #on remet eax à 0
	subl	%ecx, %eax #on effectue la soustraction de ecx par eax, soit en C: "(b*b) - (a*c)"
	#note: je n'ai pas trouvé l'instruction qui multiplie a*c par 4, je fais alors comme si elle n'y était pas dans mon explication
	
	sall	$2, %eax #l'instruction sal (ou shl) décale vers la droite de 2 bit le nombre de eax
	addl	%edx, %eax #ajoute edx à eax et le stock dans eax
	cvtsi2ss	%eax, %xmm0 #convertit la valeur de eax en "entier de simple précision" et le met dans xmm0
	movss	%xmm0, -16(%rbp) #permet de copier une valeur "entière de simple précision" dans xmm0 depuis l'emplacement -16 de la pile
	movss	-16(%rbp), %xmm0  #permet de copier une valeur "entière de simple précision" dans l'emplacement -16 de la pile depuis xmm0
	cvtps2pd	%xmm0, %xmm0 #Cette instruction permet d'effectuer la conversion d'un paquet de valeurs réel de simple précision en paquet de valeurs réel de double précision. 
	#ici les opérations sont subit sur delta.
	
	movl	$.LC5, %eax #on insère le contenu de l'étiquette .LC5 dans eax
	
	movq	%rax, %rdi #on insère le contenu de rax dans rdi
	movl	$1, %eax #on met eax à 1
	call	printf #appel de la fonction printf
	# correspond à printf("Delta:%f \n",delta);

	movss	-16(%rbp), %xmm0 #on insère le contenu de l'adresse -16 dans xmm0
	xorps	%xmm1, %xmm1 #Cette instruction permet d'effectuer un ou exclusif binaire entre xmm1 et lui même.
	ucomiss	%xmm1, %xmm0 #Cette instruction permet d'effectuer une comparaison désordonnée de valeurs réels de simple précision entre xmm1 et xmm0
	setae	%al #on insère la valeur 1 dans le registre al si le drapeau CF (indicateur de retenu) est à 0.
	testb	%al, %al #Du coup ici, on test si le registre al est à 1.
	je	.L2 #on va à l'étiquette L2 
	movss	-16(%rbp), %xmm1 #insère dans le registre xmm1 le contenu de l'adresse -16 du registre rbp
	cvtps2pd	%xmm1, %xmm1 #Cette instruction permet d'effectuer la conversion d'un paquet de valeurs réel de simple précision en paquet de valeurs réel de double précision. 
	sqrtsd	%xmm1, %xmm0 #calcul la racine carré de xmm1 et le met dans xmm0
	ucomisd	%xmm0, %xmm0 #Cette instruction permet d'effectuer une comparaison désordonnée de valeurs réels de simple précision entre xmm0 et lui même
	jp	.L4 #on va à l'étiquette l4
	ucomisd	%xmm0, %xmm0 #Cette instruction permet d'effectuer une comparaison désordonnée de valeurs réels de simple précision entre xmm0 et lui même
	je	.L3 #on va à l'étiquette L3
	
.L4:
	movapd	%xmm1, %xmm0 #Cette instruction permet de copier le contenu de 2 paquets alignés de valeurs réel de double précision de xmm1 dans xmm0
	call	sqrt #appel de la fonction sqrt (fonction qui fait la racine carré d'un nombre passé en paramètre)
	
.L3:
	movl	$.LC6, %eax #on insère le contenu de l'étiquette .LC6 dans eax
	movq	%rax, %rdi #insère le contenu de rax dans rdi
	movl	$1, %eax #on met eax à 1
	call	printf #appel de la fonction printf
	#correspond à printf("sqrt(delta): %f \n", sqrt(delta));
	
	movl	-28(%rbp), %eax #insère le contenu b dans eax
	negl	%eax # ici on met eax en négatif (donc b devient -b en somme)
	cvtsi2sd	%eax, %xmm0 #Cette instruction permet de convertir un entier de format double mot de eax en une valeur réel de double précision et l'insère dans xmm0
	movsd	%xmm0, -56(%rbp) #On insère la valeur de xmm0 à l'adresse -56 de rbp
	movss	-16(%rbp), %xmm0 #on insère la valeur de l'adresse -16 de rbp dans xmm0
	cvtps2pd	%xmm0, %xmm0 #Cette instruction permet d'effectuer la conversion d'un paquet de valeurs réel de simple précision en paquet de valeurs réel de double précision (on convertit xmm0)
	call	sqrt #appel de la fonction racine
	
	movsd	-56(%rbp), %xmm1 #on insère la valeur de l'adresse -56 du registre rbp dans xmm1
	subsd	%xmm0, %xmm1 #On soustrait xmm1 à xmm0
	movapd	%xmm1, %xmm0 ##Cette instruction permet de copier le contenu de 2 paquets alignés de valeurs réel de double précision de xmm1 dans xmm0
	movl	-32(%rbp), %eax #on met la variable a dans eax
	addl	%eax, %eax #on ajoute eax à eax (donc on multiplie a par 2)
	cvtsi2sd	%eax, %xmm1 #Cette instruction permet de convertir un entier de format double mot de eax en une valeur réel de double précision et l'insère dans xmm1
	divsd	%xmm1, %xmm0 #On divise xmm0 par xmm1
	#les deux blocs d'instructions correspondent à r1=((-b - sqrt(delta))) /(2*a);
	
	unpcklpd	%xmm0, %xmm0 #Cette instruction permet d'effectuer un dépaquetage de la partie basse d'un réel de double précision d'un opérande source et destination de xmm0.
	cvtpd2ps	%xmm0, %xmm0 #Cette instruction permet d'effectuer la conversion d'un paquet de valeurs réel de double précision en valeurs réel de simple précision et fixe à 0 le reste du paquet.
	movss	%xmm0, -12(%rbp) #on place la valeur de xmm0 à l'adresse -12 de rbp
	movl	-28(%rbp), %eax #on place la valeur de l'adresse -28 de rbp dans eax (c'est la variable b)
	negl	%eax #on effectue la négation de eax (soit -b)
	cvtsi2sd	%eax, %xmm0 #Cette instruction permet de convertir un entier de format double mot de eax en une valeur réel de double précision et l'insère dans xmm0
	movsd	%xmm0, -64(%rbp) #On insère la valeur de xmm0 à l'adresse -64 de rbp
	movss	-16(%rbp), %xmm0 #on insère la valeur de l'adresse -16 de rbp dans xmm0
	cvtps2pd	%xmm0, %xmm0 #Cette instruction permet d'effectuer la conversion d'un paquet de valeurs réel de simple précision en paquet de valeurs réel de double précision (on convertit xmm0)
	call	sqrt #appel de la fonction sqrt
	
	addsd	-64(%rbp), %xmm0 #on additione la valeur de l'adresse -64 de rbp dans xmm0
	movl	-32(%rbp), %eax #on met la valeur de l'adresse -32 de rbp dans eax (c'est a)
	addl	%eax, %eax #on multiplie eax par 2
	cvtsi2sd	%eax, %xmm1 #Cette instruction permet de convertir un entier de format double mot de eax en une valeur réel de double précision et l'insère dans xmm1
	divsd	%xmm1, %xmm0 #On divise xmm0 par xmm1
	#correspond à r2=(-b + sqrt(delta)) /(2*a);
	
	unpcklpd	%xmm0, %xmm0 #Cette instruction permet d'effectuer un dépaquetage de la partie basse d'un réel de double précision d'un opérande source et destination de xmm0.
	cvtpd2ps	%xmm0, %xmm0 #Cette instruction permet d'effectuer la conversion d'un paquet de valeurs réel de double précision en valeurs réel de simple précision et fixe à 0 le reste du paquet.
	movss	%xmm0, -8(%rbp) #Cette instruction copie la valeur réele de simple précision stockée dans xmm0 vers l'adresse -8 du registre rbp.
	movss	-8(%rbp), %xmm1 #Copie la valeur stockée à l'adresse -8 de rbp vers xmm1.
	cvtps2pd	%xmm1, %xmm1 #Conversion de xmm1 en réel double précision.
	movss	-12(%rbp), %xmm0 #Copie la valeur contenue à l'adresse -12 de rbp vers xmm0
	cvtps2pd	%xmm0, %xmm0 #Conversion de xmm0 en réel double précision.
	movl	$.LC7, %eax #Copie du contenu de l'étiquette LC7 dans le registre eax.
	movq	%rax, %rdi #Copie du registre rax vers rdi.
	movl	$2, %eax  #La valeur 2 est attribuée aux registre eax.
	call	printf #Appel de printf
	jmp	.L5 #Saut à l'étiquette L5.
.L2:
	movss	-4(%rbp), %xmm0 #Valeur en -4 de rbp copiée vers xmm0
	cvtps2pd	%xmm0, %xmm0 #Conversion de xmm0 en réel double précision.
	movl	$.LC8, %eax #Copie du contenu de l'étiquette LC8 dans le registre eax.
	movq	%rax, %rdi #Copie du contenu de rax vers rdi.
	movl	$1, %eax #La valeur 1 est attribuée au registre eax.
	call	printf #Appel de printf
.L5:
	movl	$.LC2, %eax #Copie du contenu de l'étiquette LC2 dans le registre eax.
	leaq	-20(%rbp), %rdx #Ecrit l'adresse de -20(%rbp) dans rdx.
	movq	%rdx, %rsi 
	movq	%rax, %rdi
	movl	$0, %eax
	call	__isoc99_scanf #Appel de la fonction scanf.
	movl	$0, %eax
	leave                  #On libère la zone mémoire.
	.cfi_def_cfa 7, 8
	ret                    #On quitte la procédure
	.cfi_endproc
.LFE0:
	.size	main, .-main
	.ident	"GCC: (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1"
	.section	.note.GNU-stack,"",@progbits
