الدوال التاليه للنسخ من اليسار لليمين و لا توجد مشاكل بها، أول نسخه تقوم بالنسخ byte-by-byte و الأخري تقوم بنسخ عدد 4 بايت مره واحده و الباقى - أقل من 4 بايت - يتم نسخهم byte-by-byte:
void memcpy_ltr(void* dst, const void* src, size_t cnt)
{
__asm
{
mov esi, src
mov edi, dst
mov ecx, cnt
cld
rep movsb
}
}
void memcpy2_ltr(void* dst, const void* src, size_t cnt)
{
__asm
{
mov edi, dst
mov esi, src
mov ecx, cnt
mov eax, ecx
shr ecx, 2
shl ecx, 2
sub eax, ecx
shr ecx, 2
cld
jz REMAINS
rep movsd
REMAINS:
mov ecx, eax
rep movsb
}
}لجعل النسخ يتم من اليمين لليسار لابد من جعل موقع مؤشر المصدر و الهدف عند أخر موقع لهما و كذلك جعل DF بواحد و ذلك لأن ESI و EDI سيتم طرح منهم قيمة البات التى تم نسخها، الكود التالي يقوم بذلك مع وجود مشكله سيتم ذكرها لاحقا:
void memcpy_rtl(void* dst, const void* src, size_t cnt)
{
__asm
{
mov esi, src
mov edi, dst
mov ecx, cnt
add esi, cnt
add edi, cnt
std
rep movsb
}
}
void memcpy2_rtl(void* dst, const void* src, size_t cnt)
{
__asm
{
mov edi, dst
mov esi, src
mov ecx, cnt
add esi, cnt
add edi, cnt
mov eax, ecx
shr ecx, 2
shl ecx, 2
sub eax, ecx
shr ecx, 2
std
jz REMAINS
rep movsd
REMAINS:
mov ecx, eax
rep movsb
}
}المشكله التى تحدث هي أن عملية النسخ من اليمين لليسار دائما ما تتخطي أخر مجموعه بمعنى إذا كان عدد البايت التى سيتم نسخها هو 11 و سيتم إستخدام الداله memcpy_rtl فسيتم نسخ أخر 10 بايت و أول بايت لن يتم نسخه، أما إذا تم إستخدام الداله memcpy2_rtl حينها تصبح الأحدى عشر بايت عباره عن مجموعتين بمساحة 4 بايت لكل واحده و يتبقى 3 بايت، بالنسبه للمجموعتين سيتم نسخ ثانيمها و تجاهل اولهما بالنسبه للـ 3 بايت المتبقيين سيتم نسخ أخر إثنان و تجاهل الاول.
أيضا إستخدام دوال النسخ من اليمين لليسار تسبب تلف الـ stack مع العلم ان الدوال مكتوبه بلغة السى و المترجم بشكل تلقائي يقوم بإضافة prolog and epilog لضمان عدم حدوث مثل هذا الأمر
لا اعرف لماذا تعمل هذه الدوال بهذا الشكل و اتمنى ان يستطيع احد ان يفسر لى هذا الأمر.
و الله ولي التوفيق