A sudden whim today reminds me of a face question that I met during an interview with a previous company, which is to implement a memcopy () function. Originally too nervous (just graduated the second interview), so the writing is not very good (can be said to be flawed); now just learned a little assembly, just in two languages to achieve under;
First of all, the assembly implementation of the memcpy function, is the use of macro functions to achieve, with the assembly instruction rep and MOVSB with the loop to the data in bytes from Ds:esi to Es:edi, the number of cycles in ECX . Of course this copy is the real memory copy, the other functions are a little bit farfetched.
#define MYMEMCPY (dest, SRC, N) ({ void* _ret = dest; __asm__ ("CLD;REP;MOVSB" :: "D" ((Long) (_ret)), "S" ((long) (SRC)), "C" ((long) (n))); _ret;})
When debugging the MEMCPY function implemented by the assembly, an error is encountered, which is recorded here:
Error: Mymemcpy.c:in function ' main ':
Mymemcpy.c:15:error:can ' t find a register in class ' CREG ' while reloading ' asm '
Mymemcpy.c:15:error: ' asm ' operand has impossible constraints
This error occurred because I began to add a column to modify the Register list (add change register Si, Di, ex); I checked the information that the same register was used when the same variable was two occurrences, and this error is reported. The workaround is to replace those register names in the change register with placeholders (di==0;si==1;cx==2); but I simply deleted the list of changes, because I remember some GCC compilers are not listed in the change register for registers that appear in the input and output (I also mentioned in the previous blogs that the registers that appeared in the input and output are not added to the Change register list) but some versions of GCC need to be added to the Change Register column;
The following is a C language to implement the memcpy function, in fact, I feel C language to implement or relatively simple, is to cast the input data into characters to operate, because there is no smaller than the characters in the C language units . And for whether to return RET, if you want to use memcpy multiple times (myMemcpy1 (XXX, myMemcpy1 (xx, XX, xx), XX), it must be returned. If not necessary and the original memcpy (), do not be too rigid (but it is recommended to return to RET, you can consider extending later).
void* myMemcpy1 (void* dest, void* src, unsigned int n) { char* d = (char*) dest; char* s = (char*) src; char* ret = D; while (n--) { *d++ = *s++; } return ret; }
Well, the implementation of all implemented, now to test under, of course I debug through, interested can try to debug under.
int main (void) { char test1[] = "Yuzhihui"; Char test2[1024] = {}; Char test3[1024] = {}; mymemcpy (test2, test1, sizeof (test1)); MyMemcpy1 (test3, test1, sizeof (test1)); printf ("test1:%s\n", test1); printf ("test2:%s\n", test2); printf ("test3:%s\n", test3); int T1 = +; int t2 = 0; int t3 = 0; mymemcpy (&t2, &t1, sizeof (T1)); MyMemcpy1 (&T3, &t1, sizeof (T1)); printf ("t1:%d\n", T1); printf ("t2:%d\n", T2); printf ("t3:%d\n", T3); return 0; }
The following is the result of the operation:
Reprint please indicate the author and source, original address: http://blog.csdn.net/yuzhihui_no1/article/details/43601757
If there is anything wrong, you are welcome to correct, work together, learn together!!
Memcopy () Function C language Implementation and assembly implementation comparison