/Into the Low Level: Assembling (0x04)

Into the Low Level: Assembling (0x04)

قبل أن نتحدث عن لغه الاسمبلي يجب أن نتحدث عن الكيفيه التي تنفذ بها البرامج تحت الماكينه.
تنفذ البرامج فى مستوي الماكينه على هيئه مايسمي كود الماكينه وكود الماكينه يختلف من نوع ماكينه الى اخر فقد يختلف من x86 الى ARM الى SPARC.
وليس فقط البرامج ولكن طريقه تخزين البيانات فى الذاكره..فالذاكره عباره عن أرقام ثنائيه (binary) ويختلف ماتعبر عنه الارقام على حسب طريقه المعالجه. فعلي سبيل المثال قد تكون كود اسكي ASCII اذا كانت حروف او سترنج يتم استخدامه فى البرنامج وقد تكون تلك الارقام كود ماكينه يتم تنفيذه. هيا نلقي نظره على كود الآله أو الماكينه :).
اذا كنت من مستخدمي نظام التشغيل لينوكس جنو..افتح الكونسول Terminal ونفذ الامر hd /bin/ls ستري الخرج التالي

ينقسم الخرج الى ثلاث أجزاء رأسيه.. أول جزء أقصي الشمال يمثل عنوان كود الماكينه بالنسبه إلى بدايه البرنامج فهو يعتبر إزاحه عن أول كود. أما العنونة الحقيقية فى الذاكرة فتتم عن طريق نظام التشغيل والكومبيلر او مايسمي ال Linker.
أما القسم الثاني فهو كود الآله الذي يتم معالجته لتنفيذ غرض معين. أما القسم الثالث فهو يمثل كل بايت بحرف ASCII للاستدلال على الحروف والسترنجس.
والان لنجرب تنفيذ نفس الامر على ملف تكست.
كما تري لا يوجد اي كود اله ولكن الكود الوجود هو ASCII code يمثل الحروف الموجوده داخل الملف. الارقام كما هى فى الصوره هى تنتمي للنظام السادس عشر. والارقام داخل الماكينه كما ذكرت من قبل تعالج وهى بالنظام الثنائي! ولكن وضع الارقام ذات القاعده السادسه عشر هى اختصار لتفادي حجم الخرج اذا كان الكود على الصوره الثنائيه.
اتجاه التخزين (Endianness) :-
هناك نوعين من اتجاهات التخزين. Little endian و Big endian.
الماكينه x86 تستخدم اتجاه التخزين Little Endian. وفيه يتم تخزين البيانات بطريقه عكسيه عن طريقه معالجتها. على سبيل الرقم 157 يتم تخزينه فى بايت واحد بقيمه 9D. والرقم 17254 يتم تخزينه فى 2 بايت بقيمه 1E AC ولكن هنا يختلف اتجاه التخزين فيتم تخزين تلك القيمه بأتجاه عكسي على الشكل AC 1E. اما الحروف فيتم تخزينها فى الاتجاه الطبيعي
اما اتجاه التخزين Big Endian فيه يتم تخزين البيانات بنفس الاتجاه المعتاد.
لغة التجميع :-
تختلف طريقه كتابه اللغه ونوع اللغه التى تستخدمها على حسب نوع المجمع(Assembler) والماكينه (Architecture). فهناك مايسمي ب x86 assembly وهو لغه التجميع الخاصه بالماكينه IA32 وهناك ايضا MIPS, ARM.68K. ولكنا سنتحدث عن ال x86 assembly.
تنقسم طريقه كتابه لغه التجميع تحت الماكينه x86 الى نوعين (Intel sytanx, AT&T syntax) . يستخدم المجمع GNU Assembler طريقه الكتابه AT&T. اما المجمع Netwide assembler, Microsoft assembler and Turbo assembler فيستخدمون طريقه الكتابه Intel.
سأتحدث فى تلك المقاله عن استخدام لغه التجميع تحت نظام التشغيل جنو لينوكس. وقبل ان اشرح طريقه كتابه اللغه وتنفيذ الكود يجب اولا معرفه مايسمي باستدعاءات النظام. وهى تنفيذ كود معين فى نظام التشغيل له غرض معين عن طريق وضع قيم محدد بسجلات(ريجسترات) ذات الاغراض العامه. تستطيع ان تجد تلك الاستدعاءات هنا
على سبيل المثال استدعاء النظام exit. غرضه هو انهاء تنفيذ برنامج فى قيد التنفيذ، ويتم تنفيذ اي استدعاء للنظام عن طريق الامر int 0x80.
ماهو ال int 0x80؟
اولا كلمه int تعبر عن interrupt ولكن لنطلق عليه قاطع. القاطع 80 يسمي ب قاطع استدعائي لانه يستخدم فى تنفيذ استدعاءات النظام. و طريقه عمله انه يقوم بتنفيذ استدعاء النظام من جدول استدعاءات النظام الموجود داخل كود نظام التشغيل جنو لينوكس حسب قيمه السجلات(الريجسترات).
العمليات علي الريجسترات.
تختلف انواع العمليات على الريجسترات فهناك اوامر لنقل البيانات واوامر حسابيه علي سبيل المثال.
سنبدأ بالامر MOV.
الامر MOV هو غرضه نقل البيانات من مكان الى مكان فهو يكتب على النحو التالي
MOV destination, source
يسمي الأمر هنا Opcode وتسمي المعطيات بال Operands. هنا الامر يستقبل معطيين اولهم ماسينقل البيانات اليه والثاني ما سينقل منه. قد تكون تلك المعطيات على النحو التالي.
قد تكون نقل قيمه ثابته الى ريسجتر. MOV EAX,05h علي سبيل المثال يضع القيمه 5 داخل الريجستر EAX.
قد تكون نقل قيمه من ريجستر الى ريجستر. MOV EAX,EBX هنا توضع القيمه التى هى داخل EBX فى  EAX.
قد تكون نقل قيمه من ريجستر الى مكان ما بالذاكره. MOV [EDX], EAX. هنا توضع القيمه الى داخل الريجستر EAX فى عنوان الذاكره الذي هو القيمه التى بداخل الريجستر EDX.
قد تكون نقل قيمه من مكان بالذاكره الى اخر. MOV [EAX],[EBX]. هنا يتم نقل القيمه التى داخل عنوان الذاكره صاحب قيمه الريجستر EBX الى عنوان الذاكره صاحب قيمه الريجستر EAX.
اولا سنعمل على ال MOV REGISTER,REGISTER .
البرنامج التالى ينفذ امر نقل واحد داخل ريجستر ثم يخرج.
MOV edx,1h
MOV eax,1h
MOV ebx,0h
int 80h
أولا يضع القيمه واحد داخل الريجستر edx ثم يبدا تنفيذ استدعاء النظام exit ويضع قيمه ال eax واحد. وقيمه ال ebx التي تعبر عن حاله الخروج..نظرا لعدم وجود اي اخطاء ستكون بصفر ثم احداث قاطع او انتربت استدعائي. سنناقش المزيد عن الامر MOV و لغه التجميع.. المقاله القادمه ان شاء الله .