Вопрос

Я пытаюсь написать какую-нибудь встроенную сборку на C.У меня есть два массива в качестве входных данных, все, что мне нужно, это скопировать один элемент из array1 в array2, и вот что у меня есть на данный момент:

asm (
 "movl %0,%%eax;"
 "movl %1,%%ebx;"
 "movl (%%eax),%%ecx;"
 "movl %%ecx,(%ebx);"

 "xor %%ecx,%%ecx;"
 "movl 4(%%eax),%%ecx;"
//do something on %ecx
 "movl %%ecx,4(%ebx);"  //write second
 :
 :"a"(array1),"b"(array2)
);

Почему я получаю ошибку сегментации?

Это было полезно?

Решение

Ваш встроенный код на ассемблере сломан.Вы не можете напрямую использовать EAX и EBX, не добавив их в список ошибок.В противном случае компилятор не определяет, какие регистры были изменены.

Весьма вероятно, что один из регистров, которые вы изменили, содержал что-то чертовски важное, что позже вызвало ошибку сегментации.


Этот код скопирует один элемент из array1 в array2:

asm (
 "movl (%0), %%eax \n\t" /* read first dword from array1 into eax */
 "movl %%eax, (%1) \n\t" /* write dword into array2
 : /* outputs */
 : /* inputs */ "r"(array1),"r"(array2)
 : /* clobber */ "eax", "memory"
);

Лучшая версия с надлежащими ограничениями регистра отбросила бы жестко закодированный EAX следующим образом:

int dummy;
asm (
 "movl (%1), %0 \n\t"
 "movl %0, (%2) \n\t"
 : /* outputs, temps.. */ "=r" (dummy) 
 : /* inputs */           "r"(array1),"r"(array2)
 : /* clobber */          "memory"
);

Кстати - В общем, у меня такое ощущение, что вы еще не настолько знакомы с ассемблером.Правильно написать встроенный ассемблер немного сложнее из-за всей этой магии компилятора.Я предлагаю вам начать писать некоторые простые функции на ассемблере и сначала поместить их в отдельный файл .S..Это намного проще..

Другие советы

Ваш лучший вариант - это C-код:

target_array[target_idx] = source_array[source_idx];

Это позволяет избежать ошибок сегментации до тех пор, пока индексы находятся под контролем.

а как насчет memcpy ?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top