Не работает асемблерная вставка в Си, ошибка сегментирования
Пытаюсь вычислить мат ожидание, используя ассемблерную вставку, но к сожалению не могу заставить цикл работать.
До добавления перехода по loop'ам, выдавал результат одной итерации ассемблерной вставки (сложения первых 2 чисел), например, если вводить 3,4,5,6, то выдавало 12. Но это уже не актуально.
Компилятор - gcc.

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
int main( ) { // int должна возвращать main()
int i, n;
int *p_n = &n;
float sum = 0, d = 0;// z, r;
float *p_sum = ∑ // указатель на sum
printf( "введите Количество элементов \n" );
scanf( "%d", &n );
float * ar1= (float*) malloc( n*sizeof(float) );
float * ar2= (float*) malloc( n*sizeof(float) );
/*if ( n <= 1 || n > MAX_SIZE ) {
printf( "Error\n" );
return EXIT_FAILURE;
}*/
printf( "sum = (до заполнения) %f \n", sum );
printf( "p_sum = (до заполнения) %f \n", p_sum );
printf( "p_n = (до заполнения) %d \n", p_n );
printf( "n = (до заполнения) %d \n", n );
printf( "Введите элементы массивов\n" );
for ( i = 0; i < n; i++ ){
printf( "ar1[ %d ] ", i );
if (!scanf("%f", &ar1[i])){ printf("Ошибка ввода! Нужно писать чиселки\n"); return
0;}
//scanf( "%lf", &ar1[ i ] );
printf( "ar2[ %d ] ", i );
if (!scanf("%f", &ar2[i])){ printf("Ошибка ввода! Нужно писать чиселки\n"); return
0;}
// scanf( "%lf", &ar2[ i ] );
}
for ( i = 0; i < n; i++ ) {
printf( "ar1[ %d ] = %f \n", i , ar1[i]);
printf( "ar2[ %d ] = %f \n", i , ar2[i]);
}
printf("до цикла for\n");
printf( "sum = %f \n", sum );
printf( "p_sum = %f \n", p_sum );
printf( "p_n = %d \n", p_n );
printf( "n = %d \n", n );
// for ( i = 0; i < n; i++ )
// sum += ar1[ i ] * ar2[ i ];
asm // поиск мат ожидания
(
".intel_syntax noprefix\n" /*Синтаксис Intel, допускается опускать % перед
именами регистров*/
"\n\tmov rax, %1" // заносим в начало адреса x в памяти
"\n\tmov rbx, %2" // заносим в начало адреса p в памяти
"\n\tmov rdx, %3" // заносим в регистр размер массивов
// "\n\tmovss xmm0, [%0]" // заносим sum //или обращаемся по
ссылке
"\n\tmov rcx, -1" // заносим в счетчик -1, чтобы нулевой элемент
массива не пропустить
"\n\tloop1:" // переход к след элементу
"\n\tinc rcx" // увеличиваем счетчик по элементам
"\n\tlea r8, [rax+4*rcx]" // заносим в r8 адрес элемента из массива x,
учитывая его сдвиг по циклу
"\n\tmovss xmm1, [r8]" // в xmm1 заносим значение элемента массива
"\n\tlea r8, [rbx+4*rcx]" // заносим в r8 адрес элемента из массива p,
учитывая его сдвиг по циклу
"\n\tmovss xmm2, [r8]" // в xmm2 заносим значение элемента массива
"\n\tmulss xmm1, xmm2" // умножаем p*x, результат записывается в xmm1
"\n\taddss xmm0, xmm1" // складываем sum + p*x
"\n\tcmp rcx, rdx" // сравниваем счетчик с размером
"\n\tje loop2" // и если они равны, то завершаем, переходим к
loop2
"\n\tjmp loop1" // если дошло до этой строки, то переходим к след
элементу
"\n\tloop2:"
"\n\tmovss [%0], xmm0 "
: //"=r"(p_sum) /*выходные операнды, нумеруются с нуля (r: для выбора регистра
компилятором, иначе указывается конкретный регистр)*/
: "r"(p_sum) , "r"(ar1) , "r"(ar2) , "r" (p_n) /*входные операторы, нумерация
продолжается, указание аналогично*/
: "%rax", "%rbx", "%rdx", "%rcx", "%xmm0", "%xmm1", "%xmm2" , "%xmm3" ,"memory",
"cc" /*разрушаемые регистры (в формате: %имя)*/
);
printf("после цикла for\n");
printf( "sum = %f \n", sum );
printf( "p_sum = %f \n", p_sum );
printf( "p_n = (после заполнения) %d \n", p_n );
printf( "n = (после заполнения) %d \n", n );
printf( "Мат ожидание= %f \n", p_sum );
free(ar1);
free(ar2);
return 0;
}