الجمعية: تتحرك بين عناوين الذاكرة
-
18-09-2019 - |
سؤال
أحاول تعلم التجميع (حتى تحمل معي) وأنا أحصل على خطأ في الترجمة على هذا السطر:
mov byte [t_last], [t_cur]
الخطأ هو
error: invalid combination of opcode and operands
أظن أن سبب هذا الخطأ هو ببساطة أنه ليس من الممكن أن يتحرك تعليمات MOV بين عناوين الذاكرة، ولكن نصف ساعة من googling ولم أتمكن من تأكيد ذلك - هل هذا هو الحال؟
أيضا، على افتراض أنني صحيح وهذا يعني أنني بحاجة إلى استخدام سجل كقطة وسيطة لنسخ الذاكرة:
mov cl, [t_cur]
mov [t_last], cl
ما هو السجل الموصى به للاستخدام (أو يجب أن أستخدم المكدس بدلا من ذلك)؟
المحلول
شكوكك صحيحة، لا يمكنك الانتقال من الذاكرة إلى الذاكرة.
أي سجل للأغراض العامة سوف تفعل. تذكر أن تدفع السجل إذا لم تكن متأكدا ما هو بداخله واستعادته مرة أخرى مرة أخرى.
نصائح أخرى
انها حقا بسيطة في 16 بت، فقط تفعل ما يلي:
push di
push si
push cx
mov cx,(number of bytes to move)
lea di,(destination address)
lea si,(source address)
rep movsb
pop cx
pop si
pop di
ملاحظة: الدفاعات والملوثات العضوية الثابتة هي neceessary إذا كنت بحاجة إلى حفظ محتويات السجلات.
هناك أيضا أمر متنقل من نقل البيانات من الذاكرة إلى الذاكرة:
MOV SI, OFFSET variable1
MOV DI, OFFSET variable2
MOVS
من الممكن من الناحية الفنية الانتقال من الذاكرة إلى الذاكرة.
جرب استخدام مواتية (نقل السلسلة)، وإعداد ه] سي و ه] دي, ، اعتمادا على ما إذا كنت تريد نقل البايت (ق)، كلمة (كلمات)، إلخ.
mov si, t_cur ; Load SI with address of 't_cur'
mov di, t_last ; Load DI with address of 't_last'
movsb ; Move byte from [SI] to [DI]
; Some dummy data
t_cur db 0x9a ; DB tells NASM that we want to declare a byte
t_last db 0x7f ; (See above)
هذا أقل كفاءة من استخدام متجر التحميل العادي + مع سجل مؤقت واحد، ولكنه يفعل النسخة الفعلية مع تعليمات واحدة.
إليك الطريقة مواتية يجب أن تستخدم، وكيف يعمل:https://www.felixcloutier.com/x86/movs:movsb:movsw:movsd:movsq.
عادة ما تستخدم فقط مع rep
بادئة النسخ المحكومة، وليس لعنصر واحد. (وحدات المعالجة المركزية الحديثة لها ميكروكود فعال إلى حد ما ل rep movsb
أنه قريب من سرعة حلقة باستخدام تعليمات تحميل / تخزين متجه AVX.)
هذا صحيح، لا يمكن رمز الجهاز X86 ترميز التعليمات مع اثنين صريح معاملات الذاكرة (العناوين التعسفية المحددة في []
)
- لماذا لا يسمح Movl من الذاكرة إلى الذاكرة المسموح بها؟
- ما هي تعليمات X86 تأخذ معاملات ذاكرة (أو أكثر)؟
ما هو السجل الموصى به
أي سجل لا تحتاج إلى حفظ / استعادة.
في جميع اتفاقيات الدعوة ذات السائدة 32 بت و 64 بت، تتمتع EAX، ECX، و EDX بالدعوة، وبالتالي فإن Al، CL، و DL هي خيارات جيدة. للحصول على نسخ بايت أو كلمة، تريد عادة movzx
تحميل في سجل 32 بت، ثم متجر 8 بت أو 16 بت. هذا يتجنب تبعية خاطئة على القيمة القديمة للسجل. فقط استخدام ضيق 16 أو 8 بت mov
تحميل إذا كنت بنشاط يريد للدمج في البتات المنخفضة من قيمة أخرى. X86. movzx
هو التناظرية من التعليمات مثل الذراع ldrb
.
movzx ecx, byte [rdi] ; load CL, zero-extending into RCX
mov [rdi+10], cl
في وضع 64 بت، سيل، ديل، R0B، R9B، وهلم جرا أيضا خيارات جيدة، ولكنها تتطلب بادئة REX في رمز الجهاز للمتجر، لذلك هناك سبب طفيف الحجم لتجنبها.
عموما تجنب الكتابة آه، BH، CH، أو DH لأسباب الأداء، ما لم تكن قد قرأت وفهمت الروابط التالية وأي تبعيات خاطئة أو أكشاك دمج البيانات الجزئية لن تكون مشكلة أو تحدث على الإطلاق في التعليمات البرمجية وبعد
- لماذا لا تستخدم دول مجلس التعاون الخليجي السجلات الجزئية؟
- كيف بالضبط السجلات الجزئية على أداء haswell / skylake؟ يبدو أن كتابة الاعتماد الخاطئ على الفاكس، وآه غير متناسق
(أو يجب أن أستخدم المكدس بدلا من ذلك)؟
بادئ ذي بدء، لا يمكنك دفع بايت واحد على الإطلاق، لذلك لا توجد طريقة يمكنك القيام بمتجر BYTE / BYTE من المكدس. للحصول على كلمة أو DWORD أو QWORD (اعتمادا على وضع وحدة المعالجة المركزية)، يمكنك push [src]
/ pop [dst]
, ، هذا أبطأ كثيرا من النسخ عبر السجل. يقدم زمن بيانات متاجر إضافية / إعادة توجيه المتاجر قبل أن تتم قراءتها البيانات من الوجهة النهائية، وتستغرق المزيد من عمليات الصوت الأخرى.
ما لم يكن في مكان ما على المكدس يكون الوجهة المرجوة ولا يمكنك تحسين هذا المتغير المحلي في سجل، في هذه الحالة push [src]
هو فقط على ما يرام لنسخها هناك وتخصيص مساحة مكدس لذلك.
يرى https://agner.org/optimize/ وغيرها من روابط أداء X86 في علامة X86 Wiki
فقط أريد مناقشة "حاجز الذاكرة" معك. في كود ج
a = b;//Take data from b and puts it in a
سيتم تجميعها ل
mov %eax, b # suppose %eax is used as the temp
mov a, %eax
لا يمكن للنظام ضمان ذرية المهمة. لهذا السبب نحتاج إلى RMB (حاجز قراءة)