سؤال

لقد رأيت fastcall تم إلحاق التدوين قبل العديد من الوظائف.لماذا يتم استخدامه؟

هل كانت مفيدة؟

المحلول

هذا التدوين قبل الوظيفة يسمى "اتفاقية الاتصال". إنه يحدد كيف (على مستوى منخفض) سيقوم برنامج التحويل البرمجي بتمرير معلمات الإدخال إلى الوظيفة واسترداد نتائجه بمجرد تنفيذها.

هناك العديد من اصطلاحات الاتصال المختلفة، وأكثرها شيوعًا stdcall و cdecl.

قد تظن أن هناك طريقة واحدة فقط للقيام بذلك، ولكن في الواقع، هناك العشرات من الطرق التي يمكنك من خلالها استدعاء دالة وتمرير المتغيرات إليها وإليها.يمكنك وضع معلمات الإدخال على المكدس (ادفع، ادفع، ادفع للاتصال؛pop، pop، pop لقراءة معلمات الإدخال).أو ربما تفضل لصقها في السجلات (هذا هو fastcall - يحاول احتواء بعض معلمات الإدخال في سجلات السرعة).

ولكن بعد ذلك ماذا عن النظام؟هل تدفعهم من اليسار إلى اليمين أو من اليمين إلى اليسار؟ماذا عن النتيجة - هناك دائمًا واحدة فقط (بافتراض عدم وجود معلمات مرجعية)، فهل تضع النتيجة على المكدس، في السجل، على عنوان ذاكرة معين؟

لنفترض أيضًا أنك تستخدم المكدس للتواصل - من هي مهمة مسح المكدس فعليًا بعد استدعاء الوظيفة - المتصل أم المستدعى؟

ماذا عن النسخ الاحتياطي ثم استعادة محتويات سجلات وحدة المعالجة المركزية (بعضها) - هل يجب على المتصل القيام بذلك، أم سيضمن المستدعى أنه سيعيد كل شيء كما كان؟

اصطلاح الاتصال الأكثر شيوعًا (حتى الآن) هو cdecl, ، وهو اصطلاح الاتصال القياسي في كل من C وC++.يستخدم WIN32 API stdcall, مما يعني أن أي كود يستدعي WIN32 API يحتاج إلى استخدامه stdcall لتلك المكالمات الوظيفية (مما يجعلها خيارًا شائعًا آخر).

fastcall يعد أمرًا غريبًا بعض الشيء - فقد أدرك الأشخاص العديد من الوظائف باستخدام معلمة دخول/خروج واحدة فقط، كما أن الدفع والظهور من مكدس قائم على الذاكرة يمثل قدرًا كبيرًا من الحمل ويجعل استدعاءات الوظائف ثقيلة بعض الشيء، لذا تم تقديم مترجمين مختلفين (مختلفين) ) استدعاء اصطلاحات من شأنها وضع معلمة واحدة أو أكثر في السجلات قبل وضع الباقي في المكدس للحصول على أداء أفضل.المشكلة هي أنه لم يستخدم جميع المترجمين نفس القواعد فيما يتعلق بما يحدث وأين ومن يفعل ماذا fastcall, ونتيجة لذلك عليك أن تكون حذرًا عند استخدامه لأنك لن تعرف أبدًا من يفعل ماذا.وأخيرا، انظر هل fastcall أسرع حقًا؟ للحصول على معلومات حول fastcall فوائد الأداء.

أشياء معقدة.

شيء مهم يجب مراعاته:لا تقم بإضافة أو تغيير اصطلاحات الاتصال إذا كنت لا تعرف بالضبط ما تفعله، لأنه إذا لم يتفق كل من المتصل والمستدعى عليه على اتفاقية الاتصال، فمن المحتمل أن ينتهي بك الأمر إلى تلف المكدس وsegfault.يحدث هذا عادةً عندما يتم استدعاء الوظيفة في مكتبة DLL/مشتركة ويتم كتابة برنامج يعتمد على DLL/SO/dylib كونه اصطلاح استدعاء معين (على سبيل المثال، cdecl)، ثم تتم إعادة ترجمة المكتبة باستخدام اصطلاح استدعاء مختلف (على سبيل المثال، fastcall).الآن لم يعد بإمكان البرنامج القديم التواصل مع المكتبة الجديدة.

نصائح أخرى

Wikipedia تنص على أن

قد تم توحيد اتفاقيات

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top