Таблица 4



Таблица 4

(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 неформатированная область параметров, заполняется при запуске программы из командной строки

Для обращения к полям PSP файл sysp.h содержит следующее определение: #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()

Приведем программу, определяющую адрес первого блока MCB: /** *.Name get_fmcb * *.Title Получить адрес первого MCB * *.Descr Функция возвращает адрес первого блока MCB * *.Params MCB far *get_fmcb(CVT far *cvt) * * cvt - адрес векторной таблицы связи * *.Return Указатель на первый блок MCB **/ #include "sysp.h" MCB far *get_fmcb(CVT far *cvt) { return((MCB far *)FP_MAKE(cvt->mcb_seg,0)); }

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

Для получения адреса следующего MCB можно использовать функцию get_nmcb: /** *.Name get_nmcb * *.Title Получить адрес следующего MCB * *.Descr Функция возвращает адрес следующего блока MCB * или 0, если это последний блок. В качестве * параметра используется указатель на предыдущий * блок MCB * *.Params MCB far *get_fmcb(MCB far *mcb) * * mcb - адрес предыдущего MCB * *.Return Указатель на следующий блок MCB или 0, если * это последний MCB **/ #include <dos.h> #include "sysp.h" MCB far *get_nmcb(MCB far *mcb) { unsigned seg, off; if(mcb->type == 'M') { seg = FP_SEG(mcb) + mcb->size + 1; off = FP_OFF(mcb); return((MCB far *) FP_MAKE(seg,off)); } else return ((MCB far *)0); }

В завершение описания блоков управления памятью приведем программу, выводящую некоторую информацию об активных MCB. Эта программа определяет адрес векторной таблицы связи, получает из этой таблицы адрес первого MCB и сканирует весь список MCB. #include <dos.h> #include <stdio.h> #include "sysp.h" void main(void); void main(void) { CVT far *cvt; MCB far *mcb; printf("\nБлоки управления памятью (MCB)" "\nCopyright (C)Frolov A., 1990\n" "\nАдрес MCB Тип Владелец Размер" "\n--------- --- -------- ------" "\n"); cvt=get_mcvt(); mcb=get_fmcb(cvt); for(;;) { if(mcb == (MCB far *)0) break; printf("%Fp %c %04X %04X\n", mcb, mcb->type, mcb->owner, mcb->size); mcb=get_nmcb(mcb); } exit(0); }



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