Таблица 2



Таблица 2

(0) 2 int20h двоичный код команды int 20h (программы могут использовать эту команду для завершения своей работы)
(+2) 2mem_top нижняя граница доступной памяти в системе в параграфах
(+4) 1reserv1 зарезервировано
(+5) 5call_dsp команда вызова FAR CALL диспетчера MS-DOS
(+10) 4term_adr адрес завершения (Terminate Address)
(+14) 4cbrk_adr адрес обработчика Ctrl-Break
(+18) 4crit_err адрес обработчика критической ошибки
(+22) 2parn_psp сегмент PSP программы, запустившей данную программу (программы-родителя)
(+24) 20file_tab таблица открытых файлов, если здесь находятся байты 0FFH, то таблица не используется
(+44) 2env_seg сегмент блока памяти, содержащего переменные среды
(+46) 4ss_sp адрес стека SS:SP программы
(+50) 2max_open максимальное число открытых файлов
(+52) 4file_tba адрес таблицы открытых файлов
(+56) 24reserv2 зарезервировано
(+80) 3disp диспетчер функций DOS
(+83) 9reserv3 зарезервировано
(+92) 16fcb1 форматируется как стандартный FCB, если первый аргумент командной строки содержит правильное имя файла
(+108) 20fcb2 заполняется для второго аргумента командной строки аналогично fcb1
(+128) 1p_size число значащих символов в неформатированной области параметров, либо буфер обмена с диском DTA, назначенный по умолчанию
(+129) 127 parm неформатированная область параметров, заполняется при запуске программы из командной строки
#pragma pack(1) typedef struct _PSP_ { unsigned char int20h[2]; unsigned mem_top; unsigned char reserv1; unsigned char call_dsp[5]; void far *term_adr; void far *cbrk_adr; void far *crit_err; unsigned parn_psp; unsigned char file_tab[20]; unsigned env_seg; void far *ss_sp; unsigned max_open; void far *file_tba; unsigned char reserv2[24]; unsigned char disp[3]; unsigned char reserv3[9]; unsigned char fcb1[16]; unsigned char fcb2[20]; unsigned char p_size; unsigned char parm[127]; } PSP; #pragma pack()

Программы могут получить из PSP такую информацию, как параметры командной строки при запуске, размер доступной памяти, найти сегмент области переменных среды и т.д.

Как программе узнать адрес своего PSP? Очень просто сделать это для программ, написанных на языке ассемблера: при запуске программы этот адрес передается ей через регистры DS и ES. То есть этот адрес равен DS:0000 или ES:0000 (для COM-программ на PSP указывают также регистры CS и SS).

Для программ, составленных на языке Си, доступна глобальная переменная _psp типа unsigned. Эта переменная содержит сегментный адрес PSP.

В качестве примера приведем текст программы на языке ассемблера, которая выводит на экран передаваемые ей через PSP параметры запуска: .MODEL tiny DOSSEG .STACK 100h .DATA parm_msg DB "Укажите параметры", 13, 10, "$" .CODE .STARTUP mov cl,ds:80h ; количество символов ; в командной строке cmp cl,0 je ask_parm ; нет параметров - просим ; задать параметры mov si,81h ; со смещением 81h ; начинается область ; параметров cld get_parm: lods BYTE PTR es:[si] ; загружаем в al ; очередной ; символ строки ; параметров mov ah,2 ; выводим его на экран mov dl,al int 21h loop get_parm jmp end_progr ask_parm: mov ah, 9h mov dx, OFFSET parm_msg int 21h end_progr: .EXIT 0 END

Приведенная ниже программа, составленная на языке Си, определяет адрес своего PSP, затем показывает содержимое некоторых полей из PSP: #include <stdio.h> #include <stdlib.h> #include <dos.h> #include "sysp.h" void main(void); void main(void) { PSP far *psp_ptr; psp_ptr = FP_MAKE(_psp,0); // Конструируем указатель // на PSP printf("PSP расположено по адресу: %Fp\n" "Доступно памяти, байт: %ld\n" "PSP родительской программы: %Fp\n" "\n", psp_ptr, (long)(psp_ptr->mem_top)*16L, FP_MAKE(psp_ptr->parn_psp,0)); exit(0); }

Используя поле parn_psp, можно определить адрес PSP родительской программы, то есть программы, запустившей Вашу программу.

Немного о назначении полей term_adr, cbrk_adr, crit_err.

Поле term_adr содержит значение, полученное из таблицы векторов прерываний для вектора 22h. Это адрес программы, которая получает управление, когда текущая программа завершает свою работу. Это может быть, например, COMMAND.COM. Программа может создать свою собственную подпрограмму, которая будет получать управление при завершении работы основной программы. Она может записать свой собственный адрес в вектор 22h, затем запустить другую программу. В таком случае в запущенной программе это поле в ее PSP будет содержать адрес родительской программы. Когда основная программа завершает свою работу, DOS восстанавливает адрес программы завершения в векторе 22h из поля term_adr PSP.

Поле cbrk_adr содержит адрес программы обработки прерывания по нажатию Ctrl-Break из вектора 23h таблицы векторов прерываний. Так как программа может устанавливать свою собственную программу обработки прерывания по Ctrl-Break, DOS при завершении работы программы восстанавливает оригинальное значение из поля cbrk_adr.

Аналогично поле crit_err предназначено для восстановления содержимого вектора 24h - адреса обработчика критических ошибок.

Способы переназначения векторов будут приведены в разделе, посвященном прерываниям.

Конечно, программы, составленные на языке Си, не обязательно должны использовать PSP для доступа к параметрам командной строки и переменным среды. Для этого есть параметры функции main и набор функций типа getenv, putenv и т.п., предназначенных для работы со средой. Но ведь PSP содержит и другую информацию!



- Начало - - Назад - - Вперед -