views:

545

answers:

3

I am trying to write some inline assembly into C. I have two arrays as input, what I need is to copy one element in array1 into array2, and the following is what I have at the moment:

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

However, I get a segmentation fault error.

Can anyone help me please?

+3  A: 

Your best option is C code:

target_array[target_idx] = source_array[source_idx];

This avoids segmentation faults as long as the indexes are under control.

Jonathan Leffler
+4  A: 

Your inline assembler code is broken. You can't directly use EAX and EBX without adding them to the clobber list. Otherwise the compiler does not now which registers have been modified.

It is very likely that one of the registers that you've modified contained something damn important that later caused the segmentation fault.


This code will copy one element from array1 to 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"
);

A better version with proper register constraints would drop the hard coded EAX like this:

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 - In general I have the feeling that you're not that familiar with assembler yet. Writing inline-assembler is a bit harder to get right due to all the compiler magic. I suggest that you start writing some simple functions in assembler and put them into a separate .S file first.. That's much easier..

Nils Pipenbrinck
Nils Pipenbrinck
caf
A: 

what about memcpy ?

Shaman