C copia della memoria assembly inline
-
11-09-2019 - |
Domanda
Sto cercando di scrivere qualche linea di assemblaggio in C. Ho due array come input, quello che serve è quello di copiare un elemento di array1 in matrice2, e il seguente è quello che ho in questo momento:
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)
);
Perché ricevo un errore di segmentazione?
Soluzione
Il tuo codice assembler inline è rotto. Non è possibile utilizzare direttamente EAX e EBX senza aggiungerli alla lista clobber. In caso contrario, il compilatore non ora che i registri sono stati modificati.
E 'molto probabile che uno dei registri che che hai modificato conteneva qualcosa di dannatamente importante che poi ha causato l'errore di segmentazione.
Questo codice copia un elemento da array1 a matrice2:
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"
);
Una versione migliore con adeguati vincoli sui registri scenderebbe EAX hard coded in questo modo:
int dummy;
asm (
"movl (%1), %0 \n\t"
"movl %0, (%2) \n\t"
: /* outputs, temps.. */ "=r" (dummy)
: /* inputs */ "r"(array1),"r"(array2)
: /* clobber */ "memory"
);
A proposito - In generale, ho la sensazione che non sei ancora che la familiarità con assembler. Scrivendo inline-assembler è un po 'più difficile da ottenere il diritto a causa di tutta la magia del compilatore. Vi suggerisco di iniziare a scrivere alcune semplici funzioni in assembler e metterli in un file .S separata prima .. Questo è molto più facile ..
Altri suggerimenti
La soluzione migliore è il codice C:
target_array[target_idx] = source_array[source_idx];
Questo evita errori di segmentazione fintanto che gli indici sono sotto controllo.
che dire memcpy?