жит размер блока памяти, следующего за этим блоком. Этот размер
выражается в параграфах (блоки по 16 байт) и не включает размер
самого блока MCB. Оставшиеся 11 байтов MCB не определены.
Несмотря на то, что полный список блоков управления часто от-
носят к цепочке распределения памяти, блоки MCB, на самом деле,
не редактируются вместе, MCB только указывает на распределенный
блок памяти. Вернее, каждый блок MCB непосредственно следует в
памяти перед блоком, которым он управляет. Если MCB и соответс-
твующий ему блок памяти не последние в цепочке, то за ними непос-
редственно следуют другой MCB и блок памяти.
Начиная от данного MCB, адрес сегмента следующего MCB в це-
почке получается путем сложения размера (в параграфах) текущего
блока с текущим адресом сегмента MCB, плюс 1. При этом способе
может быть просмотрена вся цепочка MCB, но только в прямом нап-
равлении. Начиная от данного MCB, можно определить адрес предыду-
щего MCB. Как затем можно узнать, какие блоки находятся в памяти?
Функция MS-DOS с номером 52h (прерывание int 21h) является
недокументируемой функцией, которая возвращает указатель на спи-
сок внутренних значений MS-DOS. Указатель возвращается в паре
ES:BX. Как раз перед этим списком в слове, указываемом значением
ES:[BX - 2], находится адрес первого MCB. Из этой начальной точки
может быть определена вся цепочка MCB.
Эти способы использованы в программе SHOWMEM (отобразить па-
мять), приведенной в листинге 3-1.
- 3-6 -
Адрес Тип Владелец Размер
0А00:0.---------------------------------------.
| 4D | 0008 | 1600 | |
0A01:0|---------------------------------------|
| |
| Распределенный блок, владельцем кото- |
| рого является MS-DOS |
2001:0|---------------------------------------|
| 4D | 2013 | 0010 | |
2002:0|---------------------------------------|
| |
| Распределенный блок, владельцем кото- |
| рого является процесс 2013 |
2012:0|---------------------------------------|
| 4D | 2013 | 0500 | |
2013:0|---------------------------------------|
| |
| Распределенный блок, владельцем кото- |
| рого является процесс 2013 |
2513:0|---------------------------------------|
| 5A | 0000 | 7AEC | |
2514:0|---------------------------------------|
| |
| Cвободный блок (владелец - MS-DOS). |
|Содержит остаток в верхней части памяти|
| |
9FFF:F ---------------------------------------
Рис. 3-3. Блоки управления памятью MS-DOS
Листинг 3-1 содержит как исходный файл SHOWMEM.ASM, так и заголо-
вок файла PCP.INC (который мы рассмотрим несколько подробней).
Рис.3-4 изображает результаты работы программы SHOWMEM. Подпрог-
рамма ShowMCBInfo в программе SHOWMEM.ASM отображает содержимое
блока MCB. Процедура main содержит коды для размещения начального
блока и, после метки show_mem, вычислительные операции для нахож-
дения следующего блока в цепочке. Дополнительные коды в подпрог-
рамме ShowMCBOwner могут совсем не иметь смысла. Эти коды исполь-
зуются для отображения имени процесса, который владеет блоком па-
мяти, и поясняются в следующих разделах.
Рассмотрев Рис.3-4, можно усвоить несколько интересных момен-
тов. В частности, можно увидеть, что автор программы загрузил в
память три резидентные программы: RETRIEVE (восстановление), MODE
(режим) и SWITCH (переключатель). На Рис.3-4 можно также увидеть,
что программа SHOWMEM имеет очень большой выделенный для нее блок
памяти - 555 Кбайт! Кроме того, можно также увидеть, что каждая
загруженная программа имеет два распределенных для нее блока па-
мяти. Вот это последнее обстоятельство мы первым и объясним.
- 3-7 -
1 SM-ShowMem, Version 1.00 c Copyright 1988
2 MCB Size Owner Command Line
-----------------------------------------------------------
0A01 08D7 0008 DOS
12D9 00D3 12DA [ SHELL ]
13AD 0003 0000 [ available ]
13B1 0032 12DA [ SHELL ]
13E4 0004 13EA c:\bin\RETRIEVE.COM
13E9 00A9 13EA c:\bin\RETRIEVE.COM
1493 000F 14A4 S:\MODE.COM\*
14A3 0017 14A4 S:\MODE.COM\*
14BB 0010 14CD c:\ws2000\SWITCH.COM
14CC 0018 14CD c:\ws2000\SWITCH.COM
14E5 0011 14F8 c:\GUIDE\EXAMPLES\SHOWMEM.EXE
14F7 8B08 14F8 c:\GUIDE\EXAMPLES\SHOWMEM.EXE
<<<------------- End of Memory Block List ------------->>> 3
Рис. 3-4. Пример отображения результатов работы программы
SHOWMEM:
1 - программа показа памяти - ShowMem, версия 1.00, авторское
право 1988; 2 - блок управления памятью, размер, владелец, ко-
мандная строка; 3 - конец списка блоков памяти.
Листинг 3-1. SHOWMEM - программа отображения блоков памяти MS-DOS
----------------------------------------------------------------
SHOWMEM.ASM
PAGE 60,132
; **** SHOWMEM *************************************************
; ShowMem - Отображение блоков управления памятью, отредактиро-
; ванных MS-DOS
; Этот файл создает программу SM.EXE
;
;***** ВКЛЮЧЕНИЯ ИЛИ ЭКВИВАЛЕНТЫ *******************************
;
INCLUDE stdmac.inc
INCLUDE psp.inc
;
BlocMCB EQU 4Dh ; тип цепочечного MCB
LastMCB EQU 5Ah ; тип последнего MCB
FreeMCB EQU 0000h ; владелец свободного MCB
;
NameSig EQU 0001h ; сигнатура имени процесса
;
; **** КОМПОНЕНТЫ СЕГМЕНТОВ DGROUP (ДАННЫЕ) ********************
;
_DATA SEGMENT BYTE PUBLIC 'DATA'
_DATA ENDS
;
STACK SEGMENT PARA STACK
dw 1024 dup (?) ; стек 2 Кбайт
STACK ENDS
;
DGROUP GROUP _DATA, STACK
- 3-8 -
;
;**** ПАМЯТЬ ДАННЫХ ИЛИ ШАБЛОНЫ ********************************
;
_DATA SEGMENT BYTE PUBLIC 'DATA'
;
; Текстовые сообщения для отображения формата в виде:
;
; "MCB Size Owner Coommand Line"
; "------------------------------------------------------------"
; "xxxx xxxx xxxx cccccccc..."
; "<<<--------------- End of Memory Block List ------------->>>"
$Title db CR,LF
db 'SM-ShowMem, Version 1.00, c Copyright 1988'
db CR,LF,CR,LF
db 'MCB Size Owner Command Linr'
db CR,LF
db '--------------------------------------------'
db '----------------'
db CR,LF,'$'
$Space db ' $'
$Free db '[ available ]$'
$DOS db 'DOS$'
$Shell db '[ SHELL ]$'
$MCBad db CR,LF
db '********** Error in MCB Chains : Aborting List'
db ' **********'
$End db CR,LF
db '<<< ************ End of Memory Block List'
db ' ------------ >>>'
$Crlf db CR,LF,'$'
;
; Шаблоны структур
mcb STRUC ; структура блока управления памятью
TypeMCB db ? ; тип блока
OwnerMCB dw ? ; владелец блока
SizeMCB dw ? ; размер блока
mcb ENDS
;
_DATA ENDS
;
; **** Здесь начинается код программы **************************
;
_TEXT SEGMENT byte public 'code'
ASSUME cs:_TEXT, ds:DGROUP, es:DGROUP, ss:DGROUP
;
EXTRN bin2hex:NEAR ; шестнадцатиричное отображение
main PROC FAR
mov ax,DGROUP ; установка сегмента данных
mov ds,ax
;
; Отображение заголовка для списка блоков памяти
@DisStr $Title
;
; Нахождение начала очереди блоков памяти
mov ah,52h ; получение параметров DOS
int 21h ; возврат указателя в ES:BX
sub bx,2 ; указывает на 1-й адрес MCB
- 3-9 -
mov ax,word ptr es:[bx] ; получение начального блока
mov es,ax
xor di,di ; очистка индекса
cmp byte ptr es:[di].TypeMCB,BlocMCB
jne bad_chain ; выход, если не начало цепочки
;
; Цикл для нахождения и отображения каждого блока памяти
show_mem:
call ShowMCBInfo ; дамп содержимого MCB
cmp byte ptr es:[di].TypeMCB,LastMCB
je done ; выход, если конец цепочки
mov ax,es ; вычисление следующего адреса
add ax,es:[di].SizeMCB ; добавление размера блока
inc ax ; плюс 1 для себя
mov es,ax ; начало нового блока
cmp byte ptr es:[di].TypeMCB,LastMCB
je show_mem ; продолжение, если правильный тип
cmp byte ptr es:[di].TypeMCB,BlocMCB
je show_mem ; продолжение, если правильный тип
;
bad_chain: ; ошибка в MCB "chains"
@DisStr $MCBad ; завершающее сообщение
@DisStr $Crlf
mov al,1 ; завершение без ошибки
@ExitToDOS ; завершение программы
;
done: @DisStr $End ; завершающее сообщение
@DisStr $Crlf
mov al,0 ; нормальное завершение
@ExitToDOS ; завершение программы
;
main ENDP
;
; **** ShowMCBInfo *********************************************
; ShowMCBInfo отображает блоки, адресуемые с помощью ES:DI как