ممكن تشرحوا لي كيف أدخل كود أسمبلي في السي++ ؟؟ مع شرح بمثال لدالة ومثال لكود عادي :)
ممكن تشرحوا لي كيف أدخل كود أسمبلي في السي++ ؟؟ مع شرح بمثال لدالة ومثال لكود عادي :)
السلام عليكم.
الأخ me إن عملية كتابة تعليمات Assembly ضمن C++ هي بسيطة و يكفي كتابة _asm قبل كل تعليمة Assembly مثل :
_asm mov eax,10 _asm add eax,5
أو يمكن استخدام ال Block لتجميع عدة تعليمات Assembly مثل :
_asm
{
mov eax,10
add eax,5
}هذا شرح سريع لكيفية كتابة تعليمات Assembly ضمن C++ و أنا جاهز لأي أسئلة أخرى.
مع التحيات.
وهل هذه التعليمات سوف تنفذ في مكان كتابتها أم يجب إستدعائها ؟؟
ترى عندي كومت أسئلة عن السي جاهز للتزهيق ؟؟ :):) ترى أمزح لكن عندي أسئلة وااااااااجددددددد
الصراحه أن الأخ الفاضل Adel Khayata "كفى و وفى" جزاه الله خيرا .
لكن لدي بعض المعلومات التي التي أحببت أن تشاركوني بها و هي :-
أولا :- عندما تريد كتابة كود أسمبلي يمن أن ستخدم أيضا __asm .
ثانيا :- كما قال أخي تنفيذ كود الأسمبلي يتم خطوه خطوه حسب ورودها في البرنامج أو بطريقه أخرى بالنفس الطريقه التي تنفذ بها كود سي "خطوه خطوه" أو "حبه حبه" ;) ;)
ثالثا :- بالنسبه لوضع المسجلات و المكدس و ما إلى ذلك عندما تريد كتابة كود أسمبلي في سي . فهو لا يتغير عند دخولك في بلوك يحتوي على كود أسمبلي .
على سبيل المثال تخيل معي أنك تنفذ كود في سي++ و نفذت آخر أمر في سي ++ الذي بعده تبدأ بتنفيذ تعليمات الأسمبلي . نفترض أنك أنهيت تعليمة سي++ و كان محتويات المسجل ecx هي 00000054h فعندما تدخل في البلوك الأسمبلي لن يتغير هذا المحتوى مالم تقم أنت بتغييره .
و من هذا كله نستنتج أنه إذا كانت هناك أكثر من بلوك أسمبلي في برنامج فإن كل بلوك يكون منفصل تماما عن أخيه .
رابعا :- و كما قال أخي يمكن أن تقوم بنقل محتويات أحد المتغيرات إلى أحد المسجلات عن طريق ذكر إسم المتغير داخل بلوك الأسمبلي و فيما ييلي سوف أعرض كود يقوم بنقل محتوى متغيرين في لغة سي ++ إلى مسجلين مختلفيت لكي تقوم الأسمبلي بجمعها :-
int MyFunc(int var1 , int var2 )
{
__asm {
mov eax ,var1
mov ecx ,var2
add eax ,ecx
}
}خامسا :- القيم المسترجعه (Returned Value) طبعا سوف تستعجب لهذا الكود لأني قمت بكتابة الداله أعلاه على أنها تعيد int لكنها لم ترجع شيئا ( هذا ماتعتقده ) لكن مهلا إن نفذت الكود أعلاه ستجد أن المصرف يقبل هذا الكود و يكتفي بتحذيرك عن عدم وجود قيمه مسترجعه . ولكن كيف ......... أليس عدم وجود قيمه مسترجعه غي هذه الداله يعتبر خطأ قواعديا لايمكن أن يغفره المصرف لك بهذه السهوله ؟!! و الجواب أن المسجل EAX يستخدم فيما يستخدم من أجله لكي يستوعب القيم السترجعة.
فنحن هنا قمنا بجمع المتغيرين و الناتج وضعناه في المسجل EAX و هذا يكفل أن يكون الناتج هو القيمه المسترجعه .
يبقا لنا سؤال واحد ألا و هو كيف نزيل التحذير الذي يظهره لنا المصرف ، صراحه أنا لم أقوم بتجربته لكن حسب ما ماكتب في MSDN ، أنه يمكن أن تزيل هذا التخذير عن طريق :-
#pragma warning
طبعا الكود أعلاه لا يكتب بالصوره التي أعلاه لكن إن كنت تريد مزيدا من التفصيل قم بالبحث عنها في MSDN
أحببت فقط أن أرخص بعض المعلومات المتعلقه بلغة الأسمبلي داخل سي و ليس كلها حيث بقيت مواضيع مثل تمرير المتغيرات أو الوسطاء إلى المكدس و أيضا calling conventions نتركعها لأهل الأختصاص
تحياتي...........................
يعطيك ألف عافية صديقي سمارت ، وأشكرك ياأخي عادل على اجابتك ..
بصراحة لا يوجد اختلاف بين _asm و __asm وهما موجودان من أجل التوافقية مع بقية المترجمات . لكن يفضل استخدام __asm في الفيجوال سي ..
في موضوع بالنسبة للمسجلات المستخدمة في بلوك الأسمبلي غير ال eax .. أي مسجل يستخدم يقوم المترجم بشكل آلي بتوليد تعليمات الأسمبلي في بداية ونهاية الروتين تقوم بدفع قيم المسجلات المستخدمة إلى المكدس وسحبها منه عن طريق تعليمتي PUSH و POP ..
طبعا يمكن أن تستعمل تعليمات القفز بالأسمبلي للقفز إلى خارج بلوك الأسمبلي ..
أخي سمارت أعتقد أنك يجب أن تحدد رقم ال warning من أجل الغائه وهو في هذه الحالة الرقم 4035 .. وبالتالي يصبح تابعك كالتالي :
// Disable the (no return value) warning
#pragma warning(disable : 4035)
int MyFunc(int var1 , int var2 )
{
__asm {
mov eax ,var1
add eax ,var2
}
}
// return it back to the default situation
#pragma warning(default : 4035)أو طبعا يمكن دفع حالة المترجم إلى مكدسه ومن ثم سحبها وهذا أفضل في حالة نريد الغاء أكثر من warning واحد ..
=============
ممكن أشارك بكود وضعته من زمن في منتدى الفيجوال بيسك وهو طبعا في الفيجوال سي ولكنه اجابة على أحد الأخوة في ذاك المنتدى . الكود يقوم بالحصول على رقم المعالج بدأ من بنتيوم 3 الرقم هم SN وهو وحيد من أجل المعالج :
#include
typedef unsigned long DWORD;
enum BOOL { FALSE, TRUE };
BOOL GetCPU_ID(DWORD &lo, DWORD &hi)
{
BOOL res = TRUE;
__asm {
mov eax, 1
cpuid
and edx, 0x00040000
jz notSuportSN
mov eax, 3
cpuid
mov esi, lo
mov [esi], ecx
mov esi, hi
mov [esi], edx
jmp finish
notSuportSN:
mov res, 0
finish:
}
return res;
}
int main()
{
DWORD lo, hi;
if (GetCPU_ID(lo, hi))
{
printf("CPU SN# = %08X%08Xn", hi, lo);
}
else
{
printf("This CPU doesn't support SN feature..n");
}
return 0;
}طبعا الأسمبلر المدمج مع الفيجوال سي قوي جدا وبامكانه دعم تعليمات ال MMX وأنا قمت بعمل مشروع دمج بين الصور باستخدام ال MMX إذا كنتم متحمسين للموضوع حتى أضع البرنامج مع الكود هنا .. وهو تطبيق يوضخ فرق السرعة بين استخدام كود MMX وكود عادي في عملية Fade-IN و Fade-OUT للصور .. الخوارزمية أنا كتبتها وبرمجتها وهي سهلة للغاية .. وهي تعتمد على علم الأشعة في الرياصيات ... :)
Coding on the Cloud and for the Cloud!
هذه كوت أسئلتب الظاهر عندنا متخصصين أهني ولله الحمد أحين أقدر أرتاح :)
1)ما هو نظام الملفات بالظبط وبأي لغة يسووه عادتا ؟؟
1) لو سويت أنا نظام وإلى هذا النظام طبعا نظام ملفات خاص به أقصد خاص بالنظام ألي سويته أولا هل كومبايلر السي++ من بورلاند الايت (الخفيف) يقدر يشتغل في نظامي (أقصد ما يظرر من نظام الملفات حقي) ؟؟ وثانيا هل لو اشتغل الكومبايلر هل البرامج ألي با سويها فيه رايح تشتغل في النظام حقي بعد ؟؟؟؟ وإذا كان الجواب لا فأي كومبايلر يشتغل وهل لا زم أسوي ليي كومبايلر خاص بنظامي عشان يشتغل ؟؟
3)هل الأسمبلي (masm,tasm)(أو أي نوع لكن أرجوا التحديد في إجاباتكم) كذلك يعني :(طبق نفس السؤال الثاني بس بدل كلمة سي++ بالأسمبلي (masm,tasm) أو أي نوع) .
4)وش الفرق بين masm و tasm وأيهما أفضل؟؟
5)كيف أقدر أحسب سرعة برنامجين واحد بالسي وواحد بالأسمبلي ؟؟
6)كيف أقدر أسوي دالة بالأسمبلي وأقدر أستدعيها من السي++؟؟ (طبعا كل الكود بينكتب في كومبايلر السي أقصد إن كود الأسمبلي وكود السي بينكتبو أثنينهم في السي++)
7)أي كومبايلرات السي++ أحسن وأفضل وأسرع ؟؟
8) هل كل الأسمبلرات تدعم تعليمات MMX,3DNOW وغيرها ؟؟ وكيف أقدر أحصل على هذه التعليمات هل هي لايبراري (مكتبة) أو إني لابد أغير الأسمبلر حقي بواحد ثاني يدعم هذه التقنيات , وويش أحسن أسمبلر حاليا؟؟
:):):) بعد ولا خلاص أقول خلاص لكن ترى في بعد لكن بعدين :)
شكرا على اهتمامكم :)
آه نسيت في حاجة مهمه
الأسمبلرات ... منه المفترض فيه برمجتها ؟؟ شركات المعالجات أم شركات البرمجيات ؟؟ وبأي لغة يتم برمجتها وكذلك اللنكر من وكيف؟؟ :):):)
السلام عليكم.
أخي me عطيناك وش و صرت تكتر علينا الأسئلة:)عمبمزح :)
سأحاول أن أجيب على بعض أسئلتك:)
نظام توضع الملفات أو File Allocation Table (FAT) هو النظام الذي يخزن نظام التشغيل بواسطته المجلدات و الملفات فمثلا لو كان عندك ملف كبير نوعا ما فإن نظام التشغيل سيقوم بتجزئته إلى مجموعة أجزاء و يخزن هذه الأجزاء على القرص و من ثم يضع مؤشرات إلى هذه الأجزاء في FAT من أجل عملية تجميع الملف عند طلبه مرة أخرى و حجم الجزء الواحد يتحدد بما يسمى ال Cluster و هو عبارة عن مجموعة من القطاعات Sectors و هو يختلف باختلاف نوع نظام الملفات المستخدم حيث يوجد عدة أنظة توضع للملفات منها FAT12 المستخدم لتخزين الملفات على القرص المرن و FAT16 المستخدم لتخزين الملفات على القرص الصلب و هذا النظام قديم و تم تحديثه مع الاصدارة الثانية من Windows95 فأصبحت Fat32 و يوجد أيضا NTFS ( New Technology File System ) المستخدم مع أنظمة Windows NT و Windows2000 و أيضا CDFS(Compact Disc File System) لتخزين الملفات على القرص الليزري و HPFS(High Perfomance File System) المستخدم في نظام Netware و العديد العديد من أنظمة توضع الملفات ... الخ.
أما الفرق بين هذه الأنظمة فهو كالتالي:
FAT16 نظام قديم و تقريبا انقرض و يدعم فقط حتى 2GB لل Partition الواحد و يمكن استعماله من قبل جميع أنظمة Windows.
FAT32 و هو نظام جديد و أفضل من FAT16 و يدعم حتى 4TB لل Partition الواحد و يمكن استعماله من قبل الاصدارة الثانية من Windows95 و Windows98 و Windows2000 و حجم ال Cluster فيه أصغر من سابقه FAT16
NTFS و هو نظام خاص بأنظمة WindowsNT و Windows2000 و هو نظام يتميز بصغر حجم ال Cluster و امكانية وضع تقييدات Security على من له الحق بعرض البيانات أو تعديلها أو حذفها ... الخ.
طبعا موضوع ال FAT موضوع واسع و حاولت قدر الامكان اعطاء فكرة سريعة عنه.
و مما سبق ينتج أن اللغة المستخدمة لبرمجة نظام FAT هي لغة الأسمبلي لأن أي عملية يقوم بها نظام التشغيل تعتمد على قراءة أو كتابة الملفات و بالتالي يعتمد عليها نظام التشغيل بشكل كبير ( أنا لم أقرأ عن اللغة المستخدمة في برمجة نظام FAT و لكن باستخدام الحقائق السابقة أعتقد أن اللغة هي Assembly حصرا)
أما بالنسبة لتشغيل برامج على نظام التشغيل الخاص بك فهذه مسؤولية نظامك و أبسط مثال أن البرنامج الذي يعمل على Windows98 الذي يستخدم نظام FAT16 يستطيع العمل على نظام Windows98 الذي يستخدم نظام FAT32 و بالتالي فإن نظام التشغيل يشكل طبقة تعزل البرامج التي تعمل على نظامك عن نظام الملفات المستخدم.
بالنسبة لحساب سرعة برنامجين واحد بالسي وواحد بالاسمبلي فهل تقصد مقارنة السرعة بين اللغتين أم حساب الزمن المستغرق لانجاز مهمة معينة ضمن البرنامج ؟
بالنسبة لكتابة دالة بالاسمبلي ضمن السي ++ : اعتبر أنك تريد كتابة دالة عادية بالسي و بدل ما تحط ضمن هذه الدالة تعليمات سي ضع بدلا عنها تعليمات اسمبلي ثم استدعي الدالة كما تستدعي اي دالة عادية.
بالنسبة لأفضل كومبايلرات السي++ فأنا أستخدم لغة Visual C++ منذ خمس سنوات و قد أثبتت جدارتها و يكفي أن تلقي نظرة على الكتب الأجنبية التي تتحدث عن C++ و COM و Windows Architecture لتجد أن الامثلة مكتوبة بلغة Visual C++ كما أنني قرأت مرة في مقالة في مجلة أجنبية أن برنامج Corel Draw الشهير بتصميم و معالجة الرسوم قد تمت كتابته بلغة Visual C++ و الله أعلم.
أطلت عليك بس انت أسئلتك كانت كتييييييييييرة:)هلكتني:)
إذا احتجت إلى توضيح بعض الذي كتبته فأنا جاهز:)
مع التحيات.
وين أجوبت باقي الأسئلة :| :| ؟؟!!
أكلتها ؟؟!! واحن نطول أهني الأسئلة ليش...وش وظيفة المنتدى مو كرف الأسئلة كراف ؟؟ :) أمزح :)
ممكن توضح أكثر في نظام الملفات ؟؟ يعني هل هو يسجل البيانات أو مؤشرات (ومؤشرات لماذا لأرقام سكتورات على الهارد دسك يعني يشير إلى سكتور بداية الملف وسكتور نهايته (سكتور الإزاحة) ؟؟)
ورجاء أن يجيب على باقي أسئلتي واحد شاطر مثلك وهي في الأعلى :)
لكن ممكن صنع دالة بالسي++ لكن كيف صناعة ذلك بس بالأسمبلي ؟؟
وأنا أقصد في سؤالي عن حساب سرعة برنامجين واحد بالسي++ وواحد بالأسمبلي أي كيف أقدر حساب سرعة البرنامجين وليس المقارنة:)
صديقي مهند بالنسبة إلى كتابة دالة فقط في الأسمبلي راجع الموضوع الجديد :
وباقي أسئلتك كنت بدي أجاوبك عليها بس أنا خلص وقتي اليوم وإن شاء الله بكرة أو أحد الشباب الطيبة يجاوبك عليها .. :)
Coding on the Cloud and for the Cloud!
السلام عليكم.
أخي "me" إن نظام توضع الملفات FAT يسجل الازاحات و كمثال بسيط لنفترض أنه لدينا ملف يحتاج إلى 3 Clusters فسيكون FAT مشابه لما يلي:
القسم الأول للملف متوضع في المدخل 15 ل FAT و يشير إلى القسم الثاني للملف المتوضع مثلا في المدخل 27 و الذي يشير بدوره إلى القسم الثالث للملف ...
بالنسبة لحساب سرعة البرامج فأنا أعرف كيف تقوم بذلك في VisualC++ و لكن بالنسبة ل Assembly فهذه اللغة لم أعمل بها منذ 5 سنوات و سأترك الاجابة على هذا الجزء من السؤال لأحد الأخوة المتابعين مع لغة ال Assembly , و بالنسبة لحساب سرعة تنفيذ برنامج بلغة Visual C++ اكتب الشيفرة التالية :
clock_t start,end; HANDLE handle=GetCurrentProcess(); SetPriorityClass(handle,REALTIME_PRIORITY_CLASS); start=clock(); for(long i=0;i<1000000000;i++) ; end=clock(); SetPriorityClass(handle,NORMAL_PRIORITY_CLASS); double time=(double)(end-start)/CLOCKS_PER_SEC;
هنا قمت بجعل البرنامج له أولوية عظمى و ذلك حتى يتم احتساب الزمن بشكل دقيق و قبل تنفيذ العملية المراد معرفة الزمن الذي استغرقته ( و هي في حالتنا حلقة for ) نقوم بتنفيذ start=clock() التي تسجل رقما يعبر عن الزمن الذي انقضى منذ بداية تنفيذ البرنامج و بعد تنفيذ العملية ننفذ التعليمة end=clock() و بالتالي بالطرح بين القيمتين و تقسيمها على الثابت ( CLOCKS_PER_SEC وهو عدد النبضات في الثانية )نحصل على الزمن المطلوب و لكن لا تنسى أن تعيد البرنامج إلى مستوى الأولوية العادي.
مع التحيات.
وين أجوبت باقي الأسئلة ؟؟ ألي فوق منه ألي أكلهم :):) أرجوا الإجابة السريعة :(
:):):)
أخواني آسف لأن آتي بهذا الموضوع من الاعماق ولكن:
بالنسبة لكود الاستاذ عادل كلما نفذت البرنامج يظهر نتيجه مختلفة
وأحد المرات ظهرت النتيجة بالسالب :( ؟!؟
كيف يمكن للبرنامج أن يعمل تمام ,
مع تحياتي و لكم جزيل الشكر ,,,
هذا الموضوع مغلق.