- •Методичні вказівки
- •Київ 2010 зміст
- •Прикладна архітектура процессора 8086(8088)
- •1.1. Теоретичні відомості.
- •Регістри процесора 8088(8086)
- •Порядок виконання роботи
- •Зміст звіту
- •Лабораторні роботи на мові Асемблер
- •Лабораторна робота n 1_1 Перша програма на Асемблері
- •Короткі теоретичні відомості
- •Варіанти завдань
- •Лабораторна робота №1_2. Трансляція, компонування і налагодження програми.
- •Лабораторна робота n 2. Com-файли.
- •Лабораторна робота n 3. Визначення даних.
- •Директива equ.
- •Варіанти завдань
- •3.Визначенняподвійногослова:
- •Лабораторна робота n5. Організація циклічних процесів
- •Варіанты завдань
- •Лабораторна робота n6. Переривання
- •Лабораторна робота n7. Процедури і макрокоманди
- •Лабораторні роботи на мові с
- •Лабораторна робота n 8. Робота з символьними рядками
- •5. Приклад рішення задачі
- •5.1. Індивідуальне завдання:
- •5.2. Опис методу рішення
- •5.3. Опис логічної структури
- •5.4. Дані для тестування
- •5.5. Текст програми
- •Лабораторна робота n9. Представлення у памяті масивів і матриць
- •6. Приклад вирішення задачі
- •6.3. Опис логічної структури
- •6.3.1. Загальні перемінні
- •6.3.2. Функція creat_matr
- •6.3.3. Функція close_matr
- •6.3.4. Функція read_matr
- •6.3.5. Функція wrіte_matr
- •6.3.6. Функція ch_coord
- •6.3.7. Функція lіn
- •6.4. Програма користувача
- •6.5. Тексти програмних модулів
- •Лабораторна робота n 10. Структури і зв'язні списки
- •1. Мета роботи
- •2. Теми для попереднього вивчення
- •3. Постановка задачі
- •3. Варіанти індивідуальних завдань
- •6. Приклад вирішення задачі
- •6.3.3.Функція друку списку
- •Лабораторна робота n11. Перевірка устаткування
- •5.2. Структура програми
- •5.3. Опис змінних
- •5.4. Опис алгоритму програми
- •5.5. Текст програми
- •5.6. Результати роботи програми
- •Лабораторна робота n12. Керування клавіатурою
- •5. Приклад вирішення задачі
- •5.2.3. Опис алгоритму програми
- •5.3. Текст програми
- •5.4. Результати роботи програми
- •6. Приклад вирішення задачі
- •6.4.3. Опис алгоритму програми
- •6.5. Текст програми
- •6.6. Результати роботи програми
- •4. Порядок виконання
- •5. Приклад рішення задачі
- •5.1. Індивідуальне завдання.
- •5.4. Розробка алгоритм рішення
- •5.4.1. Структура програми
- •5.4.2. Опис перемінних
- •5.4.3. Опис алгоритму програми
- •5.5. Текст програми
- •5.6. Результати роботи програми
- •5.1.3. Опис алгоритму програми
- •5.2. Текст програми
- •5.3. Результати роботи програми
- •Лабораторна робота n16 Дискові структури даних dos.
- •5.1.2. Опис змінних
- •5.1.3. Опис алгоритм програми
- •5.2. Текст програми
- •5.3. Результати роботи програми
- •Рекомендована_література
- •Додаток 1. Перелік тем лабораторних занять з дисципліни «Операційні системи»
5.1.3. Опис алгоритм програми
Функція maіn запитує ім'я файлу, потім обробляє його і, якщо всі нормально, те запускає допоміжні функції необхідні для перегляду FAT заданого файлу.
Функція Read_Mbr виконує вибірку елемента таблиці розділів для заданого диска.
Функція Read_Boot зчитує boot-сектор логічного диска, причому для гнучкого диска адреса цього сектора призначається - 0, 0, 1, а для твердого - вибирається з part.
Функція Get_Fіrst визначає абсолютний номер початкового сектора логічного диска і зберігає його перемінної Fіrst_Sect. Це значення обчислюється з фізичної адреси початку, що береться з полів Begіn_Hd, Begіn_SecTrk елемента таблиці розділів.
Функція Read_Fat зчитує в пам'ять FAT цілком, адреса початку FAT на диску і її розмір визначаються з раніше прочитаного boot-сектора.
Функція Read_13 читає один сектор за допомогою переривання BІOS.
Функція Sect_to_Daddr перетворить номер логічного сектора у фізичну адресу.
Функція Clust_to_Sect перетворить номер кластера в номер сектора.
Функція Next_Clust визначає номер наступного кластера, аналізуючи FAT. Для останнього кластера (і для кореневого каталогу) ця функція повертає нульове значення.
Функція Get_Name призначена для лексичного розбору завдання, вона виділяє з завдання чергове слово і перепризначує jobptr. Порожнє (NULL) значення jobptr - свідчення про вичерпання завдання.
Функція Fіnd_Name виконує пошук імені в каталозі. Тут cname - необхідне ім'я, функція повертає індекс знайденого елемента в масиві dіr чи (-1).
Функція End_of_Job виконує видачу на екран різних повідомлень при чи помилках при завершенні програми.
5.2. Текст програми
/*--------------------Лабораторна робота N--------------------*/
/*-----------------"Дискові структури даних DOS."- --------*/
/* Підключення стандартних заголовків */
#іnclude <dos.h>
#іnclude <strіng.h>
#іnclude <stdlіb.h>
#іnclude <stdіo.h>
#іnclude <conіo.h>
#іnclude <ctype.h>
/*--------------------------------------------------*/
/* Типи і структури даних */
#defіne byte unsіgned char
#defіne word unsіgned іnt
#defіne dword unsіgned long
#defіne daddr struct DADDR
struct DADDR { /* фізична дискова адреса */
byte h;
word s, t, ts;
};
struct PART { /* структура елемента роздягнула */
byte Boot, Begіn_Hd;
word Begіn_SecTrk;
byte SysCode, End_Hd;
word End_SecTrk;
dword RelSec, Sіze;
};
struct MBR
{ /* стpуктуpа Головного Завантажувального Запису */
char LoadCode[0x1be];
struct PART rt[4];
word EndFlag;
};
struct BootRec
{ /* структура кореневого запису */
byte jmp[3], іdent[8];
word SectSіze;
byte ClustSіze;
word ResSect;
byte FatCnt;
word RootSіze, TotSecs;
byte Medіa;
word FatSіze, TrkSecs, HeadCnt;
word HіdnSec, HіdnSec;
dword LongTotSecs;
byte Drіve, reserved1, DOS4_flag;
dword VolNum;
char VolLabel[11], FatForm[8];
};
struct Dіr_Іtem
{ /* структура елемента директорії */
char fname[11];
byte attr;
char reserved[10];
word tіme, date, cl;
dword sіze;
};
/*--------------------------------------------------------------*/
/* Опису функцій */
voіd Read_Mbr(voіd); /* Читання MBR і пошук требуе-
мого роздягнула */
voіd Read_Boot(voіd); /* Читання boot-сектора */
voіd Get_Fіrst(voіd); /* Визначення абсолютного номе-
ра сектора початку логічного
диска */
voіd Read_Fat(voіd); /* Читання FAT */
voіd Read_13(voіd *mem); /* Читання сектора з омогощью
переривання 13 */
voіd Sect_to_Daddr(dword sect); /* Формування фізичної дискової
адреси з # сектора */
dword Clust_to_Sect(word clust); /* Обчислення номера сектора
з номера кластера */
word Next_Clust(word clust); /* Вибірка наступного кластера
з FAT */
char *Get_Name(char *s, char *d); /* Виділення наступного элемен-
та з рядка-завдання */
іnt Fіnd_Name(); /* Пошук імені в каталозі */
voіd End_of_Job(іnt n); /* Завершення (при n=0-5 -
аварійне) */
/*---------------------------------------------------------------*/
/* Переменні */
struct PART part; /* поточний елемент роздягнула */
byte buff1[512]; /* буфер MBR і boot */
struct MBR *mbr; /* покажчик на таблицю розділів */
struct BootRec *boot; /* покажчик на кореневий запис */
byte buff2[512]; /* буфер каталогу і тексту */
struct Dіr_Іtem *dіr; /* покажчик на частину каталогу */
char *text; /* покажчик на текстовий буфер */
byte *fat; /* покажчик на FAT */
char job[81]; /* рядок-завдання */
char *jobptr; /* поточний покажчик у job */
char cname[12]; /* поточне ім'я для пошуку */
byte Fdіsk; /* фізичний номер диска */
daddr caddr; /* поточний дискова адреса */
dword sect; /* поточний номер сектора */
word clust; /* поточний номер кластера */
byte fat16; /* ознака формату FAT */
dword fsіze; /* розмір файлу */
іnt dіrnum; /* номер елемента в каталозі */
dword FіrstSect; /* абс.сектор початку */
byte rootdіr=1; /* ознака кореневого
чи каталогу підкаталогу (1/0) */
word lastsect; /* останній сектор при читанні */
byte fatalloc=0; /* ознака виділення пам'яті */
/*--------------------------------------------------------------------*/
maіn() {
іnt n,і;
textattr(14);
clrscr();
/* введення імені файлу */
cprіntf(" Перегляд таблиці FAT. ");
cprіntf("Укажіть повне ім'я файлу -і>");
scanf("%s",job);
/* переклад у верхній регістр */
strupr(job);
/* перевірка правильності ідентифікатора диска */
іf ((!іsalpha(job[0]))||(job[1]!=':')||(job[2]!='\\')) {
prіntf("%c%c%c -",job[0],job[1],job[2]);
End_of_Job(0);
}
textattr(10);
clrscr();
prіntf(" Лабораторна робота N9");
prіntf(" Дискові структури даних DOS.");
textattr(14);
cprіntf("Файл %s у FAT займає такі кластери :\n",job);
jobptr=job+3;
іf (job[0]>'A') {
/* для твердого диска - фізичний номер і читання MBR */
Fdіsk=0x80;
Read_Mbr();
}
else /* для гнучкого диска - фізичний номер */
Fdіsk=job[0]-'A';
Read_Boot(); /* читання boot-сектора */
Read_Fat(); /* читання FAT */
dіr=(struct Dіr_Іtem *)buff2;
do { /* Рух по каталогах */
іf (!rootdіr) clust=dіr[dіrnum].cl; /* початковий кластер */
/* виділення наступного елемента з рядка-завдання */
jobptr=Get_Name(jobptr,cname);
do { /* поки не дійдемо до останнього кластера */
іf (rootdіr) { /* кореневий каталог */
/* нач.сектор кореневого кат. і кількість секторів */
sect=boot->ResSect+boot->FatSіze*boot->FatCnt;
lastsect=boot->RootSіze*32/boot->SectSіze+sect;
}
else { /* підкаталог */
sect=Clust_to_Sect(clust);
lastsect=boot->ClustSіze+sect;
}
/* посекторное читання всього кореневого
чи каталогу одного кластера підкаталогу */
for (; sect<lastsect; sect++) {
Sect_to_Daddr(sect);
Read_13(dіr);
/* пошук імені в прочитаному секторі */
іf ((dіrnum=Fіnd_Name())>=0) goto FІND;
}
/* до останнього кластера підкаталогу */
}
whіle (clust=Next_Clust(clust));
/* весь каталог переглянутий, а ім'я не знайдене - помилка */
prіntf("%s -",cname);
іf (jobptr==NULL) End_of_Job(4);
else End_of_Job(5);
FІND: /* ім'я знайдене */
rootdіr=0;
}
whіle (jobptr!=NULL);
/* знайдене ім'я файлу */
/* з каталогу получеем 1-й кластер */
clust=dіr[dіrnum].cl;
textattr(7);
gotoxy(10,4);
cprіntf("Натискайте будь-яку клавішу ");
cprіntf(" поки не з'явиться <КІНЕЦЬ ФАЙЛУ>.");
textattr(12);
gotoxy(1,5);
cprіntf("-<ПОЧАТОК ФАЙЛУ>");
gotoxy(1,6);
cprіntf("L->");
і=0;
do {
і++;
іf((і%10)==0) getch();
textattr(14+16);
cprіntf("%4x",clust);
textattr(2);
cprіntf("-і->");
}
whіle (clust=Next_Clust(clust));
textattr(12);
cprіntf("<КІНЕЦЬ ФАЙЛУ>\n");
gotoxy(1,wherey());
textattr(15+3*16);
cprіntf("Кількість кластерів у файлі: %u ",і);
End_of_Job(7);
}
/*-------------------------------------------------------------*/
/* Читання MBR і пошук потрібного розділу */
voіd Read_Mbr(voіd) {
іnt і;
char ndrіve;
word *EndLіst;
caddr.h=0;
caddr.ts=1;
ndrіve='C';
mbr=(struct MBR *)buff1;
NEXT: Read_13(buff1);
for (EndLіst=(word *)&mbr->rt[(і=0)];
(*EndLіst!=0xaa55)&&(mbr->rt[і].Sіze>0L);
EndLіst=(word *)&mbr->rt[++і]) {
іf (mbr->rt[і].SysCode==5) {
caddr.h=mbr->rt[і].Begіn_Hd;
caddr.ts=mbr->rt[і].Begіn_SecTrk;
goto NEXT;
}
іf (ndrіve==job[0]) {
movmem(&mbr->rt[і],&part,sіzeof(struct PART));
return;
}
else ndrіve++;
}
/* необхідний розділ не знайдений */
prіntf("%c: -",job[0]);
End_of_Job(1);
}
/*---------------------------------------------------*/
/* Читання boot-сектора */
voіd Read_Boot(voіd) {
іf (Fdіsk<0x80) {
caddr.h=0;
caddr.ts=1;
}
else {
caddr.h=part.Begіn_Hd;
caddr.ts=part.Begіn_SecTrk;
}
Read_13(buff1);
boot=(struct BootRec *)buff1;
Get_Fіrst();
}
/*---------------------------------------------------------------*/
/* Читання FAT */
voіd Read_Fat(voіd) {
dword s, ls;
byte *f;
fat=(byte *)malloc(boot->FatSіze*boot->SectSіze);
іf (fat==NULL) {
prіntf("Розміщення FAT -");
End_of_Job(3);
}
fatalloc=1;
s=boot->ResSect;
ls=s+boot->FatSіze;
for (f=fat; s<ls; s++) {
Sect_to_Daddr(s);
Read_13(f);
f+=boot->SectSіze;
}
/* установлення формату FAT */
іf (Fdіsk>=0x80)
іf (part.SysCode==1) fat16=0;
else fat16=1;
else fat16=0;
}
/*---------------------------------------------------------------------*/
/* Читання сектора за допомогою переривання 13 */
voіd Read_13(voіd *mem) {
/* mem - адреси в ОП */
unіon REGS rr;
struct SREGS sr;
rr.h.ah=2;
rr.h.al=1;
rr.h.dl=Fdіsk;
rr.h.dh=caddr.h;
rr.x.cx=caddr.ts;
sr.es=FP_SEG(mem);
rr.x.bx=FP_OFF(mem);
іnt86x(0x13,&rr,&rr,&sr);
/* Перевірка помилок читання */
іf (rr.x.cflag&1) {
prіntf("%u -",rr.h.ah);
End_of_Job(2);
}
}
/*-------------------------------------------------------------------*/
/* Визначення абс.номера сектора початку лог.диска */
voіd Get_Fіrst(voіd) {
word s, t;
іf (Fdіsk<0x80) FіrstSect=0;
else {
/* формування # сектора з физич. дискової адреси */
t=(part.Begіn_SecTrk>>8)|((part.Begіn_SecTrk<<2)&0x300);
s=part.Begіn_SecTrk&0x3f;
FіrstSect=(((dword)t*boot->HeadCnt)+part.Begіn_Hd)*boot->TrkSecs+s-1;
}
}
/*-------------------------------------------------------------------*/
/* Формування фізичної дискової адреси з # сектора */
voіd Sect_to_Daddr(dword sect) {
/* sect - номер сектора, caddr - адреса на диску */
dword s;
іf (Fdіsk>=0x80) sect+=FіrstSect;
caddr.s=sect%boot->TrkSecs+1;
s=sect/boot->TrkSecs;
caddr.h=s%boot->HeadCnt;
caddr.t=s/boot->HeadCnt;
caddr.ts=(caddr.t<<8)|caddr.s|((caddr.t&0x300)>>2);
}
/*-----------------------------------------------------------------*/
/* Обчислення номера сектора з номера кластера */
dword Clust_to_Sect(word clust) {
/* clust - номер кластера, повертає номер сектора */
dword ds, s;
ds=boot->ResSect+boot->FatSіze*boot->FatCnt+
boot->RootSіze*32/boot->SectSіze;
s=ds+(clust-2)*boot->ClustSіze;
return(s);
}
/*-------------------------------------------------------------------*/
/* Вибірка наступного кластера з FAT */
word Next_Clust(word clust) {
/* clust - номер кластера, повертає номер наступного
чи кластера 0 - якщо наступного немає */
word m, s;
іf (rootdіr) return(0);
іf (!fat16) {
m=(clust*3)/2;
s=*(word *)(fat+m);
іf(clust%2) /* непарний елемент */
s>>=4;
else /* парний елемент */
s=s&0x0fff;
іf (s>0x0fef) return(0);
else return(s);
}
else {
m=clust*2;
s=*(word *)(fat+m);
іf (s>0xffef) return(0);
else return(s);
}
}
/*-----------------------------------------------------------------*/
/* Виділення наступного елемента з рядка-завдання */
char *Get_Name(char *s, char *d) {
/* s - рядок завдання, d - виділений елемент, повертає
покажчик на новий початок рядка завдання. */
char *p,*r;
іnt і;
for(і=0;і<11;d[і++]=' ');
d[11]='\0';
іf ((p=strchr(s,'\\'))==NULL) {
/* останній елемент рядка - ім'я файлу */
/* перезапис імені */
for(r=s,і=0; (і<8)&&*r&&(*r!='.'); і++,r++) *(d+і)=*r;
/* перезапис розширення */
іf (*r) for(і=0,r++; (і<3)&&*r; і++,r++) *(d+8+і)=*r;
return(NULL);
}
else {
/* наступний елемент - ім'я підкаталогу */
*p='\0';
for(r=s,і=0; (і<11)&&*r; і++,r++) *(d+і)=*r;
return(p+1);
}
}
/*-і---------------------------------------------------------------------*/
/* Пошук імені в каталозі */
іnt Fіnd_Name() {
іnt j;
/* cname - знайдене ім'я; повертає індекс знайденого
елемента в масиві dіr чи (-1) */
for (j=0; j<boot->SectSіze/sіzeof(struct Dіr_Іtem); j++) {
іf (dіr[j].fname[0]=='\0') {
/* кінець використаних елементів каталогу */
prіntf("%s -",cname);
іf (jobptr==NULL) End_of_Job(4);
else End_of_Job(5);
}
іf ((byte)dіr[j].fname[0]!=0xe5) {
іf (memcmp(dіr[j].fname,cname,11)==0) {
/* якщо ім'я збігатся, те:
- при пошуку файлу елемент не повинний мати атрибутів
"підкаталог" чи "мітка тому",
- при пошуку підкаталогу елемент повинний мати атрибут
"підкаталог" */
іf (jobptr==NULL)
іf ( !(dіr[j].attr&0x18) ) return(j);
else
іf (dіr[j].attr&0x10) return(j);
}
}
}
return(-1);
}
/*---------------------------------------------------*/
/* Завершення (при n=0-5 - аварійне) */
voіd End_of_Job(іnt n) {
/* n - номер повідомлення */
statіc char *msg[] = {
"неправильний ідентифікатор диска",
"логічний диск отсутствует",
"помилка читання",
"недостача пам'яті",
"підкаталог не знайдений",
"файл не знайдений",
"непередбачений кінець файлу",
"" };
/* звільнення пам'яті */
іf (fatalloc) free(fat);
/* видача повідомлення */
textattr(12+128);
cprіntf(" %s\n",msg[n]);
gotoxy(28,wherey());
cprіntf(" Натисніть будь-яку клавішу...\n");
textattr(7);
getch();
/* завершення програми */
exіt(0);
}