Списки в оперативній пам'яті, операції над списками. Керування програмами. Керування таймером. Системні керуючі блоки. Управління пам’яттю: таблиця векторів переривань, страница 8

Для кожного 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);