Segment error, Assembler box in SI language
-
When compiling, the segmentation error is:
#include <stdio.h> /*средства ввода-вывода для общения с человеком*/ #include <stdlib.h> /*базовые функции программ*/ #include <stdint.h> /*типы данных с гарантируемо известным занимаемым размером в памяти*/
int main(void)
{
float a;
float b;
float c=0;
printf("a:");
scanf("%f", &a);
printf("b:");
scanf("%f", &b);
asm //находим c = a+b
(
".intel_syntax noprefix\n" /Синтаксис Intel, допускается опускать % перед именами регистров/
"\n\tmovss xmm0, [%1]" //Заносим данные в регистр
"\n\tmovss xmm1, [%2]" //Заносим данные в регистр
"\n\taddss xmm1, xmm0" //Складываем
"\n\tmovss [%0], xmm0"//Вывод данных из регистра
: "=r"(c) //Возвращаемые данные
: "r"(a), "r"(b) //Входные данные); printf("c = a+b = "); printf("%f\n", c); return 0;
}
-
Open up. http://www.club155.ru/x86cmdsimd/MOVSS team report
MOVSS
♪ It says:Team MOVSS Copy the lower packed material value from the Operanda Source (SIMD-registration or Remembrance Operand) in the lower 32-bit field of the operandi (SIMD-Registration or Remembrance Operand).
As can be seen, only SIMD-registrations (but not general-purpose registers) and memory cells can be carried out.
What's going on in your case? Let's see the team.
movss xmm0, [%1]
♪ In the outcome https://godbolt.org/z/3qdq1Yqnh%1
Replaced by a general-purpose register with a variable before ita
:mov eax, DWORD PTR [rbp-8] // Копирование значения переменной a в EAX ... movss xmm0, [eax] // Копирование из ячейки памяти с адресом, равным EAX
As you've known,
EAX
is known to be unsuitable for use as an address, as it is equal to the number of keyboards. We can use a calculator for translationfloat
16 terrain (e.g. https://gregstoll.com/%7Egregstoll/floattohex/ to better understand the address. In case of number1.0
this value will be0x3f800000
that it would not be possible to fall within the range of the programme ' s allocated address system, as a result, when trying to access the cell in the unresolved range, the hardware interruption takes place, and the control is returning the core of the operating system. Theoretically, we can find a number where the program won't fall, but it won't work properly.Which of these could be concluded? It's not the number itself, but the index is:
#include <stdio.h> /* Средства ввода-вывода для общения с человеком */ // #include <stdlib.h> /* Базовые функции программ */ // #include <stdint.h> /* Типы данных с гарантируемо известным занимаемым размером в памяти */
int main()
{
float a, b, c;printf("a:"); scanf("%f", &a); printf("b:"); scanf("%f", &b); // Определяем и инициализируем указатели float *C = &c; // %0, %1 float *A = &a; // %2 float *B = &b; // %3 asm // Вычисляем c = a + b ( ".intel_syntax noprefix \n\t" // Синтаксис Intel, допускается опускать % перед именами регистров "movss xmm0, [%2] \n\t" // Заносим данные в регистр "movss xmm1, [%3] \n\t" // Заносим данные в регистр "addss xmm1, xmm0 \n\t" // Складываем "movss [%0], xmm1 \n\t" // Вывод данных из регистра : "=r"(C) // Возвращаемые данные (теперь это не число, а указатель на результат. // Впрочем, он нам не нужен - искомое число уже записано по этому адресу) : "r"(C), "r"(A), "r"(B) // Входные данные : "%xmm0", "%xmm1" // Разрушаемые регистры ); printf("c = a + b = %f\n", c); return 0;
}
The box itself can be simplified a little by adding up with an orange from memory, avoiding unnecessary copying and saving the register:
".intel_syntax noprefix \n\t"
"movss xmm0, [%2] \n\t" // Копируем значение по адресу A в XMM0
"addss xmm0, [%3] \n\t" // Суммируем непосредственно с ячейкой
"movss [%0], xmm0 \n\t" // Копируем результат
: "=r"(C)
: "r"(C), "r"(A), "r"(B)
: "%xmm0"
There's a number of boxes in the GCC. http://asmcourse.cs.msu.ru/wp-content/uploads/2013/04/gcc-inline-asm.pdf ♪