C встроенная копия памяти, копия - PullRequest
1 голос
/ 01 ноября 2009

Я пытаюсь записать некоторую встроенную сборку в 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)
);

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

Ответы [ 3 ]

5 голосов
/ 01 ноября 2009

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

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


Этот код скопирует один элемент из массива1 в массив2:

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"
);

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

3 голосов
/ 01 ноября 2009

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

target_array[target_idx] = source_array[source_idx];

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

0 голосов
/ 08 апреля 2010

как насчет memcpy?

...