Prefiks segmentu programu — Program Segment Prefix

Segment Program Prefiks (PSP) to struktura danych używana w DOS systemów do przechowywania stanu w programie . Przypomina Zero Page w systemie operacyjnym CP/M . PSP ma następującą strukturę:

Obrazy offsetowe Rozmiar Zawartość
00h-01h 2 bajty (kod) Wyjście podobne do CP/M-80 (zawsze zawiera INT 20h )
02h-03h słowo (2 bajty) Segment pierwszego bajtu poza pamięcią przydzieloną do programu
04h bajt Skryty
05h-09h 5 bajtów (kod) Wejście dalekiego zasięgu podobne do CP/M-80 w systemie DOS i rozmiar segmentu programu
0Ah-0Dh dword (4 bajty) Adres zakończenia poprzedniego programu (stary INT 22h )
0Eh-11h dword Adres przerwy poprzedniego programu (stary INT 23h )
12h-15h dword Adres błędu krytycznego poprzedniego programu (stary INT 24h )
16h-17h słowo Segment PSP rodzica (zwykle COMMAND.COM - wewnętrzny)
18h-2Bh 20 bajtów Tabela plików zadań (JFT) (wewnętrzna)
2Ch-2Dh słowo Segment środowiska
2Eh-31h dword SS:SP przy wejściu do ostatniego połączenia INT 21h (wewnętrzne)
32h-33h słowo Rozmiar JFT (wewnętrzny)
34h-37h dword Wskaźnik do JFT (wewnętrzny)
38h-3Bh dword Wskaźnik do poprzedniego PSP (używany tylko przez SHARE w DOS 3.3 i nowszych)
3Ch-3Fh 4 bajty Skryty
40h-41h słowo Wersja DOS do zwrócenia (DOS 4 i nowsze, zmieniane przez SETVER w DOS 5 i nowszych)
42h-4Fh 14 bajtów Skryty
50h-52h 3 bajty (kod) Uniksopodobne wejście dalekiego wywołania do DOS (zawsze zawiera INT 21h + RETF)
53h-54h 2 bajty Skryty
55h-5Bh 7 bajtów Zarezerwowany (może być użyty do przekształcenia pierwszego FCB w rozszerzony FCB)
5Ch-6Bh 16 bajtów Nieotwarty standardowy FCB 1
6Ch-7Fh 20 bajtów Nieotwarty standardowy FCB 2 (zastąpiony, jeśli FCB 1 jest otwarty)
80h 1 bajt Liczba bajtów w wierszu poleceń
81h-FFh 127 bajtów Koniec wiersza poleceń (zakończony 0Dh )

PSP jest najczęściej używany do pobierania argumentów wiersza poleceń programu DOS; na przykład polecenie "FOO.EXE /A /F" wykonuje FOO.EXE z argumentami '/A' i '/F'.

Jeśli wpis PSP dla długości wiersza poleceń jest niezerowy, a wskaźnikiem do segmentu środowiska nie jest ani 0000h ani FFFFh, programy powinny najpierw spróbować pobrać wiersz poleceń ze zmiennej środowiskowej %CMDLINE% przed wyodrębnieniem go z PSP. W ten sposób można przekazać do aplikacji wiersze poleceń dłuższe niż 126 znaków.

Adres segmentu PSP jest przekazywany w rejestrze DS podczas wykonywania programu. Można go również określić później, używając funkcji Int 21h 51h lub Int 21h funkcji 62h. Każda funkcja zwróci adres PSP w rejestrze BX.

Alternatywnie, w programach .COM załadowanych do offset 100h, można adresować PSP bezpośrednio, używając offsetów wymienionych powyżej. Przesunięcie 000hwskazuje na początek PSP, 0FFhwskazuje na koniec itp.

Na przykład poniższy kod wyświetla argumenty wiersza poleceń:

org   100h      ; .COM - not using ds

; INT 21h subfunction 9 requires '$' to terminate string
xor   bx,bx
mov   bl,[80h]
cmp   bl,7Eh
 ja   exit      ; preventing overflow

mov   byte [bx+81h],'$'

; print the string
mov   ah,9
mov   dx,81h
int   21h

exit:
mov   ax,4C00h  ; subfunction 4C
int   21h

W DOS 1.x konieczne było, aby rejestr CS (Code Segment) zawierał ten sam segment co PSP przy zakończeniu programu, dlatego standardowa praktyka programowania polegała na zapisywaniu rejestru DS na stosie podczas uruchamiania programu (ponieważ rejestr DS jest załadowany segmentem PSP) i kończenie programu instrukcją RETF, która usunęłaby zapisaną wartość segmentu ze stosu i przeskoczyła do adresu 0 PSP, który zawierał instrukcję INT 20h.

; save
push  ds
xor   ax,ax
push  ax

; move to the default data group (@data)
mov   ax,@data
mov   ds,ax

; print message in mess1 (21h subfunction 9)
mov   dx,mess1
mov   ah,9
int   21h

retf

Jeśli plik wykonywalny był plikiem .COM, ta procedura była zbędna i program mógł zostać zakończony jedynie bezpośrednią instrukcją INT 20h lub wywołaniem funkcji INT 21h 0. Jednak programista nadal musiał upewnić się, że rejestr CS zawiera adres segmentu PSP w momencie zakończenia programu. Zatem,

jmp   start

mess1 db 'Hello world!$'

start:
mov   dx,mess1
mov   ah,9
int   21h

int   20h

W DOS 2.x i wyższych, zakończenie programu zostało wykonane zamiast tego za pomocą funkcji INT 21h 4Ch, która nie wymagała, aby rejestr CS zawierał wartość segmentu PSP.

Zobacz też

Bibliografia

Dalsza lektura

Zewnętrzne linki