هل يمكن لشخص ما أن يفسر هذا التجميع مباشرة X86 JMP OPCODE؟

StackOverflow https://stackoverflow.com/questions/545093

سؤال

في المدرسة، كنا نستخدم برنامج Bootstrap لتشغيل برامج قائمة بذاتها دون نظام تشغيل. لقد كنت أدرس هذا البرنامج وعندما يتم تمكين الوضع المحمي هناك قفزة بعيدة تنفيذها مباشرة تجميع OPCODE والمعاملات كبيانات داخل البرنامج. كان هذا لتجميع جنو:


         /* this code immediately follows the setting of the PE flag in CR0 */

.byte   0x66, 0xEA
.long   TARGET_ADDRESS
.word   0x0010          /* descriptor #2, GDT, RPL=0 */

بادئ ذي بدء، لماذا يرغب المرء في القيام بذلك (بدلا من إرشادات Mnemonic)؟

لقد كنت أبحث في كتيبات إنتل، لكنني ما زلت مرتبكا قليلا من قبل الكود. على وجه التحديد في الحجم 2A، صفحة 3-549، هناك جدول من OPCodes. الدخول ذي الصلة:

EA * CP * JMP PTR16: 32 Inv. القفز الصالح بعيدا، مطلق، عنوان معين في المعامل

Opcode الفعلي واضح، ولكن البايت الأول، 0x66، وقد حظري. وبالإشارة إلى الجدول في دليل Intel، يعني CP أنه يعني أن معامل 6 بايت ستتبعه. ومن الواضح أن 6 بايت متابعة في السطرين المقبلين. 0x66 ترميز "بادئة تجاوز حجم المعامل". ماذا علاقة هذا مع CP في الجدول؟ كنت أتوقع أن تكون هناك بعض قيمة HEX ل CP، ولكن بدلا من ذلك، هناك بادئة تجاوز هذا. يمكن للشخص يرجى مسح هذا بالنسبة لي؟

هنا تفريغ من OD:

C022 ** EA66 0000 0001 0010 ** BA52 03F2 C030

تم تعريف الهدف_address باسم 0x00010000.

أنا أيضا مرتبك قليلا بأهمية آخر بايت. ومع ذلك، يبدو أن هذا هو سؤال آخر تماما. إنه يتأخر تماما، وقد كنت أحدق في الكود وأدلة إنتل لساعات، لذلك آمل أن أحصل على وجهة نظري.

شكرا للنظر!

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

المحلول

يشير 0x66 إلى أن JMP (0xea) يشير إلى ستة بايت. الافتراضي يشير إلى 64 كيلو (16 بت) في الوضع الحقيقي أو إلى 32 بت في الوضع المحمي (إذا كنت أتذكر جيدا). بعد زيادة ذلك، يشمل أيضا واصف القطاع، فهرس الجزء إما في GDT أو LDT، مما يعني أن هذا الرمز هو جعل ما يسمى تقليديا "القفز الطويل": قفزة تقاطع تتجاوز القطاعات في X86 الهندسة المعمارية. الجزء، في هذه الحالة، يشير إلى الدخول الثاني على GDT. إذا نظرت من قبل في هذا البرنامج، فمن المحتمل أن ترى كيف يتم تعريف GDT من حيث عنوان بدء الطبقات والطول (انظر في دليل Intel لدراسة جداول GDT و LDT، إدخال 32 بت وصف كل قطعة).

نصائح أخرى

أركض هذا قليلا. سيقفز بعض المجمعين فقط إلى تسمية. في هذه الحالة، يريد الشخص أن يقوم بالانتقال المطلق إلى إزاحة مشفرة بجدية محددة. JMP Target_Address لن تعمل أنا أظن، لذلك وضعوا الأمر على أنه بايت للحصول على هذه المشكلة.

0x66 يحدد حجم معامل حجم حجم شريحة الرموز الحالية. على افتراض أن حجم الرموز الحالي هو 16 بت، سيكون مؤشر التعليمات الجديد 32 بت وليس 16 بت. إذا كان حجم قطاع الرمز الحالي هو 32 بت، فسيقدم 0x66 مؤشر التعليمات المستهدفة ك 16 بت. تعتمد سمة حجم التعليمات البرمجية الحالية على محدد CS المستخدمة وسماتها المحملة من جدول GDT / LDT. في الوضع الحقيقي، يكون حجم شريحة رمز 16 بت باستثناء الحالات الخاصة لوضع "غير واقعي".

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