КаталогИндекс раздела
НазадОглавление


Лабораторная работа 13
УПРАВЛЕНИЕ ПАМЯТЬЮ

1. Цель работы

Просмотр таблицы векторов прерываний, которая в данный момент находится в ПЭВМ на рабочем месте.

2. Темы для предварительной проработки

3. Постановка задачи

Определить, какие вектора прерываний на данном компьютере перехвачены программами не из состава DOS/BIOS и имена этих программ.

4. Порядок выполнения работы

5. Пример решения задачи

5.1. Разработка алгоритма решения

5.1.1. Структура программы

Программа состоит из основной программы main() и пяти вспомогательных функций.

5.1.2. Описание переменных

Переменные глобальные для всей программы:

Стpуктуpа MCB:

       struct MCB {
         byte type;        /* тип */
         word owner;       /* владелец */
         word size;        /* размер */
         byte reserved[3]; /* не используется */
         char pgmname[8];  /* имя (только DOS 4.0 и выше) */
         };

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;
}


5.3. Результаты работы программы

В процессе работы программы на экран была выведена таблица векторов прерываний, просматривать которую можно с помощью клавиш управления:

--------------------------------------------------------------------------------
---------------              Лабораторная работа N13             ---------------
---------------                 Управление памятью.              ---------------
                           Таблица векторов прерывания.
Номер   - Адрес     - Чем_занят
INT 00h - 0BB0:0125 - TC_LAB13
INT 01h - 0070:06F4 - Занят Bios/Dos
INT 02h - 03DA:0016 - Занят Bios/Dos
INT 03h - 0070:06F4 - Занят Bios/Dos
INT 04h - 0070:06F4 - Занят Bios/Dos
INT 05h - F000:FF54 - Занят Bios/Dos
INT 06h - F000:EB43 - Занят Bios/Dos
INT 07h - F000:EAEB - Занят Bios/Dos
INT 08h - 0ACF:013D - COPY_ECR
INT 09h - 0ACF:0117 - COPY_ECR
INT 0Ah - 03DA:0057 - Занят Bios/Dos
INT 0Bh - 03DA:006F - Занят Bios/Dos
INT 0Ch - 03DA:0087 - Занят Bios/Dos
INT 0Dh - 03DA:009F - Занят Bios/Dos
INT 0Eh - 03DA:00B7 - Занят Bios/Dos
INT 0Fh - 0070:06F4 - Занят Bios/Dos
INT 10h - 057A:035B - KEYRUS


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


КаталогИндекс раздела
НазадОглавление