2009-11-01 3 views
1

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

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

Почему возникает ошибка сегментации?

+1

Дайте парсеру работать, прекратите добавлять HTML-тег - вы отбрасываете выделение, которое делает SO. –

+4

Вы просто копируете один элемент из массива в другой массив? Это не похоже на то, что поможет оптимизация сборки узлов. –

+2

Вы должны добавить немного более подробную информацию о том, почему вы хотите сделать это в сборке, или вы просто получите много «зачем беспокоиться»? ответы. –

ответ

5

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

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


Этот код будет копировать один элемент из array1 в массив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" 
); 

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

+0

Спасибо, Это именно то, что мне нужно. Я знаю только некоторые инструкции MIPS32 и MIPS64, это мой первый раз, когда я пишу встроенную сборку. Кстати, я думаю, что инструкция movl в AT & T равна Источник movl, пункт назначения , поэтому прочитайте сначала dword из массива 1 в eax должно быть "movl (% 0), %% eax \ n \ t" это правильно? – user200340

+0

Может быть .. Я всегда стараюсь избегать этого синтаксиса AT & T. Синтаксис intel isho намного чище .. –

+0

Да, синтаксис AT & T - это 'source',' dest' - я сделал эту небольшую коррекцию. – caf

3

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

target_array[target_idx] = source_array[source_idx]; 

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

0

Что относительно memcpy?

Смежные вопросы