; блоки управления памятью MS-DOS. Формат отображения показан
; выше.
;
ShowMCBInfo PROC NEAR
mov ch,04 ; отображение числовых данных
mov ax,es ; адрес MCB
call bin2hex
@DisStr $Space
mov ax,es:[di].SizeMCB ; связанный блок
call bin2hex
@DisStr $Space
mov ax,es:[di].OwnerMCB ; владелец
push ax ; сохранение владельца
call bin2hex
@DisStr $Space
pop ax
cmp ax,FreeMCB ; блок освобожден?
je is_free ; да, выполнять имя не надо
call ShowMCBOwner ; нет, отображение владельца
jmp Info_Exit
;
- 3-10 -
is_free:
@DisStr $Free ; отметить блок как свободный
Info_exit:
@DisStr $Crlf
ret
ShowMCBInfo ENDP
;
; **** ShowMCBOwner ********************************************
; ShowMCBOwner извлекает и отображает владельца MCB DOS из
; соответствующей строки среды. ES:DI указывает на допустимый
; MCB с ненулевым полем владельца.
;
ShowMCBOwner PROC NEAR
push es ; сохранение адреса MCB
push di ; сохранение для приборки
;
; Получение PID (адреса PSP), который владеет этим блоком памяти
mov ax,es:[di].OwnerMCB ; адрес PSP владельца
mov es,ax
cmp es:[di].PSPExitInt,PSPSignature ; допустимый PSP?
je Owner_PID ; да, владелец имеет PID
;
; Без PSP владелец должен быть ядром DOS
Owner_DOS:
@DisStr $DOS ; владелец MS-DOS
jmp Owner_Exit ; все выполнено
;
; Извлечение сегмента среды процесса из PSP
Owner_PID:
mov ax,es:[di].PSPEnvironment ; да, получ. адр.среды
push ax ; сохранение сегмента среды
;
; Получение размера сегмента среды
dec ax ; MCB среды
mov es,ax
mov cx,es:[di].SizeMCB ; получение размера среды
shl cx,1 ; преобразование параграфов
shl cx,1 ; в байты
shl cx,1
shl cx,1
;
; Продолжение поиска имени процесса по ES:DI, длине CX
; Каждая переменная среды завершается нулевым байтом.
; Список переменных завершается другим нулевым байтом
cld ; поиск вперед
pop es ; восстановление среды
xor al,al ; поиск значения
search:
repne scasb ; поиск для ASCIIZ
jne Owner_DOS ; останов, если выход за границу
scasb ; конец списка строк
jne search ; продолжить, если больше
;
; Проверка наличия "Сигнатуры", продолжающей (возможные) имена
mov si,di ; передача в SI
push ds ; сохранение сегмента строк
push es ; передача ES в DS
pop ds
- 3-11 -
lodsw ; чтение предшествующего слова
cmp al,NameSig ; проверка действительного имени
je show_name ; имя допустимое
;
; Без действительного имени владелец должен иметь имя SHELL
pop ds
@DisStr $Shell ; владелец имеет имя shell
jmp Owner_Exit
; ES:DI указывает на допустимое (0 завершенное) имя процесса
show_name:
lodsb ; чтение символа,
cmp al,0 ; одновременно проверка
je Owner_POP ; окончания, и
@DisStr al ; отображение
loop show_name
Owner_Pop:
pop ds
Owner_Exit:
pop di
pop es
ret
ShowMCBOwner ENDP
; ***** КОНЕЦ ПРОГРАММЫ : КОНЕЦ ФАЙЛА **************************
;
_TEXT ENDS
END main
; PSP.INC
;***************************************************************
; ФАЙЛ ВКЛЮЧЕНИЯ ОПИСАНИЙ PSP
;***************************************************************
;
PSPSignature EQU 020cdh ; слово, начинающее все PSP
;
ProgramSegmentPrefix STRUC
PSPExitInt dw ? ; прерывание выход int 20h
PSPMemTot dw ? ; вершина памяти
PSPResvr1 db ?
PSPDOSCall db 5 dup (?) ; вызов MS-DOS
PSPTerminate db ? ; адрес завершения
PSPControlC dd ? ; адрес control-C
PSPCritical dd ? ; адрес критической ошибки
PSPParent dw ? ; владелец PSP
PSPHandleTable db 20 dup (?);таблица описателей по умолчанию
PSPEnvironment dw ? ; адрес среды
PSPStack dd ? ; начальные значения стека
PSPHandleSize dw ? ; размер таблицы описателей
PSPHandlePntr dd ? ; адрес таблицы описателей
PSPResvr2 db 24 dup (?)
PSPDOSInt db 3 dup (?) ; прерывание 21h или возврат
PSPResvr3 db 9 dup (?)
PSPFCB1 db 16 dup (?) ; блок управления файлом
PSPFCB2 db 16 dup (?) ; блок управления файлом
PSPResvr4 db 4 dup (?)
PSPCommandLen db 1 ; длина командной строки
PSPCommandBuf db 127 dup (?) ; текст командной строки
ProgramSegmentPrefix ENDS
________________________________________________________________
- 3-12 -
Блок операционной среды программы
При загрузке программы в память MS-DOS всегда присоединяет в
начало программы блок операционной среды (далее просто "среда"),
запоминая в нем владельца блока памяти. На Рис.3-4 он показан как
первый небольшой блок, который соотносится с каждой программой.
Блок среды программы содержит собственную копию операционной сре-
ды MS-DOS. Среда MS-DOS представляет собой область, в которой
запоминаются PATH (путь), COMSPEC (спецификация файла
COMMAND.COM) и PROMPT (приглашения) вместе с любыми переменными,
назначаемыми по команде SET (установить). Общей формой переменной
среды является: NAME = строка . Формат блока среды приведен в
примере, показанном на Рис.3-5.
Из Рис.3-5 можно видеть, что каждый элемент в блоке среды
представляет собой строку в коде ASCII (American Standard Code
for Information Interchange - Американский стандартный код для
обмена информацией), завершаемую нулевым байтом. (Этот стандарт
фирмой "Майкрософт" назван ASCIIZ). Весь список элементов закан-
чивается еще одним нулевым байтом, показанным на Рис.3-5 в ка-
честве седьмого элемента. Элементы, предшествующие этому маркеру
"конец списка", отображаются всякий раз при использовании команды
SET. А что из себя представляют два элемента, следующие после
маркера "конец списка"?
Недокументируемая возможность MS-DOS версии 3 и последующих
версий состоит в том, что всякий раз при запуске процесса с по-
мощью COMMAND.COM либо непосредственно, либо в ответ на функцию
EXEC (выполнить), имя процесса помещается в блок среды процесса.
На Рис.3-5 последние два элемента перед частью "не используемая"
являются этим недокументируемым именем процесса. Имени процесса
предшествует слово 0001h. Имя содержит собственное имя и путь
процесса и запоминается в формате ASCIIZ. Из Рис.3-5 можно уви-
деть, что этот блок среды относится к процессу SHOWMEM.
Одним из элементов, не представленных на Рис.3-5, является
общий размер блока среды. В отличие от основной среды MS-DOS, чей
размер может управляться с помощью параметра, устанавливаемого в
файле CONFIG.SYS, размер блока среды процесса определяется во
время загрузки программы путем помещения в него только текущей
части среды.
Сравните в примере отображения SHOWMEM на Рис.3-4 800-байтный
размер среды DOS (второй элемент с именем "SHELL") со средами
RETRIEVE и SHOWMEM в 64 и 272 байта, соответственно. Несмотря на
то, что DOS должна резервировать 800 байт, при загрузке RETRIEVE
впереди файла AUTOEXEC.BAT среда содержит меньше, чем 64 байта.
После завершения файлом AUTOEXEC.BAT установок PATH и PROMPT и из-
менения других переменных, среда должна увеличиться приблизитель-
но до 200 байт.
Имеются две причины получения собственного блока среды каждым
процессом при его создании. Первая - это уменьшение вероятности
того, что процесс будет испорчен средой его владельца - критичес-
кое требование, если владелец процесса - файл COMMAND.COM. Вторая
связана с тем, что процесс-владелец должен управлять средой, пе-
редаваемой порождаемому процессу, что, в свою очередь, позволяет
процессу-владельцу управлять поведением порожденного процесса. К
этой теме мы вернемся снова, когда будем рассматривать загрузку и
выполнение программы. Мы также вернемся к нерешенному вопросу
большого размера блока памяти SHOWMEM. Не забудьте эту проблему.
- 3-13 -
.------------------------------.
| COMSPEC = C:\COMMAND.COM\ | 0 |
|----------------------------------------------.
| INCLUDE = C:\msc\include;c:\masm\include | 0 |
|-----------------------------------------------
| LIB = c:\msc\lib | 0 |
|-----------------------
| ECHO = OFF | 0 |
|-------------------.
| PROMPT = $p$g | 0 |
|-------------------------------------------------------------.
|PATH = C:\DOS;C:\BIN;C:\BAT;C:\UTILS;C:\MASM;C:\WIN;C:\WS| 0 |
|--------------------------------------------------------------
| 0 |
|-------.
| 0001h |
|-----------------------------------.
| C:\GUIDE\EXAMPLES|SHOWMEM.EXE | 0 |
|------------------------------------
| Не используемая |
| |
|/\/\/\/\/\/\/\/\/\|
Рис.3-5. Блок среды
когда мы вернемся к ней после накопления основных сведений по
рассматриваемым вопросам.
Процессы MS-DOS
Мы начали эту главу с описания того, как все пространство па-
мяти системы MS-DOS форматируется на разделы для MS-DOS, BIOS и
системных функций аппаратных средств. Затем мы видели, как раз-