Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
УМКДО_СистПрог_2016.doc
Скачиваний:
8
Добавлен:
01.07.2025
Размер:
2 Мб
Скачать
☆

5.1.3. Описание алгоритма программы

Главная программа main() осуществляет бесконечный цикл для обработки кодов нажатых клавиш и в зависимости от них вызывается функция PrintVec(int num) для вывода на экран информации о векторах прерывания. Выход из данного цикла производится по нажатию клавиши Esc.

Функция readvect() читает вектор заданного прерывания. Для чтения вектора используем функцию 35h DOS (прерывание 21h):

     

Вход:  

AH = 35h;  AL = номер вектора прерывания.

     

Выход:  

ES:BX = адрес программы обработки прерывания.

Функция get_memtop() возвращает адрес начала цепочки MCB csegm. Адpес начала цепочки блоков памяти можно получить пpи помощи недокументиpованной функции DOS 52h. Эта функция возвpащает в pегистpах ES:BXнекотоpый адpес. Вычтя из этого адpеса 2, получим адpес того слова памяти, в котоpом DOS хpанит сегментный адpес пеpвого MCB в цепочке.

Функция dos_version_h() возвращает номер версии DOS при помощи функции 30h.

Функция name_handler() находит какой программой было перехвачено текущее прерывание.

Функция PrintVec(int num) выводит на экран номера прерываний и программы которые их перехватили начиная с номера num, при этом она в цикле вызывает функцию name_handler() для получения информации о программе, которая перехватила текущий вектор прерывания.

5.2 Текст программы

/*-----------------Лабораторная работа N13----------------*/

/*------------------"Управление памятью."-----------------*/

/* Подключение стандартных заголовков */

#define byte unsigned char

#define word unsigned int

#define Esc 27

#define Up 0x48

#define Down 0x50

#define Home 0x47

#define Endk 79

#define PgUp 73

#define PgDn 81

#include <dos.h>

#include <string.h>

#include <stdlib.h>

#include <conio.h>

void *readvect(int in);

void get_memtop(void);

void dos_version_h(void);

void name_handler(void);

void PrintVec(int num);

struct MCB { /* блок упpавления памятью */

char type; /* тип */

word owner,/* владелец */

size; /* размер */

byte reserved[3]; /* зарезервировано */

char pgmname[8]; /* имя программы, находящейся в данном блоке

( для DOS 4.0 и выше ) */

};

struct MCB *cmcb; /* адpес текущего MCB */

struct MCB *emcb; /* адpес MCB сpеды */

word memtop; /* сегментныйадрес начала памяти */

word csegm; /* сегментный адpес текущего MCB */

word othersegm; /* сегментныйадрес другого MCB */

word othersegm1;

word fathersegm; /* сегментныйадрес родителя */

byte *envstr; /* адpес стpоки окружения */

int envlen; /* длина очередной строки окружения */

int envsize; /* размер блока окружения */

byte dos; /* номер версии DOS */

void far *vect; /* вектор */

int intnum; /* номер прерывания */

union REGS rr;

struct SREGS sr;

void main() {

int i,a;

get_memtop();

dos_version_h();

clrscr();

textattr(10);

clrscr();

cprintf("---------------");

cprintf(" Лабораторная работа N13 ");

cprintf("---------------");

cprintf("---------------");

cprintf(" Управление памятью. ");

cprintf("---------------");

gotoxy(28,3);

textattr(12);

cprintf("Таблица векторов прерывания.");

gotoxy(1,4);

textattr(11);

cprintf("Номер - Адрес - Чем_занят");

gotoxy(7,25);

textattr(7);

cprintf("Клавиши управления: <Up>,<Dn>,<Home>,<End>,<PgUp>,<PgDn>

,<Esc>");

intnum=0;

PrintVec(intnum);

for(i=0;i==0;)

switch(getch())

{ /* Обработка нажатых клавиш */

case Esc: i++; break;

case 0: switch (getch()) {

case Up:intnum--;

if(intnum<0) intnum=0;

PrintVec(intnum);

break;

case Down:intnum++;

if(intnum>240) intnum=240;

PrintVec(intnum);

break;

case PgUp:intnum-=16;

if(intnum<0) intnum+=16;

PrintVec(intnum);

break;

case PgDn:intnum+=16;

if(intnum>256) intnum-=16;

PrintVec(intnum);

break;

case Home:intnum=0;

PrintVec(intnum);

break;

case Endk:intnum=0xf0;

PrintVec(intnum);

break;

}

}

}

/*--------------------------------------------------------*/

void PrintVec(int num)

{

int i,y;

gotoxy(1,5);

textattr(14);

for (i=0;i<17;i++)

{ y=wherey();

cprintf(" \n");

gotoxy(1,y);

if ((num+i)<=0xff)

{

vect=readvect(num+i);

cprintf("INT %02Xh - %Fp - ",num+i,vect);

if (vect==NULL)

cprintf("%-16s","Свободен");

else

{intnum=num;

name_handler();}

printf("\n");

}

}

}

/*--------------------------------------------------------*/

void name_handler(void)

{

int i;

char *s;

word tsegm;

othersegm1=FP_SEG(vect);

tsegm=memtop;

do

{

csegm=tsegm;

cmcb=(struct MCB *)MK_FP(csegm,0);

tsegm=csegm+cmcb->size+1;

}

while((othersegm1>tsegm)&&(cmcb->type!='Z'));

if ((cmcb->owner<memtop)||(cmcb->type=='Z'))

printf("%-16s","Занят Bios/Dos");

else

{ /* блок не принадлежит DOS */

othersegm=peek(cmcb->owner,0x2c);

fathersegm=peek(cmcb->owner,0x16);

/* если хозяин сам себе родитель, то это COMMAND */

if (cmcb->owner==fathersegm)

printf("%-16s","COMMAND.COM");

else

{ /* для другой программы узнаем ее имя */

if (dos>3)

{

emcb=(struct MCB *)MK_FP(cmcb->owner-1,0);

for (i=0,s=emcb->pgmname; i<8; i++)

{

if (*s>0)

printf("%c",*(s++));

else

printf(" ");

}

printf("%-8s"," ");

}

else

if (dos>2)

{ /* для DOS 3.0 и выше имя - из строки вызова */

emcb=(struct MCB *)MK_FP(othersegm-1,0);

envsize=emcb->size*16; /*размер окружения */

envstr=(char *)MK_FP(othersegm,0);

do

{

/* пропуск строк окружения до пустой строки */

envlen=strlen(envstr)+1;

envstr+=envlen; envsize-=envlen;

}

while ((envlen>1)&&(envsize>0));

envstr+=2;

envsize-=2; /* 2 байта - кол.строк */

/* envstr - указатель на строку вызова */

if (envsize>0)

printf("%-16s",envstr);

}

}

}

}

/*==== Получение вектора ====*/

void *readvect(int in) {

union REGS rr; struct SREGS sr;

rr.h.ah=0x35; rr.h.al=in; intdosx(&rr,&rr,&sr);

return(MK_FP(sr.es,rr.x.bx));

}

/* получить адрес начала цепочки MCB csegm */

void get_memtop(void)

{

rr.h.ah=0x52;

intdosx(&rr,&rr,&sr);

memtop=csegm=peek(sr.es,rr.x.bx-2);

}

/* получить номер версии DOS */

void dos_version_h(void)

{

rr.h.ah=0x30;

intdos(&rr,&rr);

dos=rr.h.al;

}