هل يجب أن البوب رمز الخطأ دفعت إلى كومة من قبل بعض الاستثناءات قبل عودته من معالج المقاطعة?

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

سؤال

لقد حملت أحد idt الجدول مع 256 إدخالات كل لافتا إلى معالجات مماثلة:

  • استثناءات 8 و 10 و 14 ، ودفع استثناء عدد (هذه الاستثناءات دفع رمز خطأ تلقائيا)
  • بالنسبة للآخرين ، دفع "دمية" رمز خطأ استثناء ؛
  • ثم القفز إلى معالج شيوعا

لذلك عندما المشترك معالج يدخل ، المكدس يتم محاذاة بشكل صحيح ويحتوي على الاستثناء/المقاطعة رقم رمز الخطأ (التي قد تكون مجرد دمية) ، eflags, cs السكان غير النشطين اقتصاديا.

سؤالي يتعلق عودته من معالج المقاطعة.يمكنني استخدام iret العودة بعد أخذ الاستثناء رقم و رمز الخطأ من المكدس, ولكن هذا لا ينفع الاستثناء nr 8;إذا تركت رمز الخطأ على المكدس ، ثم يعود على ما يرام!

الأسئلة:

  • هل يجب أن تترك رمز الخطأ على المكدس الاستثناءات التي وضعت رمز الخطأ هناك ؟ إذا كان الأمر كذلك, كيف iret تحديد ما إذا كان يجب أن البوب رمز خطأ أو لا ؟
  • في أقرب وقت كما كنت تمكين المقاطعات أنا دائما الحصول على استثناء 8 (خطأ مزدوج) ، ولكن بعد ذلك كل شيء يسير على ما يرام (انا تطوير هواية OS).هذا هو السلوك العادي أو علي خطأ في مكان ما ؟
هل كانت مفيدة؟

المحلول

إذا كانت وحدة المعالجة المركزية دفعت رمز خطأ تلقائيا, معالج يجب أن البوب قبل iret.على iret التعليمات لا تعرف من أين أتيت ، إذا كان خطأ ، فخ أو خارجي المقاطعة.دائما يحدث نفسه ، فإنه يفترض أن لا يوجد رمز الخطأ على المكدس.

نقلا عن الموجز (مطور برامج دليل) ، المجلد 3 من الفصل 5 القسم 5.13 بعنوان رمز الخطأ:

رمز الخطأ هو الضغط على المكدس كما doubleword أو كلمة (اعتمادا على المقاطعة الافتراضي ، فخ أو المهمة بوابة الحجم).للحفاظ على كومة الانحياز بالنسبة doubleword يدفع ، النصف العلوي رمز الخطأ محفوظة.ملاحظة رمز الخطأ ليس برزت عندما على IRET التعليمات يتم تنفيذها على العودة من معالج استثناء ، حتى المعالج يجب أن إزالة رمز الخطأ قبل تنفيذ العودة.

يمكنك العثور على IA-32 مطور برامج دليل هنا: http://www.intel.com/products/processor/manuals/

المجلد 3 الجزء 1 ، 5 الفصل يصف استثناء ومعالجة المقاطعة.المجلد 2 الجزء 1 المواصفات عن iret التعليمات.

نصائح أخرى

كتبت الصغيرة إلى x86 من نظام التشغيل في حين يعود.نلقي نظرة على الملف isr.asm في السير الذاتية مستودع.

لاحظ كيف وضعنا معالجات معظم دفع دمية dword إلى المكدس لحساب بعض معالجات تلقائيا الحصول على رمز خطأ دفعت.ثم عندما نعود عبر iret يمكننا أن نفترض دائما 2 dwords على المكدس بغض النظر عن المقاطعة و إجراء إضافة esp, 8 قبل iret لتنظيف الأمور بشكل جيد.

التي يجب الإجابة على السؤال الأول.

أما بالنسبة إلى السؤال الثاني:خطأ مزدوج عند تمكين المقاطعات ، ...هممم يمكن أن يكون مشكلة مع الترحيل إذا لم تكن إعداده بشكل صحيح.يمكن أن يكون هناك مليون شيء آخر أيضا :)

كان لي مشكلة مماثلة مع "أخطاء مزدوجة" في أقرب وقت أنا تمكين المقاطعات.حسنا ، لقد بدا مثل أخطاء مزدوجة ، ولكن كانوا حقا المقاطعات جهاز ضبط الوقت!

أخطاء مزدوجة هي المقاطعة رقم 8.

للأسف الافتراضي الموافقة المسبقة عن علم التكوين إشارات توقيت يقطع كما يقطع عدد (DEFAULT_PIC_BASE + TIMER_OFFSET) = (8 + 0) = 8.

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

(الهواة تتطلب وحدة المعالجة المركزية الاعتراف يقطع قبل أن تنتج المرحلة التالية.لأن التعليمات البرمجية الخاصة بك لم يكن الاعتراف الأولي توقيت المقاطعة الموافقة المسبقة عن علم لم أعطيك أي أكثر!هذا هو السبب في أنك حصلت على واحدة فقط ، بدلا من زليون واحد قد يكون من المتوقع.)

هل يجب أن تترك رمز الخطأ على المكدس الاستثناءات التي وضعت رمز الخطأ هناك ؟

وغيرها من ذكره ، عليك القيام به إما:

pop %eax
/* Do something with %eax */
iret

أو إذا كنت ترغب في تجاهل رمز الخطأ:

add $4, %esp
iret

إذا كنت لا ، iret تفسير رمز الخطأ الجديد CS, و أنت من المحتمل أن تحصل على خطأ حماية عام كما ذكرت في: لماذا iret من خطأ صفحة معالج إنشاء مقاطعة 13 (خطأ حماية عام) و رمز الخطأ 0x18?

الحد الأدنى من العمل في هذه الصفحة معالج لقد خلق لتوضيح هذا.محاولة معلقا بها pop ونرى ذلك تفجير.

قارن أعلاه ، شعبة خطأ استثناء والتي لا البوب المكدس.

ملاحظة أنه إذا كنت تفعل ببساطة int $14, لا بايت إضافية يدفع:يحدث هذا فقط على الفعلية استثناء.

دليل إنتل حجم 3 نظام دليل البرمجة - 325384-056US أيلول / سبتمبر 2015 الجدول 6-1."الوضع المحمي الاستثناءات ويقطع" العمود "رمز الخطأ" يحتوي على قائمة المقاطعات التي تدفع رمز الخطأ أم لا.

38.9.2.2 "خطأ صفحة رموز الخطأ" يفسر ما الخطأ يعني.

أنيق طريقة للتعامل مع هذا هو دفع دمية رمز الخطأ 0 على المكدس على المقاطعات التي لا تفعل ذلك لجعل الامور موحدة.جيمس مالوي التعليمي يفعل ذلك بالضبط.

نواة لينكس 4.2 يبدو أن تفعل شيئا من هذا القبيل.تحت القوس/x86/دخول/entry64.S انها نماذج يقطع مع has_error_code:

trace_idtentry page_fault do_page_fault has_error_code=1

ثم يستخدم على نفس الملف:

.ifeq \has_error_code
pushq $-1 /* ORIG_RAX: no syscall to restart */
.endif

والتي لا تدفع عندما has_error_code=0.

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