C копия встроенной сборки в памяти
-
11-09-2019 - |
Вопрос
Я пытаюсь написать какую-нибудь встроенную сборку на 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 ?