Для кожного MSB виводиться на екран :
- сегментна адреса MSB;
- програмний iдентифікатор " власника " блоку пам'ятi;
- розмiр блоку пам'ятi в параграфах;
- клас блоку ( см. нижче );
- символьний iдентифікатор власника ( тiльки DOS 4. 0 i вище );
- рядок виклика власника ( DOS 3. 0 i вище ).
Сегмента адреса, Pid власника i розмiр блоку одержуються з MSB. Клас блоку визначається по наступним правилам. Якщо Pid власника блоку нульовий, блок є вiльним ( клас Free ). Для зайнятих блокiв клас уточнюється. Якщо Pid (сегментна адреса Psp) власника мiстить адресу, що лежить до кінця пам'ятi ,що розподiляється memtop ( звичайно це число 8 ), то блок одержує клас DOS. Для блокiв, що не належать DOS, передусiм перевiряється сегментна адреса власника. Якщо ця адреса є адресою сегменту, наступного за поточним MSB, це означає, що блок пам'ятi мiстить програмний сегмент i одержує клас Pgm. А інакше програма "заглядає " в Psp власника. Зi змiщенням 0x2c в Psp мiститься адреса сегменту оточення; якщо ця адреса є адресою сегменту, наступного за поточним MSB, то блок одержує клас Env. Якщо клас блоку не вдається визначити жодному з описаних вище засобiв, вважаємо, що блок мiстить данi i помічаємо його класом Data. Для DOS 4. 0 i вище визначаємо символьний iдентiфикатор власника, для цього "заглядаємо" в MSB того блоку, на що зазначає стаття ui_Owner_PID поточного блоку, i виводимо його статтi pgmname. Тiльки DOS 4.0 дозволяї одержати iдентiфикатор командного процесору DOS описаним вище . Проте, в раннiх версiях DOS можна розпізнавати блок пам'ятi, що належить командному процесору от яким засобом. В Psp власника зi змiщенням 0x16 знаходять сегментну адресу " батька " - програми, яка запустила дану програму. Для програм, запущених з командного рядка DOS , батьком є Command.сom. Батьком Command. Com є вiн самий. По цьому признаку ( сам собi батько ) вiн i може бути ідентифікований. Якщо ж програма не є програмою DOS , командним процесором чи резидентною, завантаженою по Install, для неї повинен зберiгатися рядок виклика. Рядок виклика знаходиться в сегментi оточення. Програма одержує адресу початку блока оточення, пропускаї в ньому всi рядки до пустого, пiсля пустого рядка пропускаї ще 2 байта i одержуї адресу рядка виклика. З рядка виклика ми i визначаїмо iм'я програми, якій належить поточний блок.
Текст Програми:
#include <conio.h>
#include <dos.h>
#include <stdio.h>
#include <string.h>
#include <iostream.h>
struct MEMORY_CONTROL_BLOCK
{
char c_Signature;
unsigned int ui_Owner_PID;
unsigned int ui_Size_Paras;
unsigned char pc_Reserved[3];
char str_Name_Of_Owner[8];
};
void Set_Strategy(int i_Strategy);
void Get_Strategy();
void main()
{
MEMORY_CONTROL_BLOCK far *p_MCB;
MEMORY_CONTROL_BLOCK far *p_EMCB;
unsigned int segm(0),offs(0);
unsigned int ui_Seg(0);
unsigned int ui_Memtop(0);
unsigned int ui_Other_Seg(0);
unsigned int ui_Father_Seg(0);
int i(0);
int i_EnvLen(0);
int i_EnvSize(0);
unsigned char* uc_EnvStr;
clrscr ();
asm xor ax, ax
asm xor bx, bx
asm mov es, ax
asm mov ah,0x52
asm int 0x21
asm mov ax, es
asm mov segm, ax
asm sub bx,2
asm mov offs,bx
ui_Memtop = ui_Seg = (unsigned)peek(segm,offs);
do {
p_MCB = (MEMORY_CONTROL_BLOCK far *)MK_FP (ui_Seg,0);
printf("Addr=%04X:0000 ",ui_Seg);
printf("PID=%04X ",p_MCB->ui_Owner_PID);
printf("Size=%-6u ",p_MCB->ui_Size_Paras*16);
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.