0787 - MS-Dos - Od środka cz.1

Prawdopodobnie najbardziej rozpowszechnionym systemem operacyjnym w Polsce jest MS-DOS, wykorzystywany przez użytkowników kopii IBM PC XT/AT. W rozpoczętym dzisiaj cyklu publikacji o MS-DOS - adresowanym do programistów tworzących oryginalne programy i użytkowników "dopasowujących" programy gotowe - będzie mowa o interfejsie pomiędzy MS-DOS a użytkownikiem, opisane zostaną funkcje systemowe pozwalające nieco bardziej zgłębić problem i przyjrzeć się szczegółom przemilczanym przez podręczniki obsługi.

Coraz szybsze rozprzestrzenianie się komputerów osobistych rodzi problem wielkości i elastyczności związanej z nimi oferty programowej. Pośrednikiem między oprogramowaniem użytkowym a sprzętem specyficznym dla danego typu komputera jest system operacyjny. Odgrywa on także zasadniczą rolę w komunikacji człowieka z maszyną. Programy odwołujące się do tego samego systemu operacyjnego określa się jako przenośne, to znaczy takie, które mogą być wykonywane na wszystkich komputerach wyposażonych w ten sam system operacyjny.

Dla komputerów zbudowanych z wykorzystaniem mikroprocesorów 8088, 8086, 80186 i 80286 przyjęły się zasadniczo trzy typy systemów operacyjnych: CP/M-86, MS-DOS/PC-DOS oraz wywodzące się z systemu UNIX (np. Xenix). Do sukcesu rynkowego mikrokomputera IBM PC i urządzeń kompatybilnych przyczyniło się wyposażenie go w system MS-DOS/PC-DOS.

MS-DOS i PC-DOS są zasadniczo dwoma niezależnymi od siebie produktami. Choć obydwa zostały wytworzone przez tę samą firmę - Microsoft - to jednak prawa do dystrybucji systemu PC-DOS ma firma IBM. Wynikało to ze względów historycznych. Gdy w 1980r. IBM postanowił wprowadzić na rynek swój komputer osobisty, dobrym kandydatem na producenta systemu operacyjnego była firma Microsoft. Miała ona wówczas prawa do systemu 86-DOS, który zrodził się z systemu operacyjnego QDOS (ang. Quick-and-Dirty Operating System) firmy Seattle Computer Products.

Na podstawie systemu 86-DOS, którego koncepcja wywodziła się najbardziej wówczas rozpowszechnionego systemu CP/M-80 firmy Digital Research, firma Microsoft rozpoczęła pracę nad PC-DOS/MS-DOS. Krótko przed wprowadzeniem na rynek komputera IBM PC firma Microsoft przejęła wszystkie prawa do 86-DOS i nazwała produkt końcowy MS-DOS. Firma IBM zakupiła natomiast prawa do identycznego systemu, który otrzymał nazwę PC-DOS. Obie firmy niezależnie konserwują i rozwijają swoje systemy, tworząc kolejne (już trzy) ich wersje, na razie jeszcze kompatybilne ze sobą.

Nie powinno zatem nikogo dziwić, że interfejs pomiędzy oprogramowaniem użytkowym a systemem MS-DOS (wersja 1) bardzo przypomina interfejs z systemu CP/M. Wersja 2 wprowadziła m.in. hierarchiczny system plików (podobny do tego, jaki jest w systemie Xenix). Dlatego w wersji 2 MS-DOS istnieją obok siebie pary funkcji wykonujących te same zadania (np. otwarcie zbioru danych); w każdej parze jedna przypomina odpowiednią funkcję systemu CP/M, a druga - Xenix-a. Przy tym powiedziane jest, że funkcje systemu CP/M zachowane są tylko ze względu na kompatybilność z wersją 1 i nie będą w przyszłości rozwijane. Warto w tym miejscu podkreślić, że dostęp do zbiorów danych poprzez funkcje typu CP/M nie umożliwia wykorzystania hierarchicznej struktury zbiorów w wersji 2.

W odróżnieniu od CP/M, system operacyjny MS-DOS znajduje się w zasadzie zawsze w tym samym miejscu, to znaczy na początku pamięci operacyjnej. Dzięki temu można na przykład rozbudowywać pamięć, bez potrzeby przesuwania systemu. Mapę pamięci typowego systemu MS-DOS pokazano na rysunku. Oznaczenie XXXX:YYYY wzięło się z podziału pamięci procesora 8086/8088 na 64-KBajtowe segmenty. XXXX oznacza segment, YYYY zaś adres (offset) w ramach segmentu. Oba składniki są liczbami szesnastkowymi.

