Префикс сегмента программы (PSP) - это данные структура, используемая в системах DOS для хранения состояния программы. Он похож на нулевую страницу в операционной системе CP / M. PSP имеет следующую структуру:
Offsetimages | Size | Contents |
---|---|---|
00h-01h | 2 байта (код) | CP / M-80 -подобный выход (всегда содержит INT 20h ) |
02h-03h | word (2 байта) | Сегмент первого байта за пределами памяти, выделенной программе |
04h | байт | Зарезервировано |
05h-09h | 5 байтов (код) | CP / M-80-like запись удаленного вызова в DOS, и размер программного сегмента |
0Ah-0Dh | dword (4 байта) | Завершить адрес предыдущей программы (старый) |
0Eh-11h | dword | Адрес разрыва предыдущей программы (старая) |
12h-15h | dword | Адрес критической ошибки предыдущей программы (старая) |
16h-17h | word | Сегмент PSP родителя (обычно COMMAND.COM - внутренний) |
18h-2Bh | 20 байтов | Таблица файлов заданий (JFT) (внутренний) |
2Ch-2Dh | word | Environment сегмент |
2Eh-31h | dword | SS: SP при входе в последний INT 21h вызов (внутренний) |
32 h-33h | word | Размер JFT (внутренний) |
34h-37h | dword | Указатель на JFT (внутренний) |
38h -3Bh | dword | Указатель на предыдущий PSP (используется только SHARE в DOS 3.3 и новее) |
3Ch-3Fh | 4 байта | Зарезервировано |
40h-41h | word | Версия DOS для возврата (DOS 4 и новее, можно изменить с помощью SETVER в DOS 5 и новее) |
42h-4Fh | 14 байтов | Зарезервировано |
50h-52h | 3 байта (код) | Unix - запись удаленного вызова в DOS (всегда содержит INT 21h + RETF) |
53h-54h | 2 байта | Зарезервировано |
55h-5Bh | 7 байтов | Зарезервировано (может использоваться для преобразования первого FCB в расширенный FCB) |
5Ch-6Bh | 16 байтов | Unopened Standard FCB 1 |
6Ch-7Fh | 20 байтов | Неоткрытый стандартный FCB 2 (перезаписывается при открытии FCB 1) |
80h | 1 байт | Количество байтов в командной строке |
81h-FFh | 127 байтов | хвост командной строки (заканчивается 0Dh ) |
PSP - это большая часть десять используется для получения аргументов командной строки программы DOS; например, команда «FOO.EXE / A / F» выполняет FOO.EXE с аргументами «/ A» и «/ F».
Если запись PSP для длины командной строки не равна нулю, а указатель на сегмент среды не равен ни 0000h, ни FFFFh, программы должны сначала попытаться получить командную строку из переменной среды % CMDLINE% перед извлечением из PSP. Таким образом, можно передавать приложениям командные строки длиной более 126 символов.
Сегментный адрес PSP передается в регистр DS при выполнении программы. Это также можно определить позже, используя функцию Int 21h 51h или функцию 62h Int 21h. Любая функция вернет адрес PSP в регистре BX.
В качестве альтернативы, в программах .COM, загруженных со смещением 100h, можно напрямую обращаться к PSP, просто используя перечисленные выше смещения. Смещение 000hуказывает на начало PSP, 0FFhуказывает на конец и т. Д.
Например, следующий код отображает аргументы командной строки:
орг 100ч;.COM - без использования ds; Подфункция 9 INT 21h требует '$' для завершения строки xor bx, bx mov bl, [80h] cmp bl, 7Eh ja exit; предотвращение переполнения mov byte [bx + 81h], '$'; вывести строку mov ah, 9 mov dx, 81h int 21h exit: mov ax, 4C00h; подфункция 4C int 21h
В DOS 1.x было необходимо, чтобы регистр CS (сегмент кода) содержал тот же сегмент, что и PSP при завершении программы, поэтому стандартная практика программирования включала сохранение регистра DS в стек в программе start (так как регистр DS загружен сегментом PSP) и завершение программы инструкцией RETF, которая выталкивает сохраненное значение сегмента из стека и переходит к адресу 0 PSP, который содержит инструкцию INT 20h.
; сохранить push ds xor ax, ax push ax; перейти в группу данных по умолчанию (@data) mov ax, @ data mov ds, ax; напечатать сообщение в mess1 (21h подфункция 9) mov dx, mess1 mov ah, 9 int 21h retf
Если исполняемый файл был файлом.COM, в этой процедуре не было необходимости, и программу можно было завершить просто с помощью прямой инструкции INT 20h или иначе вызывает INT 21h функцию 0. Однако программисту все равно нужно было убедиться, что регистр CS содержал адрес сегмента PSP при завершении программы. Таким образом,
jmp start mess1 db 'Hello world! $' Start: mov dx, mess1 mov ah, 9 int 21h int 20h
В DOS 2.x и выше завершение программы выполнялось с помощью INT 21h Function 4Ch что не требует, чтобы регистр CS содержал значение сегмента PSP.