كود ذاتي التعديل
في علوم الحاسوب ، يُعرف الكود ذاتي التعديل ( SMC أو SMoC ) بأنه كود يُعدّل تعليماته أثناء تنفيذه ، عادةً لتقليل طول مسار التعليمات وتحسين الأداء ، أو ببساطة لتقليل التكرار في الكود ، مما يُسهّل الصيانة . يُستخدم هذا المصطلح عادةً فقط في حالة الكود الذي يُعدّل نفسه عمدًا، وليس في الحالات التي يُعدّل فيها الكود نفسه عن طريق الخطأ نتيجة خطأ ما، مثل تجاوز سعة المخزن المؤقت .
يمكن أن يتضمن الكود ذاتي التعديل الكتابة فوق التعليمات الموجودة أو إنشاء كود جديد في وقت التشغيل ونقل التحكم إلى ذلك الكود.
يمكن استخدام التعديل الذاتي كبديل لطريقة "ضبط العلامات" والتفرع الشرطي للبرنامج، والتي تستخدم في المقام الأول لتقليل عدد مرات اختبار الشرط.
تُستخدم هذه الطريقة بشكل متكرر لاستدعاء رمز الاختبار/التصحيح بشكل مشروط دون الحاجة إلى تكلفة حسابية إضافية لكل دورة إدخال/إخراج .
يمكن إجراء التعديلات التالية:
- يحدث هذا فقط أثناء التهيئة - بناءً على معلمات الإدخال (عندما تُوصف العملية عادةً بأنها " تهيئة " برمجية، وهي تُشابه إلى حد ما، من الناحية المادية، ضبط وصلات التوصيل للوحات الدوائر المطبوعة ). يُعد تغيير مؤشرات دخول البرنامج طريقة غير مباشرة مكافئة للتعديل الذاتي، ولكنه يتطلب وجود مسار تعليمات بديل واحد أو أكثر، مما يزيد من حجم البرنامج .
- أثناء التنفيذ ("أثناء التشغيل") - بناءً على حالات البرنامج المحددة التي تم الوصول إليها أثناء التنفيذ
في كلتا الحالتين، يمكن إجراء التعديلات مباشرة على تعليمات رمز الآلة نفسها، عن طريق وضع تعليمات جديدة فوق التعليمات الموجودة (على سبيل المثال، تغيير المقارنة والتفرع إلى تفرع غير مشروط أو بدلاً من ذلك إلى NOP ).
في بنية IBM System/360 وخلفائها حتى z/Architecture ، تقوم تعليمة EXECUTE (EX) منطقيًا بتراكب البايت الثاني من تعليمة الهدف مع البتات الثمانية ذات الترتيب الأدنى من السجل 1. وهذا يوفر تأثير التعديل الذاتي، على الرغم من أن التعليمة الفعلية في التخزين لا تتغير.
التطبيق في لغات البرمجة منخفضة وعالية المستوى
يمكن إنجاز التعديل الذاتي بطرق متنوعة اعتمادًا على لغة البرمجة ودعمها للمؤشرات و/أو الوصول إلى "محركات" المترجم أو المفسر الديناميكي:
- تراكب التعليمات الموجودة (أو أجزاء من التعليمات مثل رمز العملية، أو السجل، أو العلامات، أو العناوين)
- إنشاء مباشر لتعليمات كاملة أو تسلسلات من التعليمات في الذاكرة
- إنشاء أو تعديل عبارات التعليمات البرمجية المصدرية متبوعة بـ "تجميع مصغر" أو تفسير ديناميكي (انظر عبارة eval )
- إنشاء برنامج كامل بشكل ديناميكي ثم تنفيذه
لغة التجميع
يُعدّ تنفيذ التعليمات البرمجية ذاتية التعديل أمرًا بسيطًا عند استخدام لغة التجميع . يمكن إنشاء التعليمات ديناميكيًا في الذاكرة (أو استبدالها بتعليمات موجودة في وحدة تخزين البرنامج غير المحمية)، [ 1 ] بتسلسل يُعادل التسلسلات التي قد يُولّدها مُصرّف قياسي ككود كائن . مع المعالجات الحديثة، قد تظهر آثار جانبية غير مقصودة على ذاكرة التخزين المؤقت لوحدة المعالجة المركزية ، والتي يجب أخذها في الاعتبار. استُخدمت هذه الطريقة بكثرة لاختبار شروط "المرة الأولى"، كما في مثال مُجمّع IBM/360 المُعلّق عليه بشكلٍ مناسب . تستخدم هذه الطريقة تراكب التعليمات لتقليل طول مسار التعليمات بمقدار ( N × 1) - 1 ، حيث N هو عدد السجلات في الملف (-1 هو التكلفة الإضافية لتنفيذ التراكب).
هل تم افتتاح فرع NOP لأول مرة هنا؟ * NOP هو x'4700' < عنوان_الفتح> OI SUBRTN+1,X'F0' نعم، قم بتغيير NOP إلى فرع غير مشروط (47F0...) افتح ملف الإدخال، فهذه هي المرة الأولى. مفتوح، احصل على المدخلات، استئناف المعالجة العادية هنا ...قد يتضمن الكود البديل اختبار "علامة" في كل مرة. يُعدّ التفرع غير المشروط أسرع قليلاً من تعليمة المقارنة، كما أنه يُقلل من طول المسار الإجمالي. في أنظمة التشغيل اللاحقة للبرامج الموجودة في وحدة تخزين محمية ، لم يكن بالإمكان استخدام هذه التقنية، لذا كان يتم استخدام تغيير المؤشر إلى الروتين الفرعي بدلاً من ذلك. كان المؤشر موجودًا في وحدة تخزين ديناميكية ، ويمكن تعديله حسب الرغبة بعد المرور الأول لتجاوز OPEN(كان تحميل المؤشر أولاً بدلاً من التفرع المباشر والربط بالروتين الفرعي يُضيف N تعليمة إلى طول المسار - ولكن كان هناك انخفاض مُقابل في N للتفرع غير المشروط الذي لم يعد مطلوبًا).
فيما يلي مثال بلغة التجميع Zilog Z80 . يقوم الكود بزيادة قيمة المسجل Bضمن النطاق [0، 5]. CPيتم تعديل تعليمة المقارنة في كل دورة.
;========== ORG 0H CALL FUNC00 HALT ;========== FUNC00: LD A , 6 LD HL , label01 + 1 LD B ,( HL ) label00: INC B LD ( HL ), B label01: CP $ 0 JP NZ , label00 RET ;==========يُستخدم أحيانًا الكود ذاتي التعديل للتغلب على قيود مجموعة تعليمات الجهاز. على سبيل المثال، في مجموعة تعليمات Intel 8080 ، لا يمكن إدخال بايت من منفذ إدخال مُحدد في سجل. يُشفّر منفذ الإدخال بشكل ثابت في التعليمات نفسها، كبايت ثانٍ من تعليمات ثنائية البايت. باستخدام الكود ذاتي التعديل، يُمكن تخزين محتويات السجل في البايت الثاني من التعليمات، ثم تنفيذ التعليمات المُعدّلة لتحقيق النتيجة المرجوة.
لغات البرمجة عالية المستوى
تسمح بعض لغات البرمجة المترجمة صراحةً بتعديل التعليمات البرمجية ذاتيًا. على سبيل المثال، يمكن تنفيذ ALTERالفعل في لغة كوبول كتعليمات تفرع يتم تعديلها أثناء التنفيذ. [ 2 ] تتضمن بعض تقنيات البرمجة الدفعية استخدام التعليمات البرمجية ذاتية التعديل. كما توفر لغتا كليبر وسبيتبول إمكانيات للتعديل الذاتي الصريح. وقد وفر مُترجم لغة ألغول على أنظمة B6700 واجهةً لنظام التشغيل، حيث يمكن للتعليمات البرمجية المنفذة تمرير سلسلة نصية أو ملف قرص مُسمى إلى مُترجم ألغول، ومن ثم استدعاء الإصدار الجديد من الإجراء.
في اللغات المفسرة، يُعدّ "رمز الآلة" هو النص المصدر، وقد يكون قابلاً للتعديل أثناء التشغيل: ففي لغة SNOBOL، تُمثّل عبارات المصدر التي يتم تنفيذها عناصر مصفوفة نصية. تسمح لغات أخرى، مثل Perl و Python ، للبرامج بإنشاء رمز جديد أثناء التشغيل وتنفيذه باستخدام دالة eval ، لكنها لا تسمح بتعديل الرمز الموجود. ويتحقق وهم التعديل (مع أنه لا يتم استبدال رمز الآلة فعليًا) عن طريق تعديل مؤشرات الدوال، كما في مثال JavaScript هذا:
var f = function ( x ) { return x + 1 };// تعيين تعريف جديد للدالة f: f = new Function ( 'x' , 'return x + 2' );تسمح وحدات الماكرو في لغة ليسب أيضًا بتوليد التعليمات البرمجية في وقت التشغيل دون تحليل سلسلة نصية تحتوي على التعليمات البرمجية للبرنامج.
لغة برمجة Push هي نظام برمجة جينية مصمم خصيصًا لإنشاء برامج ذاتية التعديل. ورغم أنها ليست لغة برمجة عالية المستوى، إلا أنها ليست منخفضة المستوى كلغة التجميع. [ 3 ]
تعديل المركب
قبل ظهور النوافذ المتعددة، كانت أنظمة سطر الأوامر توفر نظام قوائم يتضمن تعديل نص برمجي قيد التشغيل. لنفترض أن ملف دفعي MS-DOS المسمى MENU.BAT يحتوي على ما يلي: [ 4 ] [ nb 1 ]
:يبدأ SHOWMENU.EXE
عند تشغيل ملف MENU.BAT من سطر الأوامر، يعرض برنامج SHOWMENU قائمة على الشاشة، تتضمن معلومات مساعدة وأمثلة استخدام وما إلى ذلك. بعد ذلك، يختار المستخدم خيارًا يتطلب تنفيذ الأمر SOMENAME : يخرج برنامج SHOWMENU بعد إعادة كتابة ملف MENU.BAT ليحتوي على
:يبدأ SHOWMENU.EXE اتصل باسم ما .BAT ابدأ من هنا
لأن مُفسِّر الأوامر لا يُجمِّع ملفًا برمجيًا ثم يُنفِّذه، ولا يقرأ الملف بأكمله في الذاكرة قبل بدء التنفيذ، ولا يعتمد على محتوى مُخزن السجلات، فعند خروج SHOWMENU، يجد مُفسِّر الأوامر أمرًا جديدًا لتنفيذه (وهو استدعاء الملف البرمجي SOMENAME ، في موقع دليل وعبر بروتوكول معروف لـ SHOWMENU)، وبعد اكتمال هذا الأمر، يعود إلى بداية الملف البرمجي ويُعيد تنشيط SHOWMENU استعدادًا للاختيار التالي. إذا كان خيار القائمة هو الخروج، فسيتم إعادة كتابة الملف إلى حالته الأصلية. على الرغم من أن حالة البداية هذه لا تحتاج إلى التسمية، إلا أنها، أو كمية مُكافئة من النص، مطلوبة، لأن مُفسِّر الأوامر يسترجع موضع البايت للأمر التالي عند بدء تنفيذه، وبالتالي يجب أن يحافظ الملف المُعاد كتابته على المحاذاة لكي تكون نقطة بداية الأمر التالي هي بالفعل بداية الأمر التالي.
إلى جانب سهولة استخدام نظام القوائم (والميزات الإضافية المحتملة)، فإن هذا النظام يعني أن نظام SHOWMENU.EXE لا يكون موجودًا في الذاكرة عند تفعيل الأمر المحدد، وهي ميزة مهمة عند محدودية الذاكرة. [ 4 ] [ 5 ]
جداول التحكم
يمكن اعتبار مترجمي جداول التحكم ، بمعنى ما، "معدلة ذاتيًا" بواسطة قيم البيانات المستخرجة من إدخالات الجدول (بدلاً من ترميزها يدويًا بشكل محدد في عبارات شرطية من الشكل IF inputx = 'yyy').
برامج القناة
تستخدم بعض طرق الوصول من IBM تقليديًا برامج القنوات ذاتية التعديل ، حيث يتم قراءة قيمة، مثل عنوان القرص، في منطقة يشير إليها برنامج القناة، حيث يتم استخدامها بواسطة أمر قناة لاحق للوصول إلى القرص.
تاريخ
كان لدى جهاز IBM SSEC ، الذي عُرض في يناير 1948، القدرة على تعديل تعليماته أو التعامل معها تمامًا كبيانات. مع ذلك، نادرًا ما استُخدمت هذه القدرة عمليًا. [ 6 ] في بدايات الحوسبة، كان يُستخدم الكود ذاتي التعديل غالبًا لتقليل استخدام الذاكرة المحدودة، أو لتحسين الأداء، أو كليهما. كما استُخدم أحيانًا لتنفيذ استدعاءات الإجراءات الفرعية وعمليات الإرجاع عندما لم تُوفر مجموعة التعليمات سوى تعليمات تفرع أو تخطي بسيطة لتغيير مسار التحكم . [ 7 ] [ 8 ] لا يزال هذا الاستخدام ذا صلة في بعض معمارية RISC فائقة التطور ، على الأقل نظريًا؛ انظر على سبيل المثال حاسوب مجموعة التعليمات الواحدة . كما استخدمت معمارية MIX لدونالد كنوث الكود ذاتي التعديل لتنفيذ استدعاءات الإجراءات الفرعية. [ 9 ]
الاستخدام
يمكن استخدام الكود ذاتي التعديل لأغراض متنوعة:
- تحسين شبه تلقائي لحلقة تعتمد على الحالة.
- تحسين ديناميكي للكود في مكانه لزيادة السرعة اعتمادًا على بيئة التحميل. [ 10 ] [ 11 ] [ ملاحظة 2 ]
- توليد التعليمات البرمجية في وقت التشغيل ، أو تخصيص خوارزمية في وقت التشغيل أو وقت التحميل (وهو أمر شائع، على سبيل المثال، في مجال الرسومات في الوقت الحقيقي) مثل أداة الفرز العامة - إعداد التعليمات البرمجية لإجراء مقارنة المفاتيح الموصوفة في استدعاء معين.
- تغيير الحالة المضمنة لكائن ما ، أو محاكاة البناء عالي المستوى للإغلاقات .
- ترقيع استدعاء عنوان الروتين الفرعي ( المؤشر )، عادة ما يتم تنفيذه في وقت التحميل/التهيئة للمكتبات الديناميكية ، أو في كل استدعاء، ترقيع المراجع الداخلية للروتين الفرعي إلى معلماته بحيث تستخدم عناوينها الفعلية (أي التعديل الذاتي غير المباشر).
- أنظمة الحوسبة التطورية مثل التطور العصبي والبرمجة الجينية وغيرها من الخوارزميات التطورية .
- إخفاء التعليمات البرمجية لمنع الهندسة العكسية (باستخدام برنامج تفكيك أو مصحح أخطاء ) أو لتجنب الكشف عنها بواسطة برامج فحص الفيروسات/برامج التجسس وما شابه ذلك.
- ملء جميع الذاكرة (في بعض البنى) بنمط متناوب من رموز العمليات المتكررة ، لمسح جميع البرامج والبيانات، أو لاختبار الأجهزة أو إجراء اختبارات ذاكرة الوصول العشوائي . [ 12 ]
- ضغط التعليمات البرمجية ليتم فك ضغطها وتنفيذها أثناء التشغيل، على سبيل المثال، عندما تكون الذاكرة أو مساحة القرص محدودة. [ 10 ] [ 11 ]
- بعض مجموعات التعليمات المحدودة للغاية لا تترك خيارًا سوى استخدام التعليمات البرمجية ذاتية التعديل لأداء وظائف معينة. على سبيل المثال، لا يمكن لجهاز حاسوب ذي مجموعة تعليمات واحدة (OISC) يستخدم فقط تعليمة "الطرح والتفرع في حالة السالب" أن يقوم بنسخ غير مباشر (شيء مشابه لما هو مكافئ
*a = **bفي لغة C ) دون استخدام التعليمات البرمجية ذاتية التعديل. - عملية الإقلاع . غالبًا ما استخدمت الحواسيب الصغيرة القديمة شفرة ذاتية التعديل في برامج الإقلاع الخاصة بها. ولأن برنامج الإقلاع كان يُدخل عبر اللوحة الأمامية عند كل تشغيل، لم يكن مهمًا ما إذا كان برنامج الإقلاع يُعدّل نفسه أم لا. مع ذلك، حتى اليوم، لا تزال العديد من برامج الإقلاع ذاتية النقل ، وبعضها يُعدّل نفسه بنفسه. [ ملاحظة 3 ]
- تعديل التعليمات لتحقيق تحمل الأعطال. [ 13 ]
تحسين حلقة تعتمد على الحالة
مثال على الشفرة الزائفة :
كرر N مرة { إذا كانت قيمة STATE هي 1 قم بزيادة قيمة A بمقدار واحد آخر قلل قيمة A بمقدار واحد افعل شيئًا ما باستخدام أ }في هذه الحالة، سيكون الكود ذاتي التعديل مجرد مسألة إعادة كتابة الحلقة على النحو التالي:
كرر N مرة { زد A بمقدار واحد افعل شيئًا ما باستخدام أ عندما يتعين على الحالة التبديل { استبدل رمز العملية "increase" أعلاه برمز العملية "increase"، أو العكس. } }لاحظ أن استبدال الحالة الثنائية لرمز العملية يمكن كتابته بسهولة على النحو التالي "xor var at address with the value opcodeOf(Inc) xor opcodeOf(dec)".
يعتمد اختيار هذا الحل على قيمة N وتكرار تغير الحالة.
التخصص
لنفترض أننا نريد حساب مجموعة من الإحصائيات، مثل المتوسط، والقيم القصوى، وموقعها، والانحراف المعياري، وما إلى ذلك، لمجموعة بيانات كبيرة. في الحالة العامة، قد يكون من الممكن ربط أوزان بالبيانات، بحيث يرتبط كل xᵢ بـ wᵢ . وبدلاً من اختبار وجود الأوزان عند كل قيمة فهرس، يمكن استخدام نسختين من الحساب، إحداهما مع الأوزان والأخرى بدونها، مع إجراء اختبار واحد في البداية. الآن، لنفترض خيارًا آخر، وهو ربط كل قيمة بقيمة منطقية (Boolean) لتحديد ما إذا كان سيتم تخطي هذه القيمة أم لا. يمكن معالجة هذا الخيار بإنشاء أربع دفعات من التعليمات البرمجية، واحدة لكل تبديل، مما يؤدي إلى تضخم حجم التعليمات البرمجية. بدلاً من ذلك، يمكن دمج مصفوفات الأوزان والتخطي في مصفوفة مؤقتة (بأوزان صفرية للقيم المراد تخطيها)، مما يزيد من وقت المعالجة ويؤدي إلى تضخم حجم التعليمات البرمجية. مع ذلك، يمكن تعديل التعليمات البرمجية، بإضافة التعليمات البرمجية المناسبة لتخطي القيم غير المرغوب فيها وتطبيق الأوزان إلى قالب حساب الإحصائيات. لن يكون هناك اختبار متكرر للخيارات وسيتم الوصول إلى مصفوفة البيانات مرة واحدة، وكذلك مصفوفات الوزن والتخطي، إن وجدت.
استخدمه كتمويه
يُعدّ تحليل الشيفرة ذاتية التعديل أكثر تعقيدًا من تحليل الشيفرة القياسية، ولذلك يُمكن استخدامها كحماية ضد الهندسة العكسية واختراق البرمجيات . استُخدمت الشيفرة ذاتية التعديل لإخفاء تعليمات حماية النسخ في برامج الأقراص الصلبة في ثمانينيات القرن الماضي لأنظمة مثل أجهزة IBM PC المتوافقة و Apple II . على سبيل المثال، في جهاز IBM PC، لم تكن تعليمات الوصول إلى محرك الأقراص المرنةint 0x13 تظهر في صورة البرنامج القابل للتنفيذ، بل كانت تُكتب في صورة ذاكرة البرنامج بعد بدء تنفيذه.
يُستخدم الكود ذاتي التعديل أحيانًا من قِبل برامج لا ترغب في الكشف عن وجودها، مثل فيروسات الحاسوب وبعض أكواد البرامج الخبيثة . غالبًا ما تستخدم الفيروسات وأكواد البرامج الخبيثة التي تعتمد على الكود ذاتي التعديل هذا الأسلوب بالتزامن مع الكود متعدد الأشكال . كما يُستخدم تعديل جزء من الكود قيد التشغيل في بعض الهجمات، مثل هجمات تجاوز سعة المخزن المؤقت .
أنظمة التعلم الآلي ذاتية المرجعية
تعتمد أنظمة التعلم الآلي التقليدية على خوارزمية تعلم ثابتة ومبرمجة مسبقًا لضبط معاييرها . مع ذلك، ومنذ ثمانينيات القرن الماضي، نشر يورغن شميدهوبر العديد من الأنظمة ذاتية التعديل القادرة على تغيير خوارزمية التعلم الخاصة بها. تتجنب هذه الأنظمة خطر إعادة الكتابة الذاتية الكارثية من خلال ضمان بقاء التعديلات الذاتية فقط إذا كانت مفيدة وفقًا لدالة اللياقة أو الخطأ أو المكافأة التي يحددها المستخدم . [ 14 ]
أنظمة التشغيل
تستخدم نواة لينكس على نطاق واسع شيفرة ذاتية التعديل؛ وذلك لتمكينها من توزيع صورة ثنائية واحدة لكل بنية رئيسية (مثل IA-32 ، وx86-64 ، وARM 32 بت ، و ARM64 ، إلخ) مع تكييف شيفرة النواة في الذاكرة أثناء الإقلاع بناءً على طراز وحدة المعالجة المركزية المحدد، على سبيل المثال للاستفادة من تعليمات وحدة المعالجة المركزية الجديدة أو لتجاوز أخطاء الأجهزة. [ 15 ] [ 16 ] وبدرجة أقل، تعمل نواة DR-DOS أيضًا على تحسين الأجزاء الحساسة للسرعة في وقت التحميل بناءً على جيل المعالج الأساسي. [ 10 ] [ 11 ] [ ملاحظة 2 ]
بغض النظر عن ذلك، على مستوى الميتا ، لا يزال بإمكان البرامج تعديل سلوكها الخاص عن طريق تغيير البيانات المخزنة في مكان آخر (انظر البرمجة الميتا ) أو عن طريق استخدام تعدد الأشكال .
نواة تركيب ماسالين
نواة Synthesis، المعروضة في أطروحة الدكتوراه لأليكسيا ماسالين [ 17 ] [ 18 ] ، هي نواة يونكس صغيرة الحجم ، تتبنى منهجًا منظمًا ، أو حتى منهجًا كائني التوجه ، في كتابة التعليمات البرمجية ذاتية التعديل، حيث تُنشأ التعليمات البرمجية لكل كائن على حدة ، مثل مقابض الملفات. ويتيح توليد التعليمات البرمجية لمهام محددة لنواة Synthesis (كما يفعل مترجم JIT) تطبيق عدد من التحسينات ، مثل طي الثوابت أو حذف التعبيرات الفرعية المشتركة .
كانت نواة Synthesis سريعة للغاية، لكنها كُتبت بالكامل بلغة التجميع. وقد حال هذا النقص في قابلية النقل دون تبني أفكار ماسالين لتحسين الأداء في أي نواة إنتاجية. مع ذلك، يشير هيكل هذه التقنيات إلى إمكانية ترجمتها إلى لغة برمجة عالية المستوى ، وإن كانت أكثر تعقيدًا من لغات البرمجة متوسطة المستوى الحالية. من شأن هذه اللغة والمترجم أن يُتيحا تطوير أنظمة تشغيل وتطبيقات أسرع.
اعترض كل من بول هابرلي وبروس كارش على "تهميش" الكود ذاتي التعديل، والتحسين بشكل عام، لصالح خفض تكاليف التطوير. [ 19 ]
تفاعل ذاكرة التخزين المؤقت والتعليمات البرمجية ذاتية التعديل
في البنى التي لا تحتوي على ذاكرة تخزين مؤقتة للبيانات والتعليمات (على سبيل المثال، بعض نوى SPARC و ARM و MIPS ) يجب أن تتم مزامنة ذاكرة التخزين المؤقت بشكل صريح بواسطة الكود المعدل (مسح ذاكرة التخزين المؤقت للبيانات وإبطال ذاكرة التخزين المؤقت للتعليمات لمنطقة الذاكرة المعدلة).
في بعض الحالات، قد تُنفَّذ أجزاء قصيرة من التعليمات البرمجية ذاتية التعديل ببطء أكبر على المعالجات الحديثة. ويعود ذلك إلى أن المعالج الحديث عادةً ما يُحاول الاحتفاظ بكتل من التعليمات البرمجية في ذاكرة التخزين المؤقت (الكاش). في كل مرة يُعيد فيها البرنامج كتابة جزء من نفسه، يجب تحميل الجزء المُعاد كتابته إلى ذاكرة التخزين المؤقت مرة أخرى، مما ينتج عنه تأخير طفيف، إذا كان الجزء المُعدَّل من التعليمات البرمجية يشترك في نفس سطر ذاكرة التخزين المؤقت مع التعليمات البرمجية المُعدِّلة، كما هو الحال عندما يكون عنوان الذاكرة المُعدَّلة على بُعد بضعة بايتات من عنوان الذاكرة الخاص بالتعليمات البرمجية المُعدِّلة.
عادة ما تعني مشكلة إبطال ذاكرة التخزين المؤقت في المعالجات الحديثة أن التعليمات البرمجية ذاتية التعديل ستظل أسرع فقط عندما يحدث التعديل نادرًا، كما هو الحال في حالة تبديل الحالة داخل حلقة داخلية.
تقوم معظم المعالجات الحديثة بتحميل رمز الآلة قبل تنفيذه، مما يعني أنه إذا تم تعديل تعليمة قريبة جدًا من مؤشر التعليمات ، فلن يلاحظ المعالج ذلك، بل سينفذ التعليمات كما كانت قبل التعديل. انظر إلى قائمة انتظار الإدخال المسبق (PIQ). يجب على معالجات الحاسوب الشخصي (PC) التعامل مع التعليمات ذاتية التعديل بشكل صحيح لأسباب تتعلق بالتوافق مع الإصدارات السابقة، لكنها بعيدة كل البعد عن الكفاءة في القيام بذلك.
قضايا أمنية
نظراً للمخاطر الأمنية المترتبة على تعديل البرامج ذاتياً، تحرص جميع أنظمة التشغيل الرئيسية على إزالة هذه الثغرات فور اكتشافها. ولا يكمن القلق عادةً في قيام البرامج بتعديل نفسها عمداً، بل في إمكانية استغلالها وتغييرها بشكل خبيث .
إحدى آليات منع تعديل التعليمات البرمجية الخبيثة هي ميزة في نظام التشغيل تُسمى W^X (اختصارًا لـ "الكتابة أو التنفيذ"). تمنع هذه الآلية أي برنامج من جعل أي صفحة من الذاكرة قابلة للكتابة والتنفيذ في آنٍ واحد. تمنع بعض الأنظمة تحويل صفحة قابلة للكتابة إلى صفحة قابلة للتنفيذ، حتى في حال إزالة إذن الكتابة. بينما توفر أنظمة أخرى ما يُشبه " الباب الخلفي "، مما يسمح بربط صفحات متعددة من الذاكرة بصلاحيات مختلفة. إحدى الطرق الشائعة لتجاوز W^X هي إنشاء ملف بجميع الصلاحيات، ثم ربط هذا الملف بالذاكرة مرتين. في نظام لينكس، يُمكن استخدام علامة SysV غير الموثقة للذاكرة المشتركة للحصول على ذاكرة مشتركة قابلة للتنفيذ دون الحاجة إلى إنشاء ملف.
المزايا
- يمكن إنشاء مسارات سريعة لتنفيذ البرنامج، مما يقلل من بعض الفروع الشرطية المتكررة .
- يمكن للبرامج ذاتية التعديل أن تحسن كفاءة الخوارزميات .
العيوب
يصعب قراءة وصيانة الشيفرة ذاتية التعديل لأن التعليمات الواردة في قائمة البرنامج المصدر ليست بالضرورة هي التعليمات التي سيتم تنفيذها. قد لا يكون التعديل الذاتي الذي يتضمن استبدال مؤشرات الدوال غامضًا، إذا كان من الواضح أن أسماء الدوال المراد استدعاؤها هي مجرد عناصر نائبة لدوال سيتم تحديدها لاحقًا.
يمكن إعادة كتابة التعليمات البرمجية ذاتية التعديل كتعليمات برمجية تختبر علامة وتتفرع إلى تسلسلات بديلة بناءً على نتيجة الاختبار، ولكن التعليمات البرمجية ذاتية التعديل عادة ما تعمل بشكل أسرع.
يتعارض الكود ذاتي التعديل مع مصادقة الكود وقد يتطلب استثناءات من السياسات التي تتطلب توقيع جميع التعليمات البرمجية التي تعمل على النظام.
يجب تخزين الكود المعدل بشكل منفصل عن شكله الأصلي، مما يتعارض مع حلول إدارة الذاكرة التي تتخلص عادةً من الكود في ذاكرة الوصول العشوائي وتعيد تحميله من الملف القابل للتنفيذ حسب الحاجة.
في المعالجات الحديثة المزودة بخط أنابيب التعليمات ، قد يعمل الكود الذي يُعدّل نفسه باستمرار بشكل أبطأ، إذا عدّل تعليمات سبق للمعالج قراءتها من الذاكرة إلى خط الأنابيب. في بعض هذه المعالجات، تكون الطريقة الوحيدة لضمان تنفيذ التعليمات المُعدّلة بشكل صحيح هي مسح خط الأنابيب وإعادة قراءة العديد من التعليمات.
لا يمكن استخدام التعليمات البرمجية ذاتية التعديل على الإطلاق في بعض البيئات، مثل ما يلي:
- لا يمكن لبرامج التطبيقات التي تعمل تحت نظام تشغيل يتمتع بأمان W^X صارم تنفيذ التعليمات في الصفحات المسموح لها بالكتابة إليها - يُسمح لنظام التشغيل فقط بكتابة التعليمات إلى الذاكرة وتنفيذ تلك التعليمات لاحقًا.
- لا تستطيع العديد من وحدات التحكم الدقيقة ذات بنية هارفارد تنفيذ التعليمات في ذاكرة القراءة والكتابة، ولكنها لا تستطيع سوى تنفيذ التعليمات الموجودة في الذاكرة التي لا يمكنها الكتابة إليها، مثل ذاكرة القراءة فقط (ROM) أو ذاكرة الفلاش غير القابلة للبرمجة الذاتية .
- قد يحتوي التطبيق متعدد الخيوط على عدة خيوط تقوم بتنفيذ نفس الجزء من التعليمات البرمجية ذاتية التعديل، مما قد يؤدي إلى أخطاء في الحساب وفشل التطبيق.
انظر أيضاً
- رمز متداخل
- الشفرة متعددة الأشكال
- محرك متعدد الأشكال
- بنية بيانات ثابتة
- رمز AARD
- الكفاءة الخوارزمية
- الكود كبيانات
- بيان التقييم
- IBM 1130 (مثال)
- التجميع في الوقت المناسب : يمكن لهذه التقنية أن تمنح المستخدمين في كثير من الأحيان العديد من مزايا الكود ذاتي التعديل (باستثناء حجم الذاكرة) دون عيوبه.
- إزالة التعليمات البرمجية الميتة الديناميكية
- التماثل الأيقوني
- PCASTL
- كوين (الحوسبة)
- التكرار الذاتي
- البرمجة التأملية
- تعديل برمجي غير مباشر : هو تعديل يُجرى على كود وقت التشغيل ولا يؤثر على الكود المصدري الأصلي للبرنامج.
- البرمجة القابلة للتوسيع : نموذج برمجي يسمح للغة البرمجة بتعديل تركيبها النحوي.
- فيروس حاسوبي ذاتي التعديل
- الاستضافة الذاتية
- برمجة اصطناعية
- تهيئة المُترجم
- شفرة دقيقة قابلة للتعديل
ملحوظات
- ↑ قدمت الإصدارات اللاحقة من نظام التشغيل DOS (منذ الإصدار 6.0) الأمر الخارجي CHOICE (في DR-DOS أيضًا الأمر الداخلي وتوجيهCONFIG.SYS SWITCH ) ، لذلك، بالنسبة لتطبيق المثال المحدد هذا لنظام القوائم، لم يعد من الضروري الرجوع إلى مهام الدفعات ذاتية التعديل، ومع ذلك بالنسبة للتطبيقات الأخرى، فقد ظل حلاً قابلاً للتطبيق.
- على سبيل المثال، عند التشغيل على معالجات 386 أو أحدث، ستقوم تحديثات Novell DOS 7 اللاحقة، بالإضافة إلى DR -DOS 7.02 والإصدارات الأحدث، باستبدال بعض التسلسلات الافتراضيةلتعليمات 16 بت ("نسخ الكلمات") في صورة وقت تشغيل النواة بتعليمات 32 بت ( "نسخ الكلمات المزدوجة") عند نسخ البيانات من موقع ذاكرة إلى آخر (مع تقليل عدد التكرارات اللازمة إلى النصف) لتسريع عمليات نقل البيانات من القرص.ويتم التعامل مع الحالات الاستثنائية ، مثل الأعداد الفردية. [ 10 ] [ 11 ]
REP MOVSWREP MOVSD - ↑ على سبيل المثال، كانت سجلات التمهيد الرئيسية (MBRs ) وقطاعات التمهيد في نظام التشغيل DR-DOS (والتي تحتوي أيضًا على جدول التقسيم وكتلة معلمات BIOS ، مما يترك أقل من 446 و423 بايت للتعليمات البرمجية على التوالي) قادرة تقليديًا على تحديد موقع ملف التمهيد في نظام الملفات FAT12 أو FAT16 بنفسها وتحميله في الذاكرة ككل، على عكس نظيراتها في نظامي التشغيل MS-DOS / PC DOS ، والتي اعتمدت بدلاً من ذلك على ملفات النظام لشغل أول مدخلين في الدليل في نظام الملفات، وعلى تخزين القطاعات الثلاثة الأولى من ملف IBMBIO.COM في بداية منطقة البيانات في قطاعات متجاورة تحتوي على مُحمِّل ثانوي لتحميل باقي الملف في الذاكرة (مما يتطلب من SYS الاهتمام بكل هذه الشروط). عندإضافة دعم FAT32 و LBA ، لجأت مايكروسوفت إلى اشتراط استخدام تعليمات 386 وتقسيم كود الإقلاع على قطاعين لأسباب تتعلق بالحجم، وهو ما لم يكن خيارًا متاحًا لنظام DR-DOS لأنه كان سيؤدي إلى فقدان التوافق مع الإصدارات السابقة والتوافق المتبادل مع أنظمة التشغيل الأخرى في سيناريوهات الإقلاع المتعدد والتحميل المتسلسل ، بالإضافة إلى أجهزة الكمبيوتر القديمة . بدلاً من ذلك، اعتمدت قطاعات الإقلاع في DR-DOS 7.07 على كود ذاتي التعديل،وبرمجة على مستوى رمز العملية بلغة الآلة ، واستخدام مُتحكم به للآثار الجانبية (الموثقة)، وتداخل البيانات/الكود متعدد المستويات ، وتقنيات الطي الخوارزمية،وذلك لاحتواء كل شيء في قطاع فعلي بحجم 512 بايت فقط دون التخلي عن أي من وظائفها الموسعة.
مراجع
- ↑ "HP 9100A/B" . متحف آلات حاسبة HP (MoHPC) . 1998. ذاكرة البيانات والبرنامج المتداخلة / رمز التعديل الذاتي. مؤرشف من الأصل بتاريخ 23-09-2023 . تم الاطلاع عليه بتاريخ 23-09-2023 .
- ↑ "عبارة ALTER". مرجع لغة COBOL . مايكرو فوكس .
- ↑ سبيكتور، لي. "الحوسبة التطورية باستخدام الدفع: الدفع، والدفع جي بي، والدفع بوب" . تم الاسترجاع في 25-04-2023 .
- 1 2 فوسدال، لارس (2001). "ملف دفعي ذاتي التعديل" . مؤرشف من الأصل بتاريخ 21-04-2008.
- ^ ماتياس ر. بول (13/10/1996) [21/08/1996، 1994]. تعرف على الدعم الإداري الموسع في شبكة الكمبيوتر الشخصي وتحقق من اتصال Novell-LAN-Umgebung ضمن تحديث Batchsprache من DOS . 3.11 (باللغة الألمانية). آخن، ألمانيا: Lehrstuhl für Kommunikationsnetze ( ComNets ) و Institut für Kunststoffverarbeitung (IKV)، RWTH. ص 51، 71-72 . (110+3 صفحات، قرص مرن) (ملاحظة: تصميم وتنفيذ نظام إدارة موزع معياري يتم التحكم فيه مركزيًا لتكوين العميل التلقائي ونشر البرامج مع آلية تحديث ذاتية الإصلاح في بيئات الشبكة المحلية بناءً على مهام الدفعات ذاتية النسخ والتعديل الذاتي غير المباشر مع بصمة ذاكرة صفرية بدلاً من الحاجة إلى برامج إدارة مقيمة على العملاء.)
- ↑ باشي، تشارلز جيه؛ بوخهولز، فيرنر ؛ هوكينز، جورج في؛ إنجرام، جيه جيمس؛ روتشستر، ناثانيال (سبتمبر 1981). "بنية حواسيب IBM المبكرة" (ملف PDF) . مجلة IBM للبحوث والتطوير . 25 (5): 363-376 . CiteSeerX 10.1.1.93.8952 . doi : 10.1147/rd.255.0363 . ISSN 0018-8646 . تاريخ الاسترجاع: 25 أبريل 2023. ص 365:
كان SSEC أول حاسوب عامل قادر على التعامل مع تعليماته المخزنة تمامًا كبيانات، وتعديلها، والتصرف بناءً على النتيجة.
- ↑ ميلر، بارتون ب. (30 أكتوبر 2006). "تعديل الشفرة الثنائية: فن عريق مُحسَّن للقرن الحادي والعشرين" . سلسلة محاضرات ترايانجل المتميزة في علوم الحاسوب - ندوات 2006-2007. جامعة ولاية كارولاينا الشمالية ، قسم علوم الحاسوب . تاريخ الاسترجاع: 25 أبريل 2023 .
- ↑ وينزل، ماتياس؛ ميرزدوفنيك، جورج؛ أولريش، جوهانا؛ ويبل، إدغار ر. (يونيو 2019) [فبراير 2019، نوفمبر 2018، مايو 2018]. "من الاختراق إلى التقنية المُتقنة - دراسة استقصائية حول إعادة كتابة الملفات الثنائية" (ملف PDF) . مجلة ACM Computing Surveys . 52 (3). فيينا، النمسا: 49:1–49:36 [49:1]. doi : 10.1145/3316415 . S2CID 195357367. المقالة 49. مؤرشفة (ملف PDF) من الأصل بتاريخ 15 يناير 2021. تم الاطلاع عليها بتاريخ 28 نوفمبر 2021. ص. 49:1:
[…] في الأصل، كان الدافع وراء
إعادة كتابة البرامج الثنائية
هو الحاجة إلى تغيير أجزاء من البرنامج أثناء التنفيذ (على سبيل المثال، تصحيح وقت التشغيل على جهاز
PDP-1
في الستينيات) […]
(36 صفحة)
- ↑ كنوت، دونالد إرفين (2009) [1997]. "MMIX 2009 - حاسوب RISC للألفية الثالثة" . مؤرشف من الأصل بتاريخ 27-11-2021 . تم الاطلاع عليه بتاريخ 28-11-2021 .
- 1 2 3 "مجموعة أدوات المصدر القابلة للقراءة آليًا لنظام التشغيل OpenDOS من كالدرا (MRS) 7.01" . شركة كالدرا، 1997-05-01. مؤرشف من الأصل في 2021-08-07 . تم الاطلاع عليه في 2022-01-02 .
- 1 2 3 بول، ماتياس ر. (2 أكتوبر 1997). "Caldera OpenDOS 7.01/7.02 Update Alpha 3 IBMBIO.COM README.TXT" . مؤرشف من الأصل بتاريخ 4 أكتوبر 2003. تم الاطلاع عليه بتاريخ 29 مارس 2009 .
- ↑ ويلكنسون، ويليام "بيل" ألبرت (2003) [1996، 1984]. "دودة H89: اختبار ذاكرة H89" . صفحة شركة بيل ويلكنسون هيث . مؤرشفة من الأصل في 13 ديسمبر 2021. تم الاسترجاع في 13 ديسمبر 2021. [
...] بالإضافة إلى جلب التعليمات، يستخدم
معالج Z80
نصف الدورة
لتحديث
ذاكرة
الوصول العشوائي الديناميكية
. [...] بما أن معالج Z80 يقضي نصف كل دورة
جلب تعليمات
في أداء مهام أخرى، فإنه لا يملك الوقت الكافي لجلب
بايت التعليمات
كما يفعل مع بايت البيانات. إذا كانت إحدى
رقائق ذاكرة الوصول العشوائي
في موقع الذاكرة الذي يتم الوصول إليه بطيئة بعض الشيء، فقد يحصل معالج Z80 على نمط بت خاطئ عند جلب التعليمات، ولكنه يحصل على النمط الصحيح عند قراءة البيانات. [...] لن يكتشف اختبار الذاكرة المدمج هذا النوع من المشاكل [...] إنه اختبار قراءة/كتابة بيانات فقط. أثناء الاختبار، يتم جلب جميع التعليمات من
ذاكرة القراءة فقط (ROM)
، وليس من ذاكرة الوصول العشوائي (RAM)، مما يؤدي إلى اجتياز معالج
H89
لاختبار الذاكرة، ولكنه لا يزال يعمل بشكل غير منتظم مع بعض البرامج. هذا برنامج يختبر الذاكرة عن طريق إعادة توجيه نفسه عبر ذاكرة الوصول العشوائي. أثناء ذلك، يطبع المعالج عنوان البرنامج الحالي على
شاشة العرض
، ثم يجلب التعليمات من ذلك العنوان. إذا كانت دوائر ذاكرة الوصول العشوائي سليمة عند ذلك العنوان، ينقل المعالج برنامج الاختبار إلى موقع الذاكرة التالي، ويطبع العنوان الجديد، ويكرر العملية. ولكن، إذا كانت إحدى دوائر ذاكرة الوصول العشوائي بطيئة بما يكفي لإرجاع نمط بتات غير صحيح، فسيفسر المعالج التعليمات بشكل خاطئ ويتصرف بشكل غير متوقع. ومع ذلك، من المحتمل أن تتوقف الشاشة عن العمل، وتعرض عنوان الدائرة المعيبة. هذا يقلل عدد الدوائر المعيبة إلى ثماني دوائر، وهو تحسن ملحوظ مقارنةً بفحص ما يصل إلى 32 دائرة. سيقوم البرنامج بإجراء اختبار الدودة عن طريق دفع تعليمة RST 7 (إعادة التشغيل 7) من الطرف الأدنى للذاكرة وصولاً إلى آخر عنوان يعمل بشكل صحيح. يبقى باقي البرنامج ثابتًا ويتولى عرض الموقع الحالي لأمر RST 7 ونقله
.
ويُطلق على البرنامج اسم " اختبار
الدودة
" لأن تعليمة RST 7، أثناء انتقالها عبر الذاكرة، تترك وراءها
سلسلة
من
أوامر NOP
(لا عملية).
- ↑ أورتيز، كارلوس إنريكي (29 أغسطس 2015) [18 أغسطس 2007]. "حول الشفرة ذاتية التعديل ونظام تشغيل مكوك الفضاء" . تم الاطلاع عليه بتاريخ 25 أبريل 2023 .
- ↑ منشورات يورغن شميدهوبر حول الشفرة ذاتية التعديل لأنظمة التعلم الآلي ذاتية المرجعية
- ↑ بالتسيف، يفغيني (30 يناير 2020). "البرمجيات ذاتية التعديل في نواة لينكس - ما هي، وأين، وكيف" . تم الاطلاع عليه بتاريخ 27 نوفمبر 2022 .
- ↑ فيتشوركيفيتش، باويل. "بدائل نواة لينكس" . تم الاسترجاع في 27-11-2022 .
- ↑ بو، كالتون ؛ ماسالين، هنري ؛ إيوانيديس، جون (1992). التوليف: تطبيق فعال لخدمات نظام التشغيل الأساسية (ملف PDF) (أطروحة دكتوراه). نيويورك، الولايات المتحدة الأمريكية: قسم علوم الحاسوب، جامعة كولومبيا . رقم طلب UMI: GAX92-32050 . تاريخ الاسترجاع: 25 أبريل 2023 .
- ↑ هينسون، فاليري (20 فبراير 2008). "KHB: Synthesis: An Efficient Implementation of Fundamental Operating Systems Services" . LWN.net . مؤرشف من الأصل بتاريخ 17 أغسطس 2021. تم الاطلاع عليه بتاريخ 19 مايو 2022 .
- ^ هايبرلي، بول ؛ كارش ، بروس (1994/02/03). "Io Noi Boccioni - خلفية عن البرمجة المستقبلية" . الرسوم البيانية الغامضة . تم الاسترجاع 2023-04-25 .
للمزيد من القراءة
- أكيسون، لينوس (31 مارس 2013). "فك تشفير GCR أثناء التشغيل" . مؤرشف من الأصل بتاريخ 21 مارس 2017. تم الاطلاع عليه بتاريخ 21 مارس 2017 .
- بوركيرت ، كريستيان فيليكس (2012/03/20). Eine Bibliothek für Selbstmodifikationen zur Laufzeit in Java [ مكتبة للتعديلات الذاتية في وقت التشغيل في Java ] (PDF) (الأطروحة) (باللغة الألمانية). جامعة سارلاند ، كلية العلوم الطبيعية التقنية الأولى، كلية تكنولوجيا المعلومات. مؤرشفة (PDF) من النسخة الأصلية بتاريخ 2023-08-18 . تم الاسترجاع 2023-08-18 .(80 صفحة)
روابط خارجية
- نماذج البرمجة