Adres fizyczny liczy się zgodnie z następującą formułą (H oznacza liczbę szesnastkową): ZZZZ = XXXX x 10h + YYYY. Warto pamiętać, że ten sam adres fizyczny można zapisać na wiele sposobów (gdyż poszczególne segmenty mogą na siebie zachodzić). Tak więc adres fizyczny 234H można zapisać jako 2345H:0007H, 2340H:0057H, 2000H:3457H itd.

Blok programowy w pamięci oznaczony jako BIOS (Basic Input Output System) jest pośrednikiem pomiędzy MS-DOS a sprzętem charakterystycznym dla danego komputera. Jest on zazwyczaj tworzony przez wytwórcę komputera. BIOS jest ładowany do pamięci RAM przez program ładujący (bootstrap loader), może też - jak to się dzieje np. w komputerze IBM PC - zawierać się w pamięci ROM. Właściwy MS-DOS jest następnie ładowany przez BIOS.

Jako ostatni ładowany jest COMMAND.COM, czyli procesor poleceń (CCP - Console Command Processor). Jak widać na rys.1, w pamięci znajdują się dwie części COMMAND.COM, to znaczy część rezydentna, położona za procedurami sterującymi urządzeniami oraz część nie rezydentna, znajdująca się na końcu dostępnej pamięci RAM. Część rezydentna zajmuje się głównie obsługą wszystkich przerwań oraz obsługą błędów (error handling). Część nierezydentna przetwarza informacje przekazywane za pośrednictwem klawiatury i na ich podstawie podejmuje odpowiednie akcje, np. wywołanie funkcji wewnętrznej DTR lub funkcji zewnętrznej CHKDSK (poprzez załadowanie i wykonanie CHKDSK.COM).

Jeśli część nierezydentna COMMAND.COM nie jest potrzebna, obszar pamięci zajmowany przez nią może być wykorzystany przez inne programy. Część rezydentna procesora poleceń sprawdza na żądanie, czy w pamięci znajduje się część nierezydentna, czy też musi zostać dopiero załadowana.

Bufor MS-DOS, obszar pamięci zajmowany przez procedury sterujące urządzeniami oraz część rezydentna COMMAND.COM zostały określone na rys.1 jako specyfikowane przez użytkownika, choć chodzi tu przecież o część systemu MS-DOS. Wynika to stąd, że użytkownik może mieć wpływ na zawartość tej części pamięci. Mianowicie zbiór CONFIG.SYS, analizowany w czasie procesu ładowania systemu, pozwala zmieniać wielkość obszaru bufora, dodawać dodatkowe procedury sterujące urządzeniami, a także używać innego procesora poleceń.

Wywołania systemowe

Wyróżnia się pięć grup wywołań systemowych MS-DOS (system calls);

  1. Wprowadzanie i wyprowadzanie łańcuchów znaków z/na standardowe urządzenia, np. CON (console device - klawiatura/ekran), PRN (printer - drukarka) itd.
  2. Zarządzanie i gospodarowanie plikami (file management) oraz skorowidzami (directory management).
  3. Zarządzanie programami (program management).
  4. Zarządzanie pamięcią (memory management).
  5. Różnorodne funkcję systemowe (system management), np. załączanie i wyłącznie przerwań CTRL-C, ustawianie i odczytywanie czasu systemowego itp.

Inny podział wynika z rozróżnienia funkcji systemowych na funkcje typu CPM/M i typu Xenix. Przy szczegółowym opisie poszczególnych funkcji będziemy zawsze zaznaczać, do jakiego typu należy dana funkcja. Jest to istotne choćby z tego powodu, że wywołania systemowe typu CP/M nie mogą w pełni obsługiwać hierarchicznych systemów zbiorów ze skorowidzami podrzędnymi (subdirectories). Dlatego tam, gdzie potrzebne jest pełne wykorzystanie wszystkich możliwości systemu operacyjnego lub też nie wymaga się zachowania kompatybilności z MS-DOS (wersja 1) lub z CP/M, powinno się wykorzystywać wywołania typu Xenix. Przy tym okaże się, że korzystanie z funkcji typu Xenix jest mniej skomplikowane. Programiście pracującemu dotąd pod kontrolą systemu CP/M może być łatwiej wykorzystywać funkcje typu CP/M. Powinien on jednak wziąć pod uwagę fakt, że w przyszłych wersjach systemu funkcje typu CP/M mogą nie być realizowane.

Tabela 1. Przerwania systemowe MS-DOS

Przerwanie Funkcja
20h Zakończenie wykonywanego programu
21h Wywołanie każdej z funkcji MS-DOS (function dispatcher)
22h Wektor związany z tym przerwaniem (komórki pamięci 0000:0080h ... 0000:008Bh) zawiera adres, do którego nastąpi skok po zakończeniu aktualnie wykonywanego programu
23h Wektor związany z tym przerwaniem (komórki 0000:008Ch ... 0000:008Fh) zawiera adres, do którego nastąpi skok po wciśnięciu CTRL-C
24h Wektor związany z tym przerwaniem (komórki 0000:0090h ... 0000:0093h) zawiera adres, do którego nastąpi skok po napotkaniu poważnego błędu (np. dyskietka niemożliwa do odczytania)
25h Odczyt szeregu sektorów leżących jeden za drugim (odczyt "fizyczny")
26h Zapis szeregu sektorów leżących jeden za drugim (zapis "fizyczny")
27h Zakończenie aktualnie wykonywanego programu, przy czym program pozostaje w pamięci (np. spooler) i może być za pomocą odpowiednich środków powtórnie uruchomiony
28h ... 3Fh Przerwanie zarezerwowane

Tabela 2. Wywołania systemowe (function calls) dostępne przez INT 21h

Funkcja Opis
00h Zakończenie aktualnie wykonywanego programu
01h Odczytanie znaku z klawiatury z wysłaniem echa na ekran (urządzenie: CON)
02h Wysłanie znaku na ekran (urządzenie: CON)
03h Odczytanie znaku z AUX (interfejs szeregowy)
04h Wysłanie znaku na AUX
05h Wysłanie znaku na drukarkę (PRN)
06h Odczytanie/wysłanie znaku z/na CON (klawiatura/ekran)
07h Odczytanie znaku z klawiatury (CON) bez wysłania echa i bez rozpoznawania CTRL-C
08h Tak jak funkcja 07h, lecz z reakcją na CTRL-C
09h Wysłanie łańcucha znaków zakończonego $
0Ah Wprowadzenie łańcucha znaków (wejście buforowe)
0Bh Sprawdzenie, czy z klawiatury podano jakiś znak
0Ch Usunięcie wszystkich znaków z bufora klawiatury, zakończone wywołaniem jednej z funkcji 01h, 06h, 07h, 08h lub 0Ah
0Dh Zapisywanie wszystkich buforów dyskowych (które zostały zmienione) z powrotem na dyskietkę (reset disk flush buffers)
0Eh Wybranie jednego z kilku napędów dysków (select disk)
0Fh Otwarcie pliku (open file)
10h Zamknięcie pliku (close file)
11h Poszukiwanie pierwszej nazwy pliku, która pasuje do podanego wzorca (np. EXE) - (search first entry)
12h Poszukiwanie kolejnej nazwy pliku pasującej do podanego wzorca, przy czym poszukiwanie rozpoczyna się za nazwą znalezioną ostatnio za pomocą funkcji 11h lub 12h (search next entry)
13h Usunięcie zbioru (delete file)
14h Odczytanie następnej porcji danych z pliku sekwencyjnego (sequential read)
15h Zapisanie następnej porcji danych do pliku sekwencyjnego (sequential write)
16h Utworzenie nowego pliku (create new file)
17h Zmienienie nazwy pliku (rename file)
18h Funkcja zarezerwowana
19h Sprawdzenie, który z napędów był ostatnio wybrany za pomocą funkcji 0Eh (current disk)
1Ah Zmienienie adresu bufora służącego do wprowadzenia/wyprowadzenia na/z dysku (set DTA - disc transfer address)
1Bh Określenie adresu bajtów identyfikujących listę zawartości wybranego wcześniej dysku (FAT - file allocation table), jak również uzyskanie informacji o pojemności i organizacji wybranego napędu; funkcja ta przez Microsoft określona jako zarezerwowana - niemniej istnieje.
1Ch Tak jak funkcja 1Bh z tą różnicą, że użytkownik może wybrać interesujący go dysk (ta funkcja również oficjalnie nie istnieje)
1Eh ... 20h Funkcje zarezerwowane
21h Odczytanie rekordu z pliku o dostępie swobodnym (random read single record)
22h Zapisanie rekordu do pliku o dostępie swobodnym (random write single record)
23h Określenie wielkości pliku (get file size)
24h Określenie numeru rekordu przy dostępie swobodnym (set random record number) dla zwrotu parametru przy dostępie sekwencyjnym w FCB (File Control Block)
25h Ustawienie wektora przerwań (set interrupt vector)
26h Utworzenie nowego PSP (create new program segment prefix - PSP)
27h Odczytanie wielu rekordów z pliku o dostępie swobodnym (random block read)
28h Zapisanie wielu rekordów do pliku o dostępie swobodnym (random block write)
29h Poszukiwanie łańcucha znaków w specyfikacji pliku i wydzielenie go (parse file name)
2Ah Odczytanie daty z zegara systemowego (get date from time-of-year clock)
2Bh Ustawienie daty na zegarze systemowym (set date)
2Ch Odczytanie czasu z zegara systemowego (get time)
2Dh Ustawienie czasu na zegarze systemowym (set time)
2Eh Zmienienie wskaźnika weryfikacji (set/reset verify state) służącego do weryfikacji po zapisie na nośnik danych
2Fh Pobranie adresu bufora dla operacji dyskowych (get disk transfer adres/DTA)
30h Pobranie numeru wersji MS-DOS (get MS-DOS version number)
31h Zakończenie aktualnie wykonywanego programu, bez usuwania go z pamięci (terminate process and remain resident)
32h Funkcja zarezerwowana
33h Pobranie, ustalenie i zapisanie sposobu reakcji na CTRL-C (request/set/reset CTRL-C cheeck)
34h Funkcja zarezerwowana
35h Pobranie wektora przerwań (return interrupt vector)
36h Pobranie wielkości i położenia wolnych obszarów na dysku (get disk free space)
37h Funkcja zarezerwowana
38h Pobranie informacji o sposobie przedstawiania daty, czasu itd. zależnym od kraju (return country-dependent information)
39h Utworzenie nowego katalogu (create directory, MKDIR)
3Ah Usunięcie (pustego) katalogu (remove directory, RMDIR)
3Bh Zmienienie katalogu (change directory, CHDIR)
3Ch Utworzenie nowego pliku (create a file; create handle)
3Dh Otwarcie nowego pliku (open file; open handle)
3Eh Zamknięcie pliku (close file; close handle)
3Fh Odczytanie pliku/urządzenia (read file or device)
40h Zapisanie do pliku lub na urządzenie (write file or device)
41h Usunięcie pliku (delete/unlink file)
42h Przesunięcie wskaźnika odczytu/zapisu w pliku (move file read/write pointer)
43h Pobranie/zmienienie atrybutów pliku, np. hidden (get/change file mode)
44h Pobranie/zmodyfikowanie informacji o komunikacji z urządzeniem (device I/O control IOCTL)
45h Utworzenie drugiego kanału logicznego (file handle) dla dostępu do już otwartego pliku (create duplicate handle)
46h Przełączenie kanału logicznego (file handle) pliku 1 na plik 2, przy czym plik 1 zostaje zamknięty (force duplicate file handle, I/O redirection)
47h Ustalenie, który katalog został wybrany dla określonego napędu za pomocą CHDIR (funkcja 3Bh) (get current directory for specified drive)
48h Zarezerwowanie pamięci systemowej (RAM, allocate memory, lock memory)
49h Zwolnienie zarezerwowanej pamięci systemowej (free allocated memory, unlock memory)
4Ah Zmienienie wielkości zarezerwowanego bloku pamięci (modify allocated memory block)
4Bh Załadowanie programu (np. procedury sterującej lub nakładki); załadowanie i wykonanie programu (load or execute a program)
4Ch Zakończenie programu z wyprowadzeniem komunikatu (terminate using return code); otwarte pliki zostają zamknięte
4Dh Pobranie komunikatu (z numerem błędu), przekazanego z wywołanego programu do wołającego procesu (get return function code)
4Eh Poszukiwanie pierwszego pliku, którego nazwa pasuje do podanego wzorca (np. *EXE) (search first entry)
4Fh Poszukiwanie kolejnego pliku pasującego do podanego wzorca, przy czym poszukiwania rozpoczynają się od pliku ostatnio znalezionego (search next entry)
50h ... 53h Funkcje zarezerwowane
54h Zapytanie, czy po zapisie będzie wykonane sprawdzenie jego poprawności (get verify state); przeprowadzenie lub brak takiej weryfikacji można zmienić za pomocą funkcji 2Eh
55h Funkcja zarezerwowana
56h Zmienienie nazwy pliku (rename file)
57h Pobranie (zmodyfikowanie daty ostatniego zapisu do pliku (get/set date and time of last acces modyfing file)

Opr. Zbigniew Pojmański wg. mc 10/85
Mikroklan - Lipiec 1987r.