
أريد أن أعرف ماذا تعني ال Calling Conventions in C++ or C ؟ لأنني عندما عملت لها traduction في الشيخ Google
، ظهرت لي هذه الترجمة:

![]()
![]()
![]()

وإن كان بالإمكان أريد أمثلة في هذا الشأن و شكرا ![]()

أريد أن أعرف ماذا تعني ال Calling Conventions in C++ or C ؟ لأنني عندما عملت لها traduction في الشيخ Google
، ظهرت لي هذه الترجمة:

![]()
![]()
![]()

وإن كان بالإمكان أريد أمثلة في هذا الشأن و شكرا ![]()

الترجمة الصحيحة هي "Conventions d'appel" أو "اتفاقيات الإستدعاء".
اتفاقية الإستدعاء هي الطريقة التي تحدد الكيفية التي يتم بها استدعاء دالة معينة بأدق التفاصيل و بالأخص :
C++ and Java, say, are presumably growing faster than plain C, but I bet C will still be around. ― Dennis Ritchie
~OoO~________--------------------------------------------________~OoO~
من مواضيعي :
لا يختلف اثناء على ان معني call فى سي++ هو يستدعي .... وهي علمية تشغيل(اجراء routine) سواء كان( دالة او برنامج) من اجل مهمة ما او الحصول على نتائج الاجراء.
وعندما نضيف لــ call مصطلح Conventions كأننا نريد ان نقول:
ماهي برتوكولات استدعاء الدوال او البرامج؟ أو معنى آخر ما هي قوانين استدعاء دالة او اجراء؟
يمكننا وضع تعريف للمصطلح كــ:
ومن النقاط التى تختلف فيها قوانين الاستدعاء سواء من لغة الى آخر او من منصة تشغيل الى آخر هي:
قد تكون تفصيل فهم المصطلح مملة ولكن المعرفة بالشئ لا تضر.
تم تعديل هذه المشاركة بواسطة محمد عودة في 12 سبتمبر 2012 في 14:59
الـcalling conventions تصف الطريقة التي ستُستدعى فيها الدوال وكيف ستمرر المعاملات للدالة المُستدعاة ومن سيتولى عملية التنظيف بعد الإنتهاء , المُستدعى callee أم المُستدعي caller.
هناك عدّة أساليب لإستدعاء الدوال وأشهرها ثلاثة :
خُذ هذا البرنامج كمثال عليها:
#include <windows.h>
int __cdecl cde_call(int param1, int param2, int param3);
int __stdcall std_call(int param1, int param2, int param3);
int __fastcall fast_call(int param1, int param2, int param3);
int main(int argc, char **argv)
{
cde_call(1, 2, 3);
std_call(1, 2, 3);
fast_call(1, 2, 3);
return 0;
}
int __cdecl cde_call(int param1, int param2, int param3)
{
return 1;
}
int __stdcall std_call(int param1, int param2, int param3)
{
return 1;
}
int __fastcall fast_call(int param1, int param2, int param3)
{
return 1;
}فيه ثلاث دوال : cde_call وstd_call وfast_call جميعها نفس الشيء وتأخذ ثلاث مُعاملات int إلا أن كُل واحدة منها تستخدم طريقة إستدعاء مُختلفة ,لن يتأثر بها برنامجك أو سيختلف إستخدامك لأي منها أبداً, فهي تتم على مُستوى الآلة وسيحدث الإختلاف في البرنامج الناتج بعد التصريف.
الدالة الأولى : تستخدم إسلوب cdecl:
int __cdecl cde_call(int param1, int param2, int param3);
في هذا الإسلوب ستمرر المُعاملات للدالة المُستدعاة عن طريق المُكدس بطريقة مقلوبة وسبدو كود الأسمبلي لها هكذا :
... push 3 push 2 push 1 call cde_call add esp, 12 ...
لاحظّ أن المُستدعي caller هو من سيتولى التظيف بعد الإستدعاء, عندما دُفعت param1 وparam2 و param3 فالمكدس زاد بـ12 بايت (حجم كل منها 4 بايت * 3). يلزم إعادة المكدس لحالة. يُمكن عمل شيء مثل :
pop ebx pop ebx pop ebx
الا أنّك يُمكنك أن تعمل نفس الشيء بتعليمة واحدة "add esp, 12".
الدالة الثانية : تستخدم إسلوب std_call :
int __stdcall std_call(int param1, int param2, int param3);
يُسمى هذا الإسلوب stdcall أو pascal call (باسكال). وهو تماماً نفس cdecl من ناحية طريقة تمرير المُعاملات للدالة المُستدعاة :
... push 3 push 2 push 1 call std_call ...
إلا أن في هذا الإسلوب لايتولى المُستدعي مسؤولية التنظيف بعد الإنتهاء, بل ستتولاها الدالة المُستدعاة. تجده مُستخدم كثيراً في دوال ويندوز.
الدالة الثالثة : تستخدم إسلوب fastcall :
int __fastcall fast_call(int param1, int param2, int param3);
في هذا الإسلوب لايُستخدم المُكدس لمترير المُعاملات للدالة المُستدعاة. بل تُستخدم مُسجلات المُعالج :
... push 3 mov edx, 2 mov ecx, 1 call fast_call ...
هذا الإسلوب أسرع مقارنة بالإسلوبين الآخرين حيث أن التعامل مع مُسجلات المعالج أسرع من التعامل مع الذاكرة الا أنه محدود. فمثلاً عند تصريف المثال على ويندوز 32بت تجد إلا فقط المُسجلين ecx, ebx وباقي المُعاملات تُدفع للمُكدس. في بعض الأنظمة كلينكس يُستخدم حتى خمس مُسجلات, الا أنه أيضاً يُستخدم المُكدس إذا زاد على ذلك. تجد هذا الإسلوب مُستخدم في الدوال التي تُستخدم بكثرة كإستدعاءت النظام system calls , وهي دوال ذات أغراض عامة والتي بُنيت وتشكلت منها باقي دوال النظام.
يوجد اسلوب استدعاء يستخدم داخل الـ ++c يسمي بـ thiscall.
و الله ولي التوفيق
مدونتي: C++ Tips and Tricks
يُستخدم الاستدعاء thiscall مع الدوال الأعضاء الغير ساكنة (non static).
في الــ GCC, نجد أن thiscall مُطابق عمليا لــ cdecl لأن الدالة المُستدعية هي من يقوم بتنظيف المكدس كما يتم تمرير الوسائط من الأيمن إلى الأيسر, لكن الفرق يكمن في إضافة المؤشر this حيث تتم إضافته في نهاية المكدس كما لو كان الوسيط الأول.
في الــ MSVC يتم تمرير المؤشر this إلى المسجل ECX و المُستدعى (callee) هو من ينظف المكدس, على غرار الإستدعاء stdcall المُستخدم في C.
أما إذا كانت الدالة تستقبل عدد غير محدد من الوسائط فالمُستدعي caller هو من ينظف المكدس.
C++ and Java, say, are presumably growing faster than plain C, but I bet C will still be around. ― Dennis Ritchie
~OoO~________--------------------------------------------________~OoO~
من مواضيعي :
راجع الكُتيب الموجود في المرفقات سيفيدك جداً (خصوصا إن كان لديك إلمام بالأسمبلي :))