Vyšlo v týdeníku Computerworld č. 18/93 v roce 1993
Vytištěno z adresy: http://www.earchiv.cz/a93/a318c120.php3

Software interrupt

Mechanismus přerušení je v počítačích využíván k více různým účelům - o některých jsme se již zmínili ve dvou posledních příspěvcích této rubriky, kdy jsme se zabývali podstatou vnitřních a vnějších přerušení. V obou těchto případech přitom šlo o taková přerušení, která byla spíše "vedlejším efektem" jiných činností. Jestliže například určité vnější přerušení signalizuje ukončení nějaké vstupně/výstupní operace, pak tuto vstupně/výstupní operaci musel někdo iniciovat (tj. některý program resp. proces), a jeho cílem přitom nebylo přerušení jako takové, ale pouze zajištění určitých vstupně/výstupních akcí. Jiný příklad: jestliže právě probíhající instrukce způsobí výpadek stránky (ošetřovaný vnitřním přerušením), nedělá to proto, aby vyvolala přerušení jako takové, ale proto, aby si načetla či zapsala nějaká data do příslušné stránky.

Existuje ovšem i taková možnost, že právě probíhající program vyvolá přerušení zcela záměrně, a vlastně si tak vynutí provedení určitého obslužného programu. Jaká je ale logika takovéhoto počínání? K čemu je to dobré?

Pro odpověď si musíme nejprve uvědomit, že každý program, proces či úloha pracuje vždy v určitém prostředí - je obklopen jinými programy, procesy či úlohami (ve víceúlohovém prostředí), je spouštěn operačním systémem, který mu zprostředkovává různé služby atd. Obecně se tedy v rámci jednoho počítače vyskytuje více programových entit, které nějakým způsobem koexistují vedle sebe, a musí mít k dispozici nějaký mechanismus pro vzájemnou komunikaci. Takováto potřeba komunikace je nezbytně nutná, a to i v jednoúlohovém prostředí, kde (jediný) právě probíhající program musí mít možnost komunikovat s operačním systémem, aby si od něj mohl vyžádat jeho služby - například přidělení další volné paměti, otevření určitého souboru, čtení dat ze souboru atd. Zastavme se nyní u toho, jakým způsobem mohou být služby operačního systému programu, resp. programům zpřístupněny.

Poskytnutí určité služby ve své podstatě vždy znamená provedení určité posloupnosti strojových instrukcí. Ve víceúlohovém prostředí je možné koncipovat operační systém jako "trvale běžící" úlohu, která své služby poskytuje na základě požadavků, předávaných jinými úlohami formou zpráv (tj. jako data, která blíže určují, co a jak je na operačním způsobu požadováno). Žadatel se přitom nemusí sám starat o to, aby operačnímu systému předal řízení (a tento mohl požadované akce skutečně vykonat), neboť toto je ve víceúlohovém prostředí zajištěno automaticky. Poněkud jiná situace je ovšem v jednoúlohovém prostředí, kde se žadatel musí sám postarat o to, aby operační systém "pustil ke slovu". Zde proto bývají jednotlivé služby operačního systému koncipovány jako podprogramy (které jsou přímou součástí operačního systému), a právě probíhající program si pak provedení požadované služby zajistí tak, že příslušný podprogram sám zavolá.

Otázkou ovšem je, jak mají být uživatelským programům zpřístupněny vstupní body takovýchto podprogramů, které jsou součástí operačního systému. Tato otázka má dva aspekty: první je ten, že příslušné podprogramy mohou být v různých verzích operačního systému umístěny jinde - což ale způsobuje nesmírné komplikace aplikačním programům, které dost dobře nemohou anticipovat změny, ke kterým dojde v nových verzích operačního systému. Jednoduchým řešením je ovšem nepřímý přístup k příslušným podprogramům: na předem určeném místě - stejném pro všechny verze - budou uloženy ukazatele na tyto podprogramy (tj. adresy jejich vstupních bodů). Vlastní podprogramy pak mohou být umístěny v podstatě kdekoli, protože žadatelé o provedení příslušných služeb k nim budou přistupovat zásadně jen přes tyto ukazatele.

Druhým aspektem je možnost ochrany operačního systému před nevhodným chováním právě probíhajícího programu. Kdyby totiž tento program mohl volat kterýkoli podprogram v rámci operačního systému, mohl by velmi snadno překonat jakýkoli zabezpečovací mechanismus - pouhým voláním té části operačního systému, která jej odblokuje, resp. která provede takové akce, na které by program jinak neměl právo. Stejně tak nebezpečné může být i nechtěné "zabloudění" programu do operačního systému.

Operační systém by tedy neměl "pouštět" právě probíhající program kamkoli, ale jen na přesně definovaná místa (tj. zpřístupnit mu jen některé své podprogramy), kde pak může kontrolovat oprávněnost a korektnost vznášených požadavků. K tomu je ovšem zapotřebí vhodný mechanismus, který žadateli umožní volat jen takové programy, které mu operační systém sám nabídne.

Jedním z mechanismů, který je schopný toto zajistit, je právě mechanismus přerušení. Jak již víme, výsledným efektem přijetí žádosti o přerušení je provedení obslužného programu. Proč tedy nekoncipovat podprogramy operačního systému, poskytující jednotlivé služby, jako obslužné programy, a nabízet zajištění příslušných služeb formou přerušení?

K tomu jsou zapotřebí ještě dvě věci: aby mohly být tímto způsobem poskytovány různé služby, musí být žádosti o přerušení vhodným způsobem diversifikovány - musí existovat různé druhy, typy či třídy přerušení, a každé bude odpovídat jeden obslužný program, poskytující určitou konkrétní službu.

Dalším nezbytným předpokladem je to, aby právě probíhající program mohl zcela záměrně vyvolat přerušení určitého typu (čísla, třídy), a tím si vlastně vyžádat provedení příslušné služby operačního systému. Za tímto účelem musí být procesory vybaveny strojovými instrukcemi pro tzv. programové přerušení (software interrupt). Operandem těchto instrukcí je pak údaj, který určuje konkrétní typ (druh, třídu) přerušení, a tím zprostředkovaně i požadovanou službu.

Instrukce programového přerušení je tedy strojová instrukce, jejímž jediným efektem je záměrné vyvolání určitého přerušení. To bývá samozřejmě nemaskovatelné.

Čím se ale instrukce programového přerušení liší od běžné instrukce volání podprogramu, když ve své podstatě také pouze vyvolá provedení určitého podprogramu (obslužného programu)? Hlavní rozdíl je v tom, že jde vesměs o volání nepřímé - volající zde nemusí znát konkrétní adresu volaného podprogramu. Specifikuje pouze jeho nepřímou adresu, tedy vlastně jen místo, na kterém je uložen ukazatel na tento podprogram (což v tomto konkrétním případě určuje typem, číslem resp. třídou přerušení). Je pak na operačním systému, aby konkrétní ukazatel na toto místo uložil, a tím vlastně sám rozhodl o tom, kam volajícího "pustí".