دوشنبه, 10 ارديبهشت 1403

 



موضوع: وقفه ها

وقفه ها 9 سال 4 ماه ago #107886

هر رويدادی که باعث شود CPU اجرای عادی يک برنامه را قطع کند وقفه ناميده می شود. يک برنامه نويس اسمبلی با صدور وقفه های نرم افزاری می تواند به طور موثری با دستگاه های جانبی ارتباط برقرار کند.

انواع وقفه
INT
جدول بردار وقفه
چند نمونه وقفه متعارف

گاهی اوقات جريان عادی اجرای يک برنامه برای پردازش رويدادی که نياز به پاسخ سريع دارد متوقف می شود. سخت افزار کامپيوتر برای مديريت اين رويدادها مکانيسمی به نام وقفه (interrupt) را دارد.

مثال. وقتی mouse حرکت می کند، سخت افزار mouse برنامه جاری را متوقف می کند تا حرکت mouse گرفته شود( برای حرکت مکان نمای mouse روی صفحه نمايش).

وقتی CPU يک سيگنال وقفه را تشخيص می دهد، فعاليت جاری خود را متوقف می کند و روتين خاصی را فراخوانی می کند که روتين وقفه (interrupt handler) نام دارد. اين روتين علت وقوع وقفه را تشخيص می دهد و عکس العمل مناسب را انجام می دهد.

بيشتر روتين های وقفه بعد از پايان يافتن کنترل اجرا را به برنامه متوقف شده بازمی گردانند. آنها کليه مقادير ثبات ها را به وضعيت قبل از توليد وقفه بر می گردانند. بنابراين برنامه متوقف شده به گونه ای به اجرا ادامه می دهد که هيچ اتفاقی نيافتاده است به جز اين که سيکل های CPU را از دست می دهند.

وقتی دو يا چند وقفه همزمان با هم اتفاق می افتند، CPU از سيستم الويت استفاده می کند و می تواند در طی اجرای بخش بحرانی يک برنامه وقفه ها را غيرفعال کند. وقتی دارد يک روتين وقفه را اجرا می کند کليه وقفه های با الويت کمتر يا، تا زمان خاتمه اجرای روتين، غير فعال هستند.
انواع وقفه

256 سطح الويت توسط پردازنده های 80x86 پشتيبانی می شود که می توان آنها را به سه گروه کلی تقسيم کرد:

• وقفه های داخلی سخت افزاری
• وقفه های خارجی سخت افزاری
• وقفه های نرم افزاری

وقفه های داخلی سخت افزاری

وقفه های داخلی سخت افزاری (internal hardware-interrupts) بدليل رخ دادن وضعيت معينی که درحين اجرای يک برنامه پيش آمده توليد می شوند(مانند تقسيم بر صفر).

وقفه هايی که در اثر خطا بوجود می آيد تله (trap) هم ناميده می شود. تله باعث سقط برنامه می شوند.

اين وقفه ها توسط سخت افزار اداره می شوند و امکان تغيير آنها وجود ندارد. اما با وجوديکه نمی توان آنها را مستقيما مديريت کرد، اين امکان وجود دارد که از اثر آن روی کامپيوتر به نحو مفيدی استفاده شود.

مثال. سخت افزار وقفه شمارنده ساعت کامپيوتر را چندبار در ثانيه فراخوانی می کند تا زمان را نگه دارد. می توان برنامه ای نوشت که مقدار شمارنده ساعت را خوانده آنرا به شکل قابل درک کاربر به صورت ساعت و دقيقه تبديل کند.
وقفه های خارجی سخت افزاری

وقفه های خارجی سخت افزاری (external hardware-interrupts) خارج از CPU و توسط دستگاه های جانبی ، مانند صفحه کليد، چاپگر، کارت های ارتباطی و يا کمک پردازنده توليد می شوند.

دستگاه های جانبی با ارسال وقفه به CPU خواستار قطع اجرای برنامه فعلی شده و CPU را متوجه خود می کنند. آنها به پايه (maskable interrupts) INTR يا (non maskable interrupts) NMI پردازنده متصل هستند.

وقفه های دستگاه ها می توانند از طريق مداری به نام PIC 8259A، که کارش منحصرا سروکار داشتن با اين نوع وقفه هاست، به پردازنده ارسال شوند. مدار (programmable interrupt controller) PIC که توسط CPU کنترل می شود سيگنال هايش را روی پايه INTR قرار می دهد و امکان فعال و غيرفعال کردن وقفه ها و تغيير سطح الويت را تحت نظارت يک برنامه می دهد.

دستورات STI و CLI می توانند برای فعال و غيرفعال کردن وقفه هایی که روی پايه INTR ارسال می شوند بکار روند که البته روی وقفه های NMI تاثيری ندارد.
وقفه های نرم افزاری

وقفه های نرم افزاری (software interruptions) در نتيجه دستورالعمل int در يک برنامه درحال اجرا توليد می شوند.

برنامه نويس می تواند با دادن دستور int يک وقفه نرم افزاری توليد کند. بدين طريق بلافاصله اجرای برنامه فعلی را متوقف می کند و CPU را به روتين وقفه هدايت می کند. برنامه نويس از طريق وقفه ها می تواند در برنامه با وسايل جانبی ارتباط برقرار کند. استفاده از وقفه ها باعث کوتاهتر شدن کد برنامه و درک آسانتر و اجرای بهترآن می شود.

روتين های وقفه نرم افزاری بخشی از سيستم عامل هستند. از اينرو وقفه های نرم افزاری را می توان به دو گروه تقسيم کرد؛ وقفه های سيستم عامل DOS و وقفه های BIOS. وقفه های DOS آسانتر استفاده می شوند اما از وقفه های BIOS که قسمتی از سخت افزار هستند کندتر هستند.

DOS اين نوع وقفه ها را برای اجرای (application programming interface) API خودش استفاده می کند. بيشتر سيستم عامل های جديد مانند Windows و Unix واسطه C-based را استفاده می کنند.
INT

دستورالعمل (interrupt) int يک روتين وقفه را فراخوانی می کند. فرم کلی آن به صورت زير است:

int n

n شماره وقفه موردنظر و مقداری بين 0 تا 255 است که اجازه فراخوانی 256 روتين مختلف وقفه را می دهد.

دستورالعمل int يک فراخوانی سيستمی را می سازد و شکل خاصی از دستورالعمل فراخوانی يک زيربرنامه (دستورالعمل call) است.

مشکل دستورالعمل int اين است که تنها 256 روتين وقفه را می تواند پشتيبانی کند. درحاليکه DOS به تنهايی دارای بيش از 100 سرويس مختلف وقفه و BIOS بيش از هزاران سرويس وقفه است. که اين تعداد بيش از کليه وقفه هايی است که توسط اينتل رزرو شده است. برای حل اين مشکل از يک شماره وقفه برای هر دسته از سرويس های وقفه و يک شماره تابع برای تعيين سرويس موردنظر استفاه می شود. شماره تابع توسط يکی از ثبات ها (اکثرا AH) هنگام فراخوانی وقفه ارسال به روتين وقفه می شود.

مثال. سيستم عامل DOS شماره وقفه 21h را بکار می گيرد. برای انتخاب يک تابع خاص، قبل از فراخوانی وقفه، کد تابع در ثبات AH قرار می گيرد. برای نمونه تابع 4Ch اين وقفه برای خاتمه برنامه و برگشت به محيط DOS فراخوانی می شود.

mov AH, 4Ch
int 21h
جدول بردار وقفه

هر سطح وقفه يک محل رزرو شده در حافظه دارد که بردار وقفه (interrupt vector) ناميده می شود. همه بردارهای وقفه در جدولی به نام جدول بردار وقفه (interrupt vector table) نگهداری می شوند. اين جدول از ابتدای حافظه اصلی يعنی آدرس 0000:0000 ذخيره شده است.

هر بردار وقفه 4 بايت طول دارد. دوبايت بالای آن آفست و دو بايت پايين آن سگمنت روتين وقفه را دربر می گيرند. چون 256 روتين های وقفه وجود دارد بنابراين اندازه جدول بردار وقفه 256×4=1024=1KB است.

شماره وقفه به عنوان انديسی برای جدول بردار وقفه استفاده می شود. آفست روتين وقفه شماره n در آدرس n×4 و آدرس سگمنت روتين وقفه شماره n در آدرس n×4+2 جدول قرار دارد.

يک ويژگی خوب اين سيستم اين است که می توان بردارها را برای اشاره به روتين ديگری تغيير داد. که اين همان کاری است که برنامه های TSR (Terminate and Stay Resident) انجام می دهند.

در برنامه هميشه توسط شماره وقفه به يک روتين وقفه مراجعه می شود بنابراين برنامه نيازی به دانستن آدرس واقعی در حافظه ندارد و آدرس روتين وقفه هنگام اجرا توسط CPU تعيين می شود.

مثال. آدرس های آفست و سگمنت روتين وقفه شماره 5 برابر با 5×4=0014h و 5×4+2=0016h می باشد.
چند نمونه وقفه متعارف
وقفه 21h

تابع 01h. يک کليد را از صفحه کليد می خواند.
کد کليد خوانده شده در ثبات AL برگردانده می شود.

mov AH, 0lh
int 21h
mov AL, character

تابع 02h. يک کاراکتر را روی صفحه نمايش نشان می دهد.
کد کاراکتر در ثبات DL بايد قرار داده شود.

mov AH, 02h
mov DL,character
int 21h

تابع 09h. يک رشته کاراکتری را روی صفحه نمايش نشان می دهد.
آدرس شروع رشته بايد در ثبات های DS:DX قرار بگيرد. انتهای رشته توسط کاراکتر ($) بايد تعيين شده باشد.

mov AH,09h
lea DX, string
int 21h
وقفه 10h

تابع 02h. مکان نما را روی صفحه نمايش به سطر و ستون خاصی منتقل می کند.

شماره صفحه در BH، شماره سطر در DH و شماره ستون در DL بايد قرار بگيرد. مختصات صفحه از نقطه 0 و 0 از گوشه بالای چپ صفحه نمايش شروع می شود.

mov AH, 02h
mov BH, page
mov DH, row
mov DL, column
int 10h

تابع 09h. يک کاراکتر را با رنگ معين چندبار نمايش می دهد.
کد کاراکتر در AL، شماره صفحه در BH، خاصيت رنگ کاراکتر در BL و تعداد تکرار کاراکتر در CX بايد قرار بگيرد.

mov AH, 09h
mov AL, character
mov BH, page
mov BL, attribute
mov CX, number
int 10h
آخرين ويرايش: 9 سال 4 ماه ago توسط هانیه سلیمانی.
مدير دسترسي عمومي براي نوشتن را غيرفعال كرده.
مدیران انجمن: هانیه سلیمانی