مقدمة وخاتمة الوظيفة

في برمجة لغة التجميع ، يُمثل مقدمة الدالة بضعة أسطر من التعليمات البرمجية في بداية الدالة، تُهيئ المكدس والسجلات لاستخدامها داخل الدالة. وبالمثل، تظهر خاتمة الدالة في نهايتها، وتُعيد المكدس والسجلات إلى حالتها قبل استدعاء الدالة.

لا يُعدّ كلٌّ من المقدمة والخاتمة جزءًا من لغة التجميع نفسها؛ بل يُمثّلان اصطلاحًا يستخدمه مبرمجو لغة التجميع ، ومترجمو العديد من اللغات عالية المستوى . وهما جامدان إلى حدٍّ ما، إذ يتخذان الشكل نفسه في كل دالة.

تحتوي مقدمة وخاتمة الدالة أحيانًا على رمز لحماية تجاوز سعة المخزن المؤقت .

مقدمة

عادةً ما يقوم مقدمة الدالة بالإجراءات التالية إذا كانت البنية تحتوي على مؤشر أساسي (يُعرف أيضًا باسم مؤشر الإطار ) ومؤشر مكدس:

  • يدفع مؤشر القاعدة الحالي إلى المكدس، بحيث يمكن استعادته لاحقًا.
  • يتم تعيين قيمة مؤشر القاعدة إلى عنوان مؤشر المكدس (الذي يشير إلى أعلى المكدس) بحيث يشير مؤشر القاعدة إلى أعلى المكدس.
  • يُحرك مؤشر المكدس مسافةً أبعد عن طريق إنقاص قيمته أو زيادتها، وذلك بحسب اتجاه نمو المكدس، سواءً كان تنازليًا أو تصاعديًا. في معالجات x86، يتم إنقاص قيمة مؤشر المكدس لإفساح المجال للمتغيرات المحلية للدالة.

يمكن كتابة عدة مقدمات محتملة، مما ينتج عنه تكوين مختلف قليلاً للمكدس. هذه الاختلافات مقبولة، طالما أن المبرمج أو المترجم يستخدم المكدس بالطريقة الصحيحة داخل الدالة.

كمثال، إليك مقدمة نموذجية لدالة بلغة التجميع x86 كما ينتجها GCC

دفع ebp نقل ebp ، esp استبدل esp ، N

تمثل القيمة الفورية N عدد البايتات المحجوزة على المكدس للاستخدام المحلي.

يمكن تحقيق النتيجة نفسها باستخدام enterالتعليمات التالية:

أدخل N ، 0

يمكن الحصول على مقدمات أكثر تعقيدًا باستخدام قيم مختلفة (غير الصفر) للمعامل الثاني للتعليمات enter. تدفع هذه المقدمات عدة مؤشرات أساسية/إطارية للسماح بالدوال المتداخلة ، كما هو مطلوب في لغات مثل باسكال . مع ذلك، لا تستخدم الإصدارات الحديثة من هذه اللغات هذه التعليمات لأنها تحد من عمق التداخل في بعض الحالات.

خاتمة

تقوم خاتمة الدالة بعكس إجراءات مقدمة الدالة وإعادة التحكم إلى الدالة المُستدعِية. وعادةً ما تقوم بالإجراءات التالية (قد يختلف هذا الإجراء من بنية إلى أخرى):

  • قم بإسقاط مؤشر المكدس إلى مؤشر القاعدة الحالي، وبالتالي يتم تحرير المساحة المحجوزة في المقدمة للمتغيرات المحلية.
  • يقوم بإخراج مؤشر القاعدة من المكدس، بحيث تتم استعادته إلى قيمته قبل المقدمة.
  • يعود إلى الدالة المستدعِية، عن طريق إزالة عداد البرنامج الخاص بالإطار السابق من المكدس والقفز إليه.

ستعكس الخاتمة المذكورة آثار أي من المقدمتين السابقتين (سواء المقدمة الكاملة أو المقدمة التي تستخدم enter). وبموجب بعض اصطلاحات الاستدعاء، تقع مسؤولية تنظيف الوسائط من المكدس على عاتق الدالة المستدعاة، لذا يمكن أن تتضمن الخاتمة أيضًا خطوة تحريك مؤشر المكدس لأسفل أو لأعلى.

على سبيل المثال، يمكن إنجاز هذه الخطوات الثلاث في لغة التجميع x86 ذات 32 بت من خلال التعليمات التالية:

mov esp , ebp pop ebp ret

كما هو الحال في المقدمة، يحتوي معالج x86 على تعليمة مدمجة تُنفذ جزءًا من الخاتمة. الكود التالي يُكافئ الكود أعلاه:

اترك التقاعد

يقوم هذا leaveالتعليم بتنفيذ التعليمات movالمذكورة popأعلاه.

قد تحتوي الدالة على عدة نهايات. يجب أن ينتقل كل مخرج من الدالة إما إلى نهاية مشتركة، أو أن يحتوي على نهايته الخاصة. لذلك، غالبًا ما يستخدم المبرمجون أو المترجمون مزيجًا من `/` leaveو`/` retللخروج من الدالة في أي نقطة. (على سبيل المثال، يستبدل مترجم لغة Creturn عبارة ` leave/` retبتسلسل `/`).

للمزيد من القراءة