diff --git a/ASMOUSE.CPP b/ASMOUSE.CPP index 02156ba..9195673 100755 --- a/ASMOUSE.CPP +++ b/ASMOUSE.CPP @@ -1,131 +1,131 @@ -/**************************************************************************** -** ணࠬ , ⢨ 誮,** -** ᯮ ++ ᥬ. ** -****************************************************************************/ - -#include -#include -#include -#include - -// ६, ࠭騥 न ਧ -//. -unsigned int MouseX, MouseY, MouseB; - -char IfMouse (); -void ShowMouse (); -void HideMouse (); -void ReadMouse (); -void SetMouseXY (unsigned int X, unsigned int Y); -void SetMinMaxX (unsigned int Min, unsigned int Max); -void SetMinMaxY (unsigned int Min, unsigned int Max); - -// 楤 ஢ 㯭 -char IfMouse () -{ - unsigned int Result; - asm mov ax, 0 - asm int 0x33 - asm mov Result, ax - return Result; -} - -// 楤 -void ShowMouse () -{ - asm mov ax, 0x1 - asm int 0x33 -} - -// 楤 -void HideMouse () -{ - asm mov ax, 0x2 - asm int 0x33 -} - -// 楤 뢠 ਧ -// -void ReadMouse () -{ - asm mov ax, 0x3 - asm int 0x33 - asm mov MouseB, bx - asm mov MouseX, cx - asm mov MouseY, dx -} - -// 楤 ⠭ 㣨 न -void SetMouseXY (unsigned int X, unsigned int Y) -{ - asm mov ax, 0x4 - asm mov cx, X - asm mov dx, Y - asm int 0x33 -} - -// 楤 ⠭ 쭮 ᨬ쭮 祭 -//࠭ ஬⪠, ஬ -// ਧ⠫쭮 . -void SetMinMaxX (unsigned int Min, unsigned int Max) -{ - asm mov ax, 0x7 - asm mov cx, Min - asm mov dx, Max - asm int 0x33 -} - -// 楤 ⠭ 쭮 ᨬ쭮 祭 -//࠭ ஬⪠, ஬ -// ⨪쭮 . -void SetMinMaxY (unsigned int Min, unsigned int Max) -{ - asm mov ax, 0x8 - asm mov cx, Min - asm mov dx, Max - asm int 0x33 -} -// ࠬ - 楤 ᠭ . -main(){ - clrscr(); - IfMouse(); - cout<<" 㯭 ⥬.\n"; - delay(3000); - cout<<"  - প 3 ᥪ.\n"; - delay(3000); - ShowMouse(); - cout<<" 祧 - প 3 ᥪ.\n"; - delay(3000); - HideMouse(); - cout<<"१ 3 ᥪ  .\n"; - delay(3000); - ShowMouse(); - ReadMouse(); - cout<<"\nन #1:\n"; - cout<<"-न: "< +#include +#include +#include + +//Глобальные переменные, хранящие координаты и признак нажатия на кнопку +//мыши. +unsigned int MouseX, MouseY, MouseB; + +char IfMouse (); +void ShowMouse (); +void HideMouse (); +void ReadMouse (); +void SetMouseXY (unsigned int X, unsigned int Y); +void SetMinMaxX (unsigned int Min, unsigned int Max); +void SetMinMaxY (unsigned int Min, unsigned int Max); + +//Эта процедура проверяет доступна ли мышь +char IfMouse () +{ + unsigned int Result; + asm mov ax, 0 + asm int 0x33 + asm mov Result, ax + return Result; +} + +//Эта процедура делает видимым курсор мыши +void ShowMouse () +{ + asm mov ax, 0x1 + asm int 0x33 +} + +//Эта процедура делает невидимым курсор мыши +void HideMouse () +{ + asm mov ax, 0x2 + asm int 0x33 +} + +//Эта процедура считывает положение курсора мыши и признак нажатия +//на клавишу +void ReadMouse () +{ + asm mov ax, 0x3 + asm int 0x33 + asm mov MouseB, bx + asm mov MouseX, cx + asm mov MouseY, dx +} + +//Эта процедура устанавливает курсор в другие координаты +void SetMouseXY (unsigned int X, unsigned int Y) +{ + asm mov ax, 0x4 + asm mov cx, X + asm mov dx, Y + asm int 0x33 +} + +//Эта процедура устанавливает минимальное и максимальное значение +//границ промежутка, в котором может двигаться курсор мыши +//в горизонтальном положении. +void SetMinMaxX (unsigned int Min, unsigned int Max) +{ + asm mov ax, 0x7 + asm mov cx, Min + asm mov dx, Max + asm int 0x33 +} + +//Эта процедура устанавливает минимальное и максимальное значение +//границ промежутка, в котором может двигаться курсор мыши +//в вертикальном положении. +void SetMinMaxY (unsigned int Min, unsigned int Max) +{ + asm mov ax, 0x8 + asm mov cx, Min + asm mov dx, Max + asm int 0x33 +} +//Главная пограмма - тестирует мышь и процедуры описанные выше. +main(){ + clrscr(); + IfMouse(); + cout<<"Мышь доступна в системе.\n"; + delay(3000); + cout<<"Сейчас появится курсор - задержка 3 сек.\n"; + delay(3000); + ShowMouse(); + cout<<"Сейчас курсор исчезнет - задержка 3 сек.\n"; + delay(3000); + HideMouse(); + cout<<"Через 3 сек курсор появится вновь.\n"; + delay(3000); + ShowMouse(); + ReadMouse(); + cout<<"\nКоординаты мыши на момент #1:\n"; + cout<<"Х-координата: "< -#include -#include -#include -#include -#define Port8042 0x60 - -long far * pTime=(long far*)0x46C; // ⥫ 稪 ⨪ - -// । 㪠⥫ 砫 - -int far * pHeadPtr=(int far *)0x41A; // ⥫ 㪠⥫ .. -int far * pTailPtr=(int far *)0x41C; // ⥫ 㪠⥫ 墮 .. -unsigned char far * pBuf; - -void main() -{ -// 3 N1. - clrscr(); - - cout << "\n 3 N1:\n"; - cout << "\n 祭 !"; - cout << "\n ஡ - .\n"; - char cScan,cAsci; - int iAdres; - do - { - // 㧨 ॣ஢, ਬ ds:si 祭 0x40:0x1A - asm{ - push ds // - push si // ࠭ ॣ - push di // - mov ax,0x40 // - mov ds,ax // 㧨 ᥣ - mov si,0x1A // 㪠⥫ - mov di,0x1C // 墮 - } - wait_kbd: - asm{ - mov ax,[si] // ࠢ 㪠⥫ - - cmp ax,[di] // .. - je wait_kbd - // 㧨 ॣ di 祭 0x1C - // ࠢ 㪠⥫ - // 㪠⥫ - mov si,[si] - } - iAdres=_SI; - // 祭 - asm mov ax,[si] - // _AL _AH ᮤঠ ᪠- ASCII- - asm pop di - asm pop si - asm pop ds - cScan=_AH; - cAsci=_AL; - printf(" = %x = %d ASCII = %d \n",iAdres,cScan,cAsci); - } while(getch() != 32); - cout << "\n ࢮ . Press any key...\n"; - getch(); - - delay(1000); - asm in al,0x60 - cScan=0; // ?????? - printf(" = %x \n",cScan); -// goto met; -// -} -// -// 1 ।⠢ ணࠬ -// । ⫨稥 ASCII : ᭮ 㦥 -// 2 ணࠬ 横᪮ ⥭ ᪠ 60 -// । ⫨稥 ᪠ : ᪠ +// "Обмен IBM PC с клавиатурой" +// Labv10 + +#include +#include +#include +#include +#include +#define Port8042 0x60 + +long far * pTime=(long far*)0x46C; // Указатель на счетчик тиков + +// Определим указатели начала и конца буфера + +int far * pHeadPtr=(int far *)0x41A; // Указатель на указатель головы буф.кл. +int far * pTailPtr=(int far *)0x41C; // Указатель на указатель хвоста буф.кл. +unsigned char far * pBuf; + +void main() +{ +// 3адание N1. + clrscr(); + + cout << "\n 3адание N1:\n"; + cout << "\n Нажимайте клавиши для получения кодов!"; + cout << "\n Пробел - идем дальше.\n"; + char cScan,cAsci; + int iAdres; + do + { + // Загрузить пару регистров, например ds:si значением 0x40:0x1A + asm{ + push ds // + push si // Сохранили регистры + push di // + mov ax,0x40 // + mov ds,ax // Загрузили сегмент + mov si,0x1A // и указатели на голову + mov di,0x1C // и на хвост + } + wait_kbd: + asm{ + mov ax,[si] // Сравниваем указатели - + cmp ax,[di] // т.е. ждем нажатия + je wait_kbd + // Загрузить регистр di значением 0x1C + // Сравнить указатели + // Прочитать указатель + mov si,[si] + } + iAdres=_SI; + // Прочитать значение из буфера + asm mov ax,[si] + // Теперь _AL и _AH содержат скан-код и ASCII-код + asm pop di + asm pop si + asm pop ds + cScan=_AH; + cAsci=_AL; + printf("Адрес = %x Скан = %d ASCII = %d \n",iAdres,cScan,cAsci); + } while(getch() != 32); + cout << "\n Конец первого задания. Press any key...\n"; + getch(); + + delay(1000); + asm in al,0x60 + cScan=0; // ?????? + printf(" Скан = %x \n",cScan); +// goto met; +// +} +// Задание +// 1 Разберите представленную программу +// Определите отличие ASCII кодов: основных и служебных клавиш +// 2 Напишите мини программу циклического чтения скан кодов из порта 60 +// Определите отличие скан кодов: нажатия и отпускания клавиши diff --git a/LABV11.CPP b/LABV11.CPP index 697e191..3a04e47 100755 --- a/LABV11.CPP +++ b/LABV11.CPP @@ -1,40 +1,40 @@ -/* ୠ ࠡ 11 - , ᪨ ० sVGA -*/ -#include -#include -#include - -void set_mode(int mode) -{ - asm{ - mov ax,0x4f02; - mov bx,mode ; - int 0x10; - } -} - -void main(void) -{ -set_mode(0x0112); -unsigned char c=0; -for (int i=2; i<640*4;i+=4) -{ -asm { - mov ax,0xa000; - mov es,ax; - mov si,i - mov bh,c - mov bl,c - mov es:[si],bl - - } - - c++; -} -getch(); -set_mode(0x3); -} -// -//। 浪 梥 111 112 ० -// ணࠬ 뢮 ⮭ +/* Лабораторная работа 11 + Видеоадаптер, графические режимы sVGA +*/ +#include +#include +#include + +void set_mode(int mode) +{ + asm{ + mov ax,0x4f02; + mov bx,mode ; + int 0x10; + } +} + +void main(void) +{ +set_mode(0x0112); +unsigned char c=0; +for (int i=2; i<640*4;i+=4) +{ +asm { + mov ax,0xa000; + mov es,ax; + mov si,i + mov bh,c + mov bl,c + mov es:[si],bl + + } + + c++; +} +getch(); +set_mode(0x3); +} +// Задание +//Определите в каком порядке кодируются цвета в 111 и 112 режимах +//Напишите программу вывода полутонового клина на Асс diff --git a/LABV5.CPP b/LABV5.CPP index 4f8349d..5b48284 100755 --- a/LABV5.CPP +++ b/LABV5.CPP @@ -1,57 +1,57 @@ -// N LAB5 -// ணࠬ -// - - -#include -#include -#include - -/* - 맮 㭪樨 , Call - Assembler. ⮬ । 㭪 ࠬ, - ਭ樯 ࠢ . ⥬ IP ᫥饩 , -饩 Call. (ᥣ 맮 楤) -室 㭪樨 ⢫ RET. -*/ - -//㭪, 믮 ᫮, ࠬ । १ ⥪ -void addition(long sl_1,long sl_2, long &sum) -{ -/* asm{ - mov AX,[BP+4] //AX - 訥 pp p ᫠ - mov DX,[BP+8] //DX - 訥 pp ண ᫠ - mov SI,[BP+12] //SI - 㬬 pp冷 - add AX,DX //᫮ pp冷 - mov [SI],AX //p ᢥ SI - mov AX,[BP+6] //AX - p訥 pp p ᫠ - mov DX,[BP+10] //DX - 訥 pp ண ᫠ - //᫮ p pp冷 - mov [SI+2],AX //p SI - }*/ - sum=sl_2; -} - -void main ( void ) -{ -long a,b; -long sum; - -cout<<"\n ࢮ ᫠: "; -cin>>a; -cout<<" ஥ ᫠: "; -cin>>b; - -addition(a,b,sum); - -cout<<"a + b = "< +#include +#include + +/* +При вызове функции в Си, она интерпретируется как команда Call +в Assembler. При этом передаваемые в функцию параметры, заносятся в +СТЕК по принципу справа налево. Затем заносится IP следующей команды, +идущей за Call. (внутрисегментный вызов процедуры) +Выход из функции осуществляется с помощью команды RET. +*/ + +//Функция, выполняющая сложение, параметры перед через стек +void addition(long sl_1,long sl_2, long &sum) +{ +/* asm{ + mov AX,[BP+4] //AX - младшие pазpяды пеpвого слагаемого + mov DX,[BP+8] //DX - младшие pазpяды второго слагаемого + mov SI,[BP+12] //SI - сумма младших pазpядов + add AX,DX //сложение младших pазpядов + mov [SI],AX //pезультат косвенно в SI + mov AX,[BP+6] //AX - стаpшие pазpяды пеpвого слагаемого + mov DX,[BP+10] //DX - младшие pазpяды второго слагаемого + //сложение стаpших pазpядов + mov [SI+2],AX //pезультат в SI + }*/ + sum=sl_2; +} + +void main ( void ) +{ +long a,b; +long sum; + +cout<<"\n Введите первое слагаемое: "; +cin>>a; +cout<<" Введите второе слагаемое: "; +cin>>b; + +addition(a,b,sum); + +cout<<"a + b = "< -#include -#include -#include - -void interrupt (*old)(...); // 㤥 ࠭ -void interrupt cmp_int(...) // ࠡ稪 -{ -cout<<"뢠 "; -getch(); - -} - -void main(void) -{ int aa; - aa=1; - old=getvect(0xf0); - disable(); - setvect(0xf0,cmp_int); - enable(); -// aa=aa/0; - geninterrupt(0xf0); - - puts("v1=v2"); - setvect(0xf0,old); - return; -// -// 1 ணࠬ ࠡ⪨ 뢠 -// 2 맮 뢠 ⥬ ࣠樨 ᮡ -// 3 ᯮ짮 int3, । ᯮ. TD - } +/* LAB6 + Лабораторная работа по теме + "Программные прерывания" + + +При вызове функции - прерывания из СИ, используется INT. +В связи с этим стек заполняется несколько иначе. +В стеке сохраняются значения IP, СS (сегмент кода),от куда вызывается +прерывание, и флаги. +Выход из INT осуществляется с помощью IRet,которая вынимает из стека +все старые регистров CS, IP и флагов. +Так же при вызове прерывания,флажок прерывания i и t +устанавливается в 0, что запрещает вызов любых других прерываний, +а также запрещает трассировку. +*/ +#include +#include +#include +#include + +void interrupt (*old)(...); // здесь будем сохранять старый вектор +void interrupt cmp_int(...) // а это наш обработчик +{ +cout<<"Прерывание "; +getch(); + +} + +void main(void) +{ int aa; + aa=1; + old=getvect(0xf0); + disable(); + setvect(0xf0,cmp_int); + enable(); +// aa=aa/0; + geninterrupt(0xf0); + + puts("v1=v2"); + setvect(0xf0,old); + return; +// Задания +// 1 Напишите программу обработки прерывания +// 2 Вызовите прерывание путем организации особого случая +// 3 Покажите использование команды int3, определите ее код с испол. TD + } diff --git a/LABV7.CPP b/LABV7.CPP index 31d9c43..268de9e 100755 --- a/LABV7.CPP +++ b/LABV7.CPP @@ -1,41 +1,41 @@ -/* LAB-7 - ୠ ࠡ ⥬ - "᫠ ᯫ饩 ⮩" - - */ -#include -#include -#include -#include -#include - -void main(void) -{ int aa; -// 樨 饩 ⮩ ஢ - float bb,ad; - aa=1; bb=5.0;ad=3.1; - bb=aa; -cout<<"\n Ci "<>bb; -getch(); - -// 樨 饩 ⮩ ஢ ᥬ -asm { finit - fld ad - fld bb - fadd - fstp bb -} -cout<<" Acc "< +#include +#include +#include +#include + +void main(void) +{ int aa; +// Операции с плавающей запятой на уровне Си + float bb,ad; + aa=1; bb=5.0;ad=3.1; + bb=aa; +cout<<"\n Ci "<>bb; +getch(); + +// Операции с плавающей запятой на уровне Ассемблера +asm { finit + fld ad + fld bb + fadd + fstp bb +} +cout<<" Acc "< -#include -#include -#include -#include - -#include ; - -union REGS r; - -void main() -{ -// ⠭ ० - int j,i,ii,color=0; - r.h.ah=0x0; - r.h.al=0x13; -//_asm int 0x10; - int86(0x10,&r,&r); - // 뢮 梥⭮ - for( j =1 ; j <319 ; j ++) - { color=color+1; - _AH=0x0c; - _AL=color; - if(color==256) color=0; - _BH=0; - _DX=50; - _CX=j; - geninterrupt(0x10); - } - getch(); - -//९ணࠬ஢ ⠡ - ii=clock(); - for( i = 0 ; i < 255 ; i++) - { _AH=0x10; - _AL=0x10; - _BX=i; // ॣ - _CH=i; /* G */ - _CL=i; /* B */ - _DH=i; /* R */ - geninterrupt(0x10); - } /* */ - color=256; - i=clock()-ii; - -// 뢮 ⮭ - for( j =1 ; j <319 ; j ++) /* */ - { color=color-1; - _AH=0x0c; - _AL=color; - if(color==0) color=256; - _BH=0; - _DX=100; // ப 뢮 - _CX=j; - geninterrupt(0x10); - } -// printf("६ ९ணࠬ஢ ⠡ : %d",i); - getch(); - -// -// 1 ⮭ 梥⮬ -// 2 뢥 ० אַ ࠡ -// ( ணࠬ 뢮 , 稭 a0000) -// 3 ६ 뢮 ९ணࠬ ⠡ ᯮ i=clock() -// 4 ਤ㬠 ࠪ , 뢥 ᪮쪮 -// 梥⮢ 쥢 横᪨ ९ணࠬ ⠡ - return; +/* Lab: Ass, BIOS and Ci functions + Шаблон программы для работы с видеосистемой Labv9 + Графические режимы + */ +#include +#include +#include +#include +#include + +#include ; + +union REGS r; + +void main() +{ +// Устан номера видеорежима + int j,i,ii,color=0; + r.h.ah=0x0; + r.h.al=0x13; +//_asm int 0x10; + int86(0x10,&r,&r); + // Вывод цветного клина + for( j =1 ; j <319 ; j ++) + { color=color+1; + _AH=0x0c; + _AL=color; + if(color==256) color=0; + _BH=0; + _DX=50; + _CX=j; + geninterrupt(0x10); + } + getch(); + +//Перепрограммирование таблицы палитры + ii=clock(); + for( i = 0 ; i < 255 ; i++) + { _AH=0x10; + _AL=0x10; + _BX=i; // Номер регистра + _CH=i; /* G */ + _CL=i; /* B */ + _DH=i; /* R */ + geninterrupt(0x10); + } /* */ + color=256; + i=clock()-ii; + +// Вывод полутонового клина + for( j =1 ; j <319 ; j ++) /* */ + { color=color-1; + _AH=0x0c; + _AL=color; + if(color==0) color=256; + _BH=0; + _DX=100; // строка вывода + _CX=j; + geninterrupt(0x10); + } +// printf("Время перепрограммирования табл палитр : %d",i); + getch(); + +// Задания +// 1 Подкрасьте полутоновой клин красным цветом +// 2 Выведите клин в режиме прямой работы с видео памятью +// (напишите Асс программу вывода возрастающ кода, начиная с a0000) +// 3 Измерьте время вывода и перепрограммир табл палитры используя i=clock() +// 4 Придумайте абстрактную анимацию, выведя несколько +// цветовых клиньев и циклически перепрограммируя табл палитры + return; } \ No newline at end of file diff --git a/Lab_asm.asm b/Lab_asm.asm index a50d677..008bdc1 100755 --- a/Lab_asm.asm +++ b/Lab_asm.asm @@ -2,16 +2,16 @@ .MODEL TINY .STACK 100h .DATA -Message DB 13,10,'Hi ! ',13,10,'$' +Message DB 13,10,'Hi Привет! ',13,10,'$' .CODE mov ax,@Data - mov ds,ax ; DS - ; , - ; - mov ah,9 ; DOS - mov dx,OFFSET Message ; "!" - int 21h ; "!" - mov ah,4ch ; DOS - ; - int 21h ; + mov ds,ax ; установить регистр DS таким + ; образом, чтобы он указывал + ; на сегмент данных + mov ah,9 ; функция DOS вывода строки + mov dx,OFFSET Message ; ссылка на сообщение "Привет!" + int 21h ; вывести "Привет!" на экран + mov ah,4ch ; функция DOS завершения + ; программы + int 21h ; завершить программу END \ No newline at end of file diff --git a/Labv1.cpp b/Labv1.cpp index 8c507b5..15fe234 100755 --- a/Labv1.cpp +++ b/Labv1.cpp @@ -1,226 +1,226 @@ -// ਬ ଫ ணࠬ - -// N 0 -// ७ ६ 믮 ࠣ ணࠬ -// 㤥 000.0 , , & -// - -#include -#include -#include -#include - -#define PortCan0 0x40 - - -void beep(unsigned iTone,unsigned iDlit); // ⨯ 㭪樨 - // 㪮 ᨣ, ᯮ㥬 ७ ६ - -void main(void) -{ - - //  ६ -long int lCnt=0; // 祩 - 稪 ७ -int iA=0x1234; // 㬬-祩, ᯮ㥬 ᫥㥬 - -/*************************************************************************\ -/* ᬮ ᮤন 䨧᪨ ᮬ */ - - // ᫨ ⨬ ᮤন ᮬ 0046h - //塞 far-㪠⥫ ६ ⨯ char 樠㥬 - // 㪠⥫ 祭 , ।⥫쭮 ८ࠧ - // ⨯ char * -char far * pT=(char *)0x46C; // (1) - printf ("\n ⠥ 10 ࠧ 祭 ᮬ \n"); - for (int i=0; i<10; i++) - printf (" \n %d ", * pT); // (1) - printf ("\n த \n"); - getch(); // ணࠬ - - -/******************************************\ -\* ᬮ ᮤন */ - -// ⠥ ᮤন ᮬ 40 㭪樨 - printf ("\n ⠥ ᮤন ᮬ 40 㭪樨 \n" ); - // 0.5 - printf ("\n 室 横 - \n" ); - - - while (bioskey(1)==0) // 㤥  - { - printf (" \n 40 = %d ", inp(PortCan0)); //(2) - // TD ᬮ, ॢ頥 - inp() - // ஢ 設 - delay(500); // প ᥪ㭤 (500 ) - } - getch(); // 頥 -/**************************************************************************\ - ਬ砭: * -㭪 printf (...) ᯥ ࠭ 祭 ६, * - ⠪ ந ⥪. * -㭪 bioskey(1) ।, * -㭪 inp(uPort) Port * -㭪 outp(uPort,iValue) 뢥 稭 iValue uPort * -㭪 delay(uTime) ࣠ ணࠬ প uTime ᥪ㭤 * -㭪 getch() 뢠 ᨬ . * - 砥 ⪨ * -\**************************************************************************/ - -// ⠥ ணࠬ ஥ ᥬ - printf ("\n ⠥ ᮤন ᮬ 40 ᥬ஬ \n" ); - - while (bioskey(1) == 0 ) // 横 㤥 , - // - - // ਬ ᯮ짮 ஥ ᥬ (3) - { - asm { push ax // ᯮᮡ ஥ ᥬ - in al,0x40 - } - - unsigned char Tmm = _AL; // ⭠ mov Tmm,al - // !! ⮬ TD - - asm pop ax // 㣮 ᯮᮡ ஥ ᥬ - delay (500); - printf (" \n 40 = %d ", Tmm ); - // ᫨ - 室 - } - getch(); - printf ("\n த - \n "); - getch(); - -/************************************************************* - ᬮ ᮤন (ਬ)塠⮢ - ६ 0046 c । */ - -long far * pTime=(long *)0x46C; // ⥫ 稪 ⨪ - while (bioskey(1) == 0) - { - printf ("\n %ld",*pTime); - delay(1000); - } - getch(); - // ⠥ ⠥ ᮤন 塠⮢ ६ - // 0046C ।⢠ ஥ ᥬ - int Time; - while (bioskey(1) == 0) - { - asm push ds // ࠭ 直 砩 ॣ - asm push si - // ஥ ᥬ - asm mov ax,40h // 뢠 hex-⠭ ⠪ ... - asm mov ds,ax - asm mov si,0x6C // ... ⠪ - asm mov ax,[ds:si] - asm mov Time,ax - asm pop si // ⥯ ⠭ ॣ - asm pop ds // ( ९⠩ 冷 !!!) - - printf ("\n %d",Time); - delay(300); - } - -/**************************************************************** - ਬ 믮 ⨯ - ॡ ६ 믮 - ( ਬ - mov reg,mem, ९⥫ - ) - - ७ ६ 믮 ࠣ ணࠬ */ - - beep(400,200); // ⬥砥 砫 ࢠ (5) - for ( lCnt=0; lCnt<1000000; lCnt++) - { -a1: asm { mov ax,iA - mov ax,iA - mov ax,iA - mov ax,iA - mov ax,iA - mov ax,iA - mov ax,iA - mov ax,iA - mov ax,iA -a2: mov ax,iA } - } - beep(400,200); // ⬥砥 ࢠ (5) -} - - // 㭪 㪮 ᨣ ⥫쭮 (5) -void beep(unsigned iTone,unsigned iDlit) -{ sound(iTone); - delay(iDlit); - nosound(); -} - -// 믮 -// ⨫ ணࠬ -// ࢮ ᪥ ⮪ ⪠ a1 a2 ஢ -// ६ 믮 ⠢ 3.15 +- 0.2 ᥪ㭤 ( 業 訡 -// ண ७ 5 ࠧ 뫮 業 । 祭 -// ।᪮ ⪫. ਢ ࠢ 2*) -// ஬ ᪥ ⮪ a1-a2 ࠡ⠫. ६ 믮 -// ⠢ 7.5 +- 0.2 ᥪ㭤. ⢮ ७ MOV REG,MEM -// ࠢ 10^7, ६ ࠢ 4.35 +- 0.3 ᥪ㭤, 業 ६ -// 믮 0.44 +- 0.03 . -// TD ।, ᯮ짮 -// ᬥ饭 [BP+disp] - -/* - 믮 ࠡ LAB0-0 - -1. ⠩ ⥪ ணࠬ 뤥 ᪨ 吝 , - , . ⥪, - , 㭪樨 ᯮ 祬. , - 짮 ⥪ Help' - -2. ணࠬ 㡥, 訡 - -3. ணࠬ,  १ 㡥, - - , ந室. - -4. , ᯮ ஥ ⫠稪 IDE: - 믮 ணࠬ 窨 ⠭. ஢ -室 -⥪ ᤥ, ᯮ 㭪 Run - Debug/Breakpoints. - ஢/ ᮤন ६ ᫥ ⠭. -ᯮ 㭪 Debug/Evaluate/Modify, -Debug/Inspect ( Alt/F4) Debug/Watches - ६ 믮 ९⥫ -⠪, ᤥ ணࠬ LAB0 MOV REG,MEM. - -5. ।⢠ ⫠稪 TD CPU (㭪 View/CPU) : - - / ᮤন ॣ஢ (㬠, - - ॣ ( - - ਢ ⠫ ଠ쭮 믮 - ணࠬ १⠬) - - / 祩 䨧᪨ ᮬ: - (०, 祬 㤠-, 뫮 㬠: - - ( ᯮ - - ணࠬ), , 䨧᪮ ன⢮, ᮮ- - 饥 ... -ਠ: - 1. 0x46C - 0x80000 - 0xF000:0xFFF0 - 2. 0x0040:0x6D - 0x8000:0x0010 - 0xFFFFE - 3. 0x41A - 0x80210 - 0xFFFF:0x100 - 4. 0x0040:0x1E - 0xD00000 - 0x8000:0x200 - 5. - 0x41A-0x43C - 0xD000:0x100 - 0xFFFF:0xE -- / ந /뢮 (ਬ: - 0x40 ᪮쪮 ࠧ - ஡ ᭨  १- - ; ᫮ 3 61 , ⮬ 㤠 ); - -6. । ᥬ ࠭᫨஢ 몠 - 横. ஢ ᥬ ᢮ ਠ 横. -ࠢ, १ ।⠢ ९⥫. -*/ +// Пример оформления программы + +// Работа N 0 +// Измерение времени выполнения фрагмента программы +// Студенты гр 000.0 Иванофф, Петрофф, & Сидорофф +// + +#include +#include +#include +#include + +#define PortCan0 0x40 + + +void beep(unsigned iTone,unsigned iDlit); // Это прототип функции + // звукового сигнала, используемой при измерении времени + +void main(void) +{ + + // Объявление переменных +long int lCnt=0; // Ячейка - счетчик повторений +int iA=0x1234; // Думми-ячейка, используемая в исследуемой команде + +/*************************************************************************\ +/* Как из Си посмотреть содержимое байта с известным физическим адресом */ + + // Если хотим напечатать содержимое байта с адресом 0046Сh + //объявляем far-указатель на переменную типа char и инициализируем + //этот указатель значением адреса, предварительно преобразовав + //его к типу char * +char far * pT=(char *)0x46C; // (1) + printf ("\n Печатаем 10 раз значение байта с известным адресом \n"); + for (int i=0; i<10; i++) + printf (" \n %d ", * pT); // (1) + printf ("\n Для продолжения нажмите любую клавишу \n"); + getch(); // Программа ждет нажатия клавиши + + +/******************************************\ +\* Как из Си посмотреть содержимое порта */ + +// Читаем содержимое порта с адресом 40 с помощью функции Си + printf ("\n Читаем содержимое порта с адресом 40 с помощью функции Си \n" ); + // Цикл повторяется каждые 0.5 с + printf ("\n Для выхода из цикла - нажмите любую клавишу \n" ); + + + while (bioskey(1)==0) // пока не будет нажата любая клавиша + { + printf (" \n Порт40 = %d ", inp(PortCan0)); //(2) + // С помощью TD посмотрите, во что превращается ф-ция inp() + // на уровне машинных команд + delay(500); // Задержка на полсекунды (500 мс) + } + getch(); // Очищаем буфер клавиатуры +/**************************************************************************\ + Примечания: * +Функция printf (...) позволяет распечатать на экране значения переменных, * + а также произвольный текст. * +Функция bioskey(1) позволяет определить, нажата ли клавиша * +Функция inp(uPort) позволяет считать байт из порта Port * +Функция outp(uPort,iValue) позволяет вывести величину iValue в порт uPort * +Функция delay(uTime) организует программную задержку на uTime миллисекунд * +Функция getch() считывает один символ из буфера клавиатуры. * + В данном случае это надо для очистки буфера клавиатуры * +\**************************************************************************/ + +// Снова читаем тот же порт с помощью программы на встроенном ассемблере + printf ("\n Читаем содержимое порта с адресом 40 ассемблером \n" ); + + while (bioskey(1) == 0 ) // Этот цикл будет повторяться, + // пока не нажмем клавишу + + // Примеры использования встроенного ассемблера (3) + { + asm { push ax // Один способ записи на встроенном ассемблере + in al,0x40 + } + + unsigned char Tmm = _AL; // Эта команда эквивалентна mov Tmm,al + // !! Убедитесь в этом с помощью TD + + asm pop ax // Другой способ записи на встроенном ассемблере + delay (500); + printf (" \n Порт40 = %d ", Tmm ); + // Если нажата клавиша - то выход + } + getch(); + printf ("\n Для продолжения - нажмите любую клавишу \n "); + getch(); + +/************************************************************* + Как посмотреть содержимое длинной (например)четырехбайтовой + переменной с адреса 0046С c помощью средств Си */ + +long far * pTime=(long *)0x46C; // Указатель на счетчик тиков + while (bioskey(1) == 0) + { + printf ("\n %ld",*pTime); + delay(1000); + } + getch(); + // Читаем и печатаем содержимое двухбайтовой переменной + // с адреса 0046C средствами встроенного ассемблера + int Time; + while (bioskey(1) == 0) + { + asm push ds // Сохраним на всякий случай регистры + asm push si + // Во встроенном ассемблере + asm mov ax,40h // можно записывать hex-константы так ... + asm mov ds,ax + asm mov si,0x6C // ... или так + asm mov ax,[ds:si] + asm mov Time,ax + asm pop si // А теперь восстановим регистры + asm pop ds // (не перепутайте порядок !!!) + + printf ("\n %d",Time); + delay(300); + } + +/**************************************************************** + Пример выполнения задания типа И + Требуется измерить время выполнения заданной команды + (в примере - команда mov reg,mem, а Вы спросите у преподавателя + какую команду Вам взять ) + + Измерение времени выполнения фрагмента программы */ + + beep(400,200); // Сигнал отмечает начало интервала (5) + for ( lCnt=0; lCnt<1000000; lCnt++) + { +a1: asm { mov ax,iA + mov ax,iA + mov ax,iA + mov ax,iA + mov ax,iA + mov ax,iA + mov ax,iA + mov ax,iA + mov ax,iA +a2: mov ax,iA } + } + beep(400,200); // Сигнал отмечает конец интервала (5) +} + + // Функция подачи звукового сигнала заданной высоты и длительности (5) +void beep(unsigned iTone,unsigned iDlit) +{ sound(iTone); + delay(iDlit); + nosound(); +} + +// Результаты выполнения +// Запустили программу дважды +// При первом пуске участок между метками a1 и a2 был закомментирован +// Время выполнения составило 3.15 +- 0.2 секунд (для оценки ошибки +// прогон был повторен 5 раз и было оценено среднее значение и +// среднеквадратическое отклонение. Приведенный допуск равен 2*СКО) +// При втором пуске участок a1-a2 работал. Время выполнения +// составило 7.5 +- 0.2 секунд. Количество повторений команды MOV REG,MEM +// равно 10^7, добавка времени равна 4.35 +- 0.3 секунд, оценка времени +// выполнения команды 0.44 +- 0.03 мкс. +// С помощью TD определили, что компилятор использовал адресацию +// базовая со смещением [BP+disp] + +/* + Задание на выполнение работы LAB0-0 + +1. Прочитайте текст программы и выделите логически связные части, + поймите, что делают эти части. Разбирая текст, обратите внимание на + то, какие функции Си используются и зачем. Делая это, научитесь + пользоваться контекстным Help'ом + +2. Скомпилируйте программу и убедитесь, что в ней отсутствуют ошибки + +3. Запустите программу, наблюдайте результат и убедитесь, что Вы пони- + маете, что происходит. + +4. Научитесь, используя встроенный отладчик IDE: + Выполнить программу до заданной точки останова. На уровне +исходного Си-текста это можно сделать, используя пункты меню Run +и Debug/Breakpoints. + Проверить/изменить содержимое переменных после останова. +Используйте пункт меню Debug/Evaluate/Modify, +Debug/Inspect (горячая клавиша Alt/F4) либо Debug/Watches + Измерить время выполнения заданной преподавателем команды +так, как это сделано в программе LAB0 с командой MOV REG,MEM. + +5. Средствами отладчика TD в окне CPU (пункт меню View/CPU) научитесь: + - наблюдать/изменять содержимое регистров процессора (подумайте, ка- + кие регистры можно менять безболезнено (изменения в некоторых ре- + гистрах могут привести к фатальным для нормального выполнения + программы результатам) + - наблюдать/изменять ячейку памяти с известным физическим адресом: + (Прежде, чем писать куда-либо, хорошо было бы подумать: что это за + адрес - адрес ОЗУ(не использует ли этот адрес еще какая-нибудь + программа), адрес ПЗУ, существует ли физическое устройство, соот- + ветствующее данному адресу... +Варианты: + 1. 0x46C + 0x80000 + 0xF000:0xFFF0 + 2. 0x0040:0x6D + 0x8000:0x0010 + 0xFFFFE + 3. 0x41A + 0x80210 + 0xFFFF:0x100 + 4. 0x0040:0x1E + 0xD00000 + 0x8000:0x200 + 5. область памяти - 0x41A-0x43C + 0xD000:0x100 + 0xFFFF:0xE +- читать/писать в произвольный порт ввода/вывода (например: считать + порт 0x40 несколько раз - попробуйте объяснить наблюдаемый резуль- + тат; записать число 3 в 61 порт, потом быстро записать туда нуль); + +6. Определите в какие команды Ассемблера оттранслирован с языка СИ +оператор цикла. Напишите на уровне Ассемблера свой вариант цикла. +Сравните, результаты представте преподавателю. +*/ diff --git a/Labv12.CPP b/Labv12.CPP index b0fe011..a3a8f81 100755 --- a/Labv12.CPP +++ b/Labv12.CPP @@ -1,87 +1,87 @@ -/* ஢ 䠩 - ୠ ࠡ 12 -*/ -#include -#include - -typedef unsigned int WORD; -typedef unsigned long DWORD; -struct BITMAPFILEHEADER { - WORD bfType; - DWORD bfSize; // 䠩 - WORD bfReserved1; - WORD bfReserved2; - DWORD bfOffBits; -}; -struct BITMAPINFOHEADER{ - DWORD biSize; - DWORD biWidth; - DWORD biHeight; - WORD biPlanes; - WORD biBitCount; // ⢮ ᥫ - DWORD biCompression; - DWORD biSizeImage; - DWORD biXPelsPerMeter; - DWORD biYPelsPerMeter; - DWORD biClrUsed; - DWORD biClrImportant; -}; - - -void main(int c,char **a) -{ - FILE *in, *out; - highvideo(); -BITMAPFILEHEADER bfh; -BITMAPINFOHEADER bih; -/* FILE *po; -if(argc==0) return 0; -if(argc==2) { mode=257;} else mode=atoi(argv[2]); -po=fopen(argv[1],"rb"); -fread(&bfh,14,1,po); -fread(&bih,40,1,po); -if(bih.biBitCount!=8) return 1; -if(bih.biClrUsed==0){ cmax=256; } -else cmax=bih.biClrUsed; -*/ -cputs("(c) Rex Software'99 Bmp Universal Invertor v1.0"); -normvideo(); -cputs(""); - - int n,bpp; - if (c!=2) - { - puts("\nNeeds some bmps"); - return ; - } - - in = fopen(a[1], "rb"); - if ((out = fopen("inversed.bmp", "wb"))== NULL) - { - puts("Cannot open output file"); return ; - } - cprintf("\n"); - cputs("Please wait"); - for (int i=0;i<54;i++) { - int c=fgetc(in); - fputc(c,out); - if (i==28) bpp=c;} - if (bpp==8) - { - for (i=0;i<1024;i++) fputc(255-fgetc(in),out); - - while (!feof(in)) fputc(fgetc(in),out); - } - if (bpp==24) - { for (int i=0;i<54;i++) fputc(fgetc(in),out); - while (!feof(in)) fputc(255-fgetc(in),out);} - - fcloseall(); - printf("\n%s is %d bit-per-pixel color depth bitmap\n",a[1],bpp); - puts("Successsfully retrieved to Inversed.bmp"); -} -/* -1. ணࠬ ਧ樨 ࠦ. -2. ணࠬ ஢ 室 䠩 (8 - 24 ) -易⥫쭮 ᯮ ஢. +/* Структура растрового ВМР файла + Лабораторная работа 12 +*/ +#include +#include + +typedef unsigned int WORD; +typedef unsigned long DWORD; +struct BITMAPFILEHEADER { + WORD bfType; + DWORD bfSize; // Размер файла + WORD bfReserved1; + WORD bfReserved2; + DWORD bfOffBits; +}; +struct BITMAPINFOHEADER{ + DWORD biSize; + DWORD biWidth; + DWORD biHeight; + WORD biPlanes; + WORD biBitCount; // Количество бит в пикселе + DWORD biCompression; + DWORD biSizeImage; + DWORD biXPelsPerMeter; + DWORD biYPelsPerMeter; + DWORD biClrUsed; + DWORD biClrImportant; +}; + + +void main(int c,char **a) +{ + FILE *in, *out; + highvideo(); +BITMAPFILEHEADER bfh; +BITMAPINFOHEADER bih; +/* FILE *po; +if(argc==0) return 0; +if(argc==2) { mode=257;} else mode=atoi(argv[2]); +po=fopen(argv[1],"rb"); +fread(&bfh,14,1,po); +fread(&bih,40,1,po); +if(bih.biBitCount!=8) return 1; +if(bih.biClrUsed==0){ cmax=256; } +else cmax=bih.biClrUsed; +*/ +cputs("(c) Rex Software'99 Bmp Universal Invertor v1.0"); +normvideo(); +cputs(""); + + int n,bpp; + if (c!=2) + { + puts("\nNeeds some bmps"); + return ; + } + + in = fopen(a[1], "rb"); + if ((out = fopen("inversed.bmp", "wb"))== NULL) + { + puts("Cannot open output file"); return ; + } + cprintf("\n"); + cputs("Please wait"); + for (int i=0;i<54;i++) { + int c=fgetc(in); + fputc(c,out); + if (i==28) bpp=c;} + if (bpp==8) + { + for (i=0;i<1024;i++) fputc(255-fgetc(in),out); + + while (!feof(in)) fputc(fgetc(in),out); + } + if (bpp==24) + { for (int i=0;i<54;i++) fputc(fgetc(in),out); + while (!feof(in)) fputc(255-fgetc(in),out);} + + fcloseall(); + printf("\n%s is %d bit-per-pixel color depth bitmap\n",a[1],bpp); + puts("Successsfully retrieved to Inversed.bmp"); +} +/* Задание +1. Напишите программу бинаризации изображения. +2. Напишите программу тестирования входного файла (8 - 24 бита) +обязательно используйте структуры для тестирования. */ \ No newline at end of file diff --git a/Labv13.cpp b/Labv13.cpp index 3ec4bfb..e28f3a9 100755 --- a/Labv13.cpp +++ b/Labv13.cpp @@ -1,175 +1,175 @@ -/* ୠ ࠡ 13 - , ᪨ ० sVGA, VESA -*/ -#include -#include -#include -#include -#define LOWORD(l) ((int)(1)) -#define HIWORD(l) ((int)((l) >> 16)) -#define MYMODE1 113h //800x600x32k -#define MYMODE2 101h //640x480x256 -#define MYMODE3 105h //1024x768x256 - - int pattern_ust=1; - int current_b=0; - -/* struct Vesainfo { - int attr_m; - char attr_a; - char attr_b; - int h_ust; - int size; - unsigned segm_a; - unsigned segm_b; - void far (*fun)(); - int byte_str; - int resx; - int resy; - char xchsize; - char ychsize; - char kolvo; - char bit_pix; - char kolvobank; - char memmod; - char size_bank; - char pages; - char reserved; - char red_mask_s; - char red_mask_p; - char green_mask_s; - char green_mask_p; - char blue_mask_s; - char blue_mask_p; - char reserved_mask_s; - char reserved_mask_p; - char colour_info; - char reserved2[216]; - }mine; */ - - -struct SvgaModeInfo -{ - unsigned state; - char a_window_state; - char b_window_state; - unsigned window_multiplicity; - unsigned window_size; - unsigned a_window_segment; - unsigned b_window_segment; - void far (*fun)(); - unsigned string_width; - unsigned width; - unsigned height; - char symbol_height; - char symbol_width; - char switches_count; - char bits_per_pixel; - char banks_count; - char memory_model; - char bank_size; - char pages_count; - char reserved1; - char red_mask; - char red_bit; - char green_mask; - char green_bit; - char blue_mask; - char blue_bit; - char reserved_mask; - char reserved_bit; - char palette_state; - char lfb[10]; - char resrved2[206]; -}mine; - -void Bank_ust(int begin) -{ - if (begin==current_b) - return; - current_b=begin; - begin *= pattern_ust; - asm{ - mov ax,4F05h - mov bx,0 - mov dx,begin - push dx - int 10h - pop dx - mov bx,1 - int 10h - }; -} - -inline int RGBcolour(int red,int green,int blue) -{ - return ((red >> 3)<<10) | ((green >> 3)<<5) | (blue >> 3); -} -void set_text_mode() -{ - asm mov ax,0x0003 - asm int 0x10 -} -void draw(int x,int y,int colour) -{ - long ttt; - asm{ - mov dx,y //bank number - shr dx,6 - mov bx,0 - }; - mine.fun(); - ttt = (y*1024%65536)+x; - _SI = (unsigned int)ttt; - asm{ - mov ax,colour - mov bx,0xA000 - mov es,bx - mov es:[si],al - }; -} - -void paint(int begx,int begy,int endx,int endy,int colour) -{ - int x,y; - for(y=begy;y<=endy;y++) - for(x=begx;x<=endx;x++) - draw(x,y,colour); - -} -void main() -{ - int colour,x,y; - asm{ - //information - mov cx,MYMODE3 - lea di,mine - mov ax,ds - mov es,ax - - mov ax,0x4F01 - - int 10h - }; - asm{ //setting of this mode - mov ax,4F02h - mov bx,MYMODE3 - int 10h - }; - x=0; - y=0; - for(colour=1;colour<255;colour++){ - if(x>1024){ - x=0; - y=y+48; - } - paint(x,y,x+64,y+48,colour); - x=x+64; - } - getch(); - set_text_mode(); -} -// -// 1. 뢥 ⮭ 2 . -// 2. । ᯮ ࠭. +/* Лабораторная работа 13 + Видеоадаптер, графические режимы sVGA, VESA +*/ +#include +#include +#include +#include +#define LOWORD(l) ((int)(1)) +#define HIWORD(l) ((int)((l) >> 16)) +#define MYMODE1 113h //800x600x32k +#define MYMODE2 101h //640x480x256 +#define MYMODE3 105h //1024x768x256 + + int pattern_ust=1; + int current_b=0; + +/* struct Vesainfo { + int attr_m; + char attr_a; + char attr_b; + int h_ust; + int size; + unsigned segm_a; + unsigned segm_b; + void far (*fun)(); + int byte_str; + int resx; + int resy; + char xchsize; + char ychsize; + char kolvo; + char bit_pix; + char kolvobank; + char memmod; + char size_bank; + char pages; + char reserved; + char red_mask_s; + char red_mask_p; + char green_mask_s; + char green_mask_p; + char blue_mask_s; + char blue_mask_p; + char reserved_mask_s; + char reserved_mask_p; + char colour_info; + char reserved2[216]; + }mine; */ + + +struct SvgaModeInfo +{ + unsigned state; + char a_window_state; + char b_window_state; + unsigned window_multiplicity; + unsigned window_size; + unsigned a_window_segment; + unsigned b_window_segment; + void far (*fun)(); + unsigned string_width; + unsigned width; + unsigned height; + char symbol_height; + char symbol_width; + char switches_count; + char bits_per_pixel; + char banks_count; + char memory_model; + char bank_size; + char pages_count; + char reserved1; + char red_mask; + char red_bit; + char green_mask; + char green_bit; + char blue_mask; + char blue_bit; + char reserved_mask; + char reserved_bit; + char palette_state; + char lfb[10]; + char resrved2[206]; +}mine; + +void Bank_ust(int begin) +{ + if (begin==current_b) + return; + current_b=begin; + begin *= pattern_ust; + asm{ + mov ax,4F05h + mov bx,0 + mov dx,begin + push dx + int 10h + pop dx + mov bx,1 + int 10h + }; +} + +inline int RGBcolour(int red,int green,int blue) +{ + return ((red >> 3)<<10) | ((green >> 3)<<5) | (blue >> 3); +} +void set_text_mode() +{ + asm mov ax,0x0003 + asm int 0x10 +} +void draw(int x,int y,int colour) +{ + long ttt; + asm{ + mov dx,y //bank number + shr dx,6 + mov bx,0 + }; + mine.fun(); + ttt = (y*1024%65536)+x; + _SI = (unsigned int)ttt; + asm{ + mov ax,colour + mov bx,0xA000 + mov es,bx + mov es:[si],al + }; +} + +void paint(int begx,int begy,int endx,int endy,int colour) +{ + int x,y; + for(y=begy;y<=endy;y++) + for(x=begx;x<=endx;x++) + draw(x,y,colour); + +} +void main() +{ + int colour,x,y; + asm{ + //information + mov cx,MYMODE3 + lea di,mine + mov ax,ds + mov es,ax + + mov ax,0x4F01 + + int 10h + }; + asm{ //setting of this mode + mov ax,4F02h + mov bx,MYMODE3 + int 10h + }; + x=0; + y=0; + for(colour=1;colour<255;colour++){ + if(x>1024){ + x=0; + y=y+48; + } + paint(x,y,x+64,y+48,colour); + x=x+64; + } + getch(); + set_text_mode(); +} +// Задание +// 1. Выведите полутоновой клин во 2 банке памяти. +// 2. Определите как располагаются банки памяти на экране. // \ No newline at end of file diff --git a/Labv14.cpp b/Labv14.cpp index 14dc1da..5b58a24 100755 --- a/Labv14.cpp +++ b/Labv14.cpp @@ -1,184 +1,184 @@ -/* ୠ ࠡ 14 - ꥤ ࠫ쭮 믮 - (⨬ ஢ ) - */ - -#include -#include -void NullProc(void){} -void ExTime(void (*PP)(void)) -{ - long far* pTime = (long*)0x46C; //稪 ⨪ - long Time0, Time1, Time2, i; - - void (*NP)(void); - NP = NullProc; - Time0 = *pTime; - for (i = 1; i<1000000L; i++) - { - NP(); - NP(); - NP(); - NP(); - NP(); - NP(); - NP(); - NP(); - NP(); - NP(); - } - Time1 = *pTime; - for (i = 1; i<1000000L; i++) - { - PP(); - PP(); - PP(); - PP(); - PP(); - PP(); - PP(); - PP(); - PP(); - PP(); - } - Time2 = *pTime; - Time2 = (((Time2 - Time1) - (Time1 - Time0))*(6553500L/1193180L)); - printf("%ld \n",Time2); -} -void P1(void) //ॣ஢ ᨬ -{ - asm{ - mov ax,bx - mov dx,ax - stc - adc bx,cx - stc - sbb dx,ax - - add ax,bx - mov cx,ax - sub dx,bx - mov bx,dx - } -} -void P2(void) //ॣ஢ ᨬ ࠭ -{ - asm{ - - - } -} -void P3(void) //㣨 稭 ᯠ७ -{ - asm{ - mov cl,3 //।⢥ ࠭ - inc bx - mov cl,3 - dec bx - mov cl,3 - inc bx - mov cl,3 - dec bx - - inc bx // ᤢ cl ⢥ 稪 - ror ax,cl - dec bx - rol ax,cl - - inc dx // 䨪ᠬ . . U - - mov ax,ds:[bx] - mov ax,ss:[bx] - mov ax,es:[bx] - mov ax,cs:[bx] - mov cl,3 - mov cl,3 - mov cl,3 - dec dx - - inc dx // ᤢ . . U - - ror ax,1 - rol ax,1 - dec dx - } -} -void P4(void) //稭 ᯠ७ ࠭ -{ - asm{ - - } -} -void main(void) -{ - clrscr(); - printf("Program1 - ॣ஢ ᨬ \n"); - ExTime(P1); - printf("Program2 - ॣ஢ ᨬ ࠭\n"); - ExTime(P2); - printf("Program3 - 㣨 稭 ᯠ७\n"); - ExTime(P3); - printf("Program4 - 稭 ᯠ७ ࠭\n"); - ExTime(P4); - getch(); -} - -// -// 1. ࠭ 稭 ᯠ७ . -// 2. । ᭨ ६ 믮 ࠣ⮢ ணࠬ. -// -/* - Pentium 믮 -⠪. 믮 ६ - 㤮⢮ ᫥騬 ᫮: - -- 易 <묨> ᫥, । -; -- ॣ஢ ᨬ⥩ ⨯ ⥭- ᫥- - -᫥- (read-after-write or write-after-wnte) , -- ᮤঠ ᬥ饭 (displacement) -।⢥ ࠭; -- 䨪ᠬ ( ᪫祭 OF 室 JCC) - ⮫쪮 U-. - 묨 , ࠢ -믮 ⢫ ⭮, ᯮ짮 -ப, ॠ ⠪. ᪫祭  - ALU mem, reg ALU reg, mem, ॡ騥 ⠪⮢ -믮 ᮮ⢥⢥. 樠 ।⢠ -ᯮ 믮 . 騥 -楫᫥ ᬠਢ ⢥ -ᯠ७: --mov reg, reg/mem/imnl --mov mem, reg/imm ( ।) ; --alu reg, reg/mero/imm ( 䬥᪨ -- alu meln , reg/ imm ᪨ 権) ; -- inc reg/mem ( ६, -- dec reg/mem (६) ; --push reg/mem ( 饭 -- pop reg ( ⥪ ) ; --lea reg,mem ( 㧪 ᥣ ॣ஢) ; --jmp/call/jcc near ( । ࠢ) ; --n ( ) . - ᫮ ᫮ । ࠢ -6쥤 , ᫨ ⢥ . - ᯠ७ ᫥饩 ᫥⥫쭮 . - SHIFT/ROT ᤢ ࠧ SHIFT ந쭮 -᫮ ࠧ冷 ᯠਢ ⮫쪮 ( ). - ஢ ᨬ - ஢ ᨬ, 騥 ᯠਢ , - ᨬ १ ॣ 䫠, 㪠 . - ᨬ⥩ ஢ -⨯ 樠権: RAR - "⥭ ᫥ ⥭", WAR - " ᫥ ⥭" -WAW - " ᫥ ", RAW - "⥭ ᫥ ". -ᨬ⥩ ࠭. RAR, , -ᮮ⢥ ⢨ ᨬ⥩, ᪮ 砥 冷 -믮 祭. ⢨⥫쭮 ᨬ  -⮫쪮 "⥭ ᫥ " (RAW), ⠪ 室 -।⥫쭮 ᠭ , . - 譨 ᨬ  १ " ᫥ -⥭" (WAR) " ᫥ " (WAW). ᨬ WAR ⮨ -⮬, 祭 祩 ॣ, - ந ⥭. 譨 ᨬ  - ᪮쪨 稭: ⨬஢ ணࠬ , ࠭祭 -⢠ ॣ஢, ६ , 稥 ணࠬ -横. - -*/ +/* Лабораторная работа 14 + Объединение команд для их параллельного выполнения + (оптимизация уровня команд) + */ + +#include +#include +void NullProc(void){} +void ExTime(void (*PP)(void)) +{ + long far* pTime = (long*)0x46C; //счетчик тиков + long Time0, Time1, Time2, i; + + void (*NP)(void); + NP = NullProc; + Time0 = *pTime; + for (i = 1; i<1000000L; i++) + { + NP(); + NP(); + NP(); + NP(); + NP(); + NP(); + NP(); + NP(); + NP(); + NP(); + } + Time1 = *pTime; + for (i = 1; i<1000000L; i++) + { + PP(); + PP(); + PP(); + PP(); + PP(); + PP(); + PP(); + PP(); + PP(); + PP(); + } + Time2 = *pTime; + Time2 = (((Time2 - Time1) - (Time1 - Time0))*(6553500L/1193180L)); + printf("%ld нс\n",Time2); +} +void P1(void) //регистровые зависимости имеются +{ + asm{ + mov ax,bx + mov dx,ax + stc + adc bx,cx + stc + sbb dx,ax + + add ax,bx + mov cx,ax + sub dx,bx + mov bx,dx + } +} +void P2(void) //регистровые зависимости устранены +{ + asm{ + + + } +} +void P3(void) //другие причины неспаренности +{ + asm{ + mov cl,3 //непосредственный операнд + inc bx + mov cl,3 + dec bx + mov cl,3 + inc bx + mov cl,3 + dec bx + + inc bx //команды сдвига с cl в качестве счетчика + ror ax,cl + dec bx + rol ax,cl + + inc dx //команды с префиксами м. б. в U - конвейере + mov ax,ds:[bx] + mov ax,ss:[bx] + mov ax,es:[bx] + mov ax,cs:[bx] + mov cl,3 + mov cl,3 + mov cl,3 + dec dx + + inc dx //команды сдвига м. б. в U - конвейере + ror ax,1 + rol ax,1 + dec dx + } +} +void P4(void) //причины неспаренности устранены +{ + asm{ + + } +} +void main(void) +{ + clrscr(); + printf("Program1 - регистровые зависимости имеются\n"); + ExTime(P1); + printf("Program2 - регистровые зависимости устранены\n"); + ExTime(P2); + printf("Program3 - другие причины неспаренности\n"); + ExTime(P3); + printf("Program4 - причины неспаренности устранены\n"); + ExTime(P4); + getch(); +} + +//Задание +// 1. Устраните причины неспаренности команд. +// 2. Определите и объясните время выполнения фрагментов программ. +// +/* ПРАВИЛА ОБЪЕДИНЕНИЯ КОМАНД +Процессор Pentium может выполнять одну или две команды в каждом +такте. Для выполнения в процессоре одновременно двух команд они +должны удовлетворять следующим условиям: + +-обе команды в паре обязаны быть <простыми> в смысле, определенном +ниже; +-между ними не должно быть регистровых зависимостей типа чтение- после- +записи или запись-после-записи (read-after-write or write-after-wnte) , +-ни одна из команд не может содержать смещение (displacement) и +непосредственный операнд; +-команды с префиксами (за исключением OF в командах перехода JCC) +могут встречаться только в U-конвейере. + Под простыми командами понимаются команды, управление +выполнением которых осуществляется аппаратно, без использования +микрокоманд, и которые реализуются за один такт. Исключением являются +команды ALU mem, reg и ALU reg, mem, требующие трех и двух тактов для +выполнения соответственно. Специальные аппаратные средства +используются для их выполнения как простых команд. Следующие +целочисленные команды рассматриваются в качестве простых и могут быть +спарены: +-mov reg, reg/mem/imnl +-mov mem, reg/imm (команды передачи) ; +-alu reg, reg/mero/imm (команды арифметических +- alu meln , reg/ imm и логических операций) ; +- inc reg/mem (команды инкремента, +- dec reg/mem (декремента) ; +-push reg/mem (команды обращения +- pop reg (к стековой памяти) ; +-lea reg,mem (команды загрузки сегментных регистров) ; +-jmp/call/jcc near (команды передачи управления) ; +-nор (пустая команда) . + Команды безусловной и условной передач управления могут +о6ьединяться в пары, если они встречаются в качестве вторых команд в паре. +Они не могут быть спарены со следующей последовательной командой. Также +команды SHIFT/ROT со сдвигом на один разряд и SHIFT на произвольное +число разрядов могут спариваться только как первые ( команды в паре). + Регистровые зависимости + Регистровые зависимости, запрещающие спаривание команд, включают +неявные зависимости через регистры или флаги, не указанные в команде. +Все виды зависимостей по данным могут быть классифицированы по +типу ассоциаций: RAR - "чтение после чтения", WAR - "запись после чтения" и +WAW - "запись после записи", RAW - "чтение после записи". Некоторые из +зависимостей по данным могут быть устранены. RAR, по сути дела, +соответствует отсутствию зависимостей, поскольку в данном случае порядок +выполнения команд не имеет значения. Действительной зависимостью является +только "чтение после записи" (RAW), так как необходимо прочитать +предварительно записанные новые данные, а не старые. + Лишние зависимости по данным появляются в результате "записи после +чтения" (WAR) и "записи после записи" (WAW). Зависимость WAR состоит в +том, что команда должна записать новое значение в ячейку памяти или регистр, +из которых должно быть произведено чтение. Лишние зависимости появляются +по нескольким причинам: не оптимизированный программный код, ограничение +количества регистров, стремление к экономии памяти, наличие программных +циклов. + +*/ diff --git a/Labv15.cpp b/Labv15.cpp index c71a30e..9a6e742 100755 --- a/Labv15.cpp +++ b/Labv15.cpp @@ -1,256 +1,256 @@ -/* ୠ ࠡ 15 - Saund Blaster - FM ᨭ⥧ - -1. நࠩ , 맮 ᯥ䥪 -2. ࠩ -*/ -#include -#include -#include -#include -#include -#include - -#define KEYON 0x20 // key-on bit in regs b0 - b8 -#define FM 8 // SB (mono) ports (e.g. 228H and 229H) - -unsigned IOport=544; // Sound Blaster port address - -void mydelay(unsigned long clocks) -// time = clocks / 2386360 -{ - unsigned long elapsed=0; - unsigned int last,next,ncopy,diff; - - /* Read the counter value. */ - outp(0x43,0); /* want to read timer 0 */ - last=inp(0x40); /* low byte */ - last=~((inp(0x40)<< 8) + last); /* high byte */ - - do { - /* Read the counter value. */ - outp(0x43,0); /* want to read timer 0 */ - next=inp(0x40); /* low byte */ - ncopy=next=~((inp(0x40)<< 8) + next); /* high byte */ - - next-=last; /* this is now number of elapsed clock pulses since last read */ - - elapsed += next; /* add to total elapsed clock pulses */ - last=ncopy; - } while (elapsed> 8) & 0x3) + (block << 2) | KEYON); - getche(); - } - - - /***************************************************************** - * Generate a range of frequencies by changing frequency number. * - *****************************************************************/ - - printf("Range of frequencies created by changing frequency number.\n"); - block=4; - for (fn=0; fn<1024; fn++) { - fm(0xA0,(fn & 0xFF)); - fm(0xB0,((fn >> 8) & 0x3) + (block << 2) | KEYON); - delay(1); - } - - /********************************* - * Attenuate the signal by 3 dB. * - *********************************/ - - getche(); - fm(0xB0,((fn >> 8) & 0x3) + (block << 2) | KEYON); - printf("Attenuated by 3 dB.\n"); - fm(0x43,4); /* attenuate by 3 dB */ - getche(); - - fm(0xB0,((fn >> 8) & 0x3) + (block << 2)); - - exit(0); -} - - -unsigned int x; -FILE *fp; -char buf,key; -unsigned long playtime,showtime; -unsigned char gstring[80]; - - -int main ( int argc, char *argv[] ) -{ -//---------------- -// Initialize DSP for Voice -//------------- - outportb(0x0226,0x01); - delay(3); - outportb(0x0226,0x00); - for(x=0;x<100;x++) - { - if(inportb(0x022E)&0x80) - { - if(inportb(0x022A)==0xAA) break; - } - } - if(x==100) - { - printf("Sound Blaster not found at 0220h\n"); - exit(1); - } -//------------ -// Menu -//----------------- - clrscr(); - printf("1) Play original\n2) Play reduced\n3) FM Synth\n4) Exit\n"); - key=getch(); - if (key=='4') exit(0); - if (key=='3') midimain(); -//------------ -// Read file & play -//----------------- - clrscr(); - printf("Program compiled for Sound Blaster ver. 1.0 (8bit 44100Hz mono).\n\n"); - if (key=='1') printf("Normal play.\n"); - if (key=='2') printf("Reduced play.\n"); - printf("Playing .wav ...\n\n"); - if(argc==1) - { - printf(".WAV file not specified\n"); - exit(1); - } - strcpy(gstring,argv[1]); - strcat(gstring,".WAV"); - if((fp=fopen(gstring,"rb"))==0) - { - strcpy(gstring,argv[1]); - if((fp=fopen(gstring,"rb"))==0) - { - printf("Error opening .WAV file [%s]\n",argv[1]); - exit(1); - } - } - printf("FILE: [%s]\n",gstring); - fseek(fp,36L,SEEK_SET); - while (inportb(0x022C)&0x80); - outdsp(0xD1); //speaker on - playtime=0; - while (fread(&buf,1,1,fp)!=0) - { - if(key=='2') fread(&buf,1,1,fp); - if(key=='2') mydelay(15); - if(key=='2') playtime++; - if(key=='2') showtime=playtime/100000; - if(key=='2') if (showtime*100000== playtime) printf("Time: %u \r",showtime); - outdsp(0x10); - outdsp(buf); - mydelay(15); - playtime++; - showtime=playtime/100000; - if (showtime*100000== playtime) printf("Time: %u r",showtime); - - } - outdsp(0xD3); //speaker off - fclose(fp); - return 0; -}; +/* Лабораторная работа 15 + Saund Blaster + FM синтез +Задание +1. Проиграйте гамму, вызовите спецэффекты +2. Сыграйте мелодию +*/ +#include +#include +#include +#include +#include +#include + +#define KEYON 0x20 // key-on bit in regs b0 - b8 +#define FM 8 // SB (mono) ports (e.g. 228H and 229H) + +unsigned IOport=544; // Sound Blaster port address + +void mydelay(unsigned long clocks) +// time = clocks / 2386360 +{ + unsigned long elapsed=0; + unsigned int last,next,ncopy,diff; + + /* Read the counter value. */ + outp(0x43,0); /* want to read timer 0 */ + last=inp(0x40); /* low byte */ + last=~((inp(0x40)<< 8) + last); /* high byte */ + + do { + /* Read the counter value. */ + outp(0x43,0); /* want to read timer 0 */ + next=inp(0x40); /* low byte */ + ncopy=next=~((inp(0x40)<< 8) + next); /* high byte */ + + next-=last; /* this is now number of elapsed clock pulses since last read */ + + elapsed += next; /* add to total elapsed clock pulses */ + last=ncopy; + } while (elapsed> 8) & 0x3) + (block << 2) | KEYON); + getche(); + } + + + /***************************************************************** + * Generate a range of frequencies by changing frequency number. * + *****************************************************************/ + + printf("Range of frequencies created by changing frequency number.\n"); + block=4; + for (fn=0; fn<1024; fn++) { + fm(0xA0,(fn & 0xFF)); + fm(0xB0,((fn >> 8) & 0x3) + (block << 2) | KEYON); + delay(1); + } + + /********************************* + * Attenuate the signal by 3 dB. * + *********************************/ + + getche(); + fm(0xB0,((fn >> 8) & 0x3) + (block << 2) | KEYON); + printf("Attenuated by 3 dB.\n"); + fm(0x43,4); /* attenuate by 3 dB */ + getche(); + + fm(0xB0,((fn >> 8) & 0x3) + (block << 2)); + + exit(0); +} + + +unsigned int x; +FILE *fp; +char buf,key; +unsigned long playtime,showtime; +unsigned char gstring[80]; + + +int main ( int argc, char *argv[] ) +{ +//---------------- +// Initialize DSP for Voice +//------------- + outportb(0x0226,0x01); + delay(3); + outportb(0x0226,0x00); + for(x=0;x<100;x++) + { + if(inportb(0x022E)&0x80) + { + if(inportb(0x022A)==0xAA) break; + } + } + if(x==100) + { + printf("Sound Blaster not found at 0220h\n"); + exit(1); + } +//------------ +// Menu +//----------------- + clrscr(); + printf("1) Play original\n2) Play reduced\n3) FM Synth\n4) Exit\n"); + key=getch(); + if (key=='4') exit(0); + if (key=='3') midimain(); +//------------ +// Read file & play +//----------------- + clrscr(); + printf("Program compiled for Sound Blaster ver. 1.0 (8bit 44100Hz mono).\n\n"); + if (key=='1') printf("Normal play.\n"); + if (key=='2') printf("Reduced play.\n"); + printf("Playing .wav ...\n\n"); + if(argc==1) + { + printf(".WAV file not specified\n"); + exit(1); + } + strcpy(gstring,argv[1]); + strcat(gstring,".WAV"); + if((fp=fopen(gstring,"rb"))==0) + { + strcpy(gstring,argv[1]); + if((fp=fopen(gstring,"rb"))==0) + { + printf("Error opening .WAV file [%s]\n",argv[1]); + exit(1); + } + } + printf("FILE: [%s]\n",gstring); + fseek(fp,36L,SEEK_SET); + while (inportb(0x022C)&0x80); + outdsp(0xD1); //speaker on + playtime=0; + while (fread(&buf,1,1,fp)!=0) + { + if(key=='2') fread(&buf,1,1,fp); + if(key=='2') mydelay(15); + if(key=='2') playtime++; + if(key=='2') showtime=playtime/100000; + if(key=='2') if (showtime*100000== playtime) printf("Time: %u \r",showtime); + outdsp(0x10); + outdsp(buf); + mydelay(15); + playtime++; + showtime=playtime/100000; + if (showtime*100000== playtime) printf("Time: %u r",showtime); + + } + outdsp(0xD3); //speaker off + fclose(fp); + return 0; +}; diff --git a/Labv2.cpp b/Labv2.cpp index 5724f10..cceb41d 100755 --- a/Labv2.cpp +++ b/Labv2.cpp @@ -1,289 +1,289 @@ -// ணࠬ ࠡ LAB2 -// 祭 ⥬ - -#include -#include - -int main (void) -{ int aa; - - clrscr(); -/* -******************************************************** - 1 2 3 ணࠬ, 騥 ࠡ ᫥ : - -1. JL. - JL metka. - ⢫ 室 㪠 , - ᫨ १ ।饣 ࠢ: - (室 ⢫, ᫨ 䫠 SF=0 OF =0) - - asm { - cmp ax, 13 - JL metka - ..... ; - - - metka: - ...... ; - - }; - -2. ROL - Rol ax, 1 - Rol bx, cl - - 横᪮ ᤢ . - ᫨ ன ࠭ - CL, ᫮ ࠧ冷, - ⢫ ᤢ, । ᮤন ॣ CL. - -3. LEA. - ⮩ ண ࠭ । ॣ - ࢮ ࠭. - lea ax, a; - -4. NOP - 樨 - -5. AND - and ax,bx - ᪮ 㬭 - ࠭ 㬭 () ன - १ */ -/* -******************************************************** - 4 ணࠬ ப묨 - MOVS. - 뫪 ப. - ࠢ 뫪 । 祭 䫠 DF - 䫠 ࠢ. - - 権 ⠬ - MOVSB - 権 ᫮ - MOVSW - - ࠭. 䫠. - - 뫠 , 㥬 ॣ஬ SI - sourse - , 㥬 ॣ஬ DI - destination. - - */ -// ਢ ਬ ணࠬ - int A[10]={2,1,2,3,4,5,6,7,8,9}; - int B[10]={1,1,0,0,0,0,0,0,0,0}; - - asm { - cld //뢠 䫠 ࠢ - lea si,A - lea di,B -// mov dx,di - }; -// : ᯥ⠩ 祭 ॣ஢ -// । -// printf ("\n 祭 ॣ஢ is, di = %x %x ", _SI, _DI); - asm mov cx,1 ; // ???? - asm movsb ; // ????? - -// : ᯥ⠩ 祭 ॣ஢ -// ᫥ । । 諠? 쪮 ᫮ ।? - -printf ("\n 祭 ॣ஢ is, di = %x %x ", _SI, _DI); - printf ("\n 뢮 ᨢ ᫥ ப ।"); - for (int i=0; i<10; i++) - { - printf (" \n %d ", B[i]); - } - - getch(); - -//******************************************************** -// 5 ணࠬ ᪠ ᨬ - printf (" \n ᨬ "); -/* asm - asm -e1: asm { - mov ax, 0xb800 - mov es, ax - mov - cmp es:[di],al - jnz e2 }; - printf (" \n 諨 ᨬ "); -e2: asm add di, 2 - asm loop e1 - printf (" \n 諨 ᨬ "); - getch(); - - */ -// return (0); -//***************** ****************** -// -// 1 ந ணࠬ 㪠 -// 2 ᬮ -// 3 ⠡, ᯮ TD. ⢮ -// ଠ . -/* - 䨪 ⡠ 饭 .࠭ - 樨 - Ĵ - 1 and ax,bx - - - - 2 rep and bx,ax - 3 add ax,16 - - - 4 add al,[bx+si] -*/ - -// 4. ணࠬ ப묨 10 । -// 5. ࠡ⠩ -奬 ணࠬ -// ᪠ ᨬ 4- ࠭ -// 6. ⢥ : 宯࠭ 00FF. -// 믮 LDS BX,PtriA - -/* - - _ i8086 - - ணࠬ ஢ 㯭 ୠ ॣ- -஢. 㤮 ࠧ 㯯: 1) , 2)- -, 3)ᥣ 4)㪠⥫ ॣ 䫠(ਧ- -). -1) ( 뢠 ॣࠬ 饣 - 祭). ࠭ ॣ ᫮ ⠪ - . ᫨ ࠭ - , 㪠  - ॣ. , 㭪樨 ⤥ ॣ஢ - ᯥ樠஢ (.⠡.) -2) ⥫ ॣ ( ॣ, ᯮ - ࠭ 16-ࠧ來 ᮢ). ॣ - ⠪ ᯥ樠஢ (.⠡.) -3) ॣ (㪠뢠 砫 ᥣ⮢ - ⪮ - 64 1 : ᥣ CS, ᥣ ⥪ SS - ᥣ - DS ES extra) -4) ⥫ ॣ 䫠 - - 樠 㭪樨 ॣ஢ 8086 - -AX , -뢮 ᫮ -AL () , -뢮 ⮢ -AH () ⮢ -BX ॣ, ८ࠧ (?) -CX 稪 樨 楯窠, 横 -CL 稪 () ᪨ ᤢ 樨 -DX ᫮, - ᢥ -뢮 -SP ⥫ ⥪ ⥪ 樨 -BP ⥫ ॣ -SI 筨 樨 楯窠, ॣ -DI ⥫ 樨 楯窠, - - _ 䫠 - - 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 - Ĵ - OF DF IF TF SF ZF AF PF CF - - CF ( Carry Flag ) - 䫠 ७; - PF ( Parity Flag ) - 䫠 ⭮; - AF ( Auxiliary Carry Flag ) - 䫠 ᯮ⥫쭮 ७; - ZF ( Zero Flag ) - 䫠 ; - SF ( Sign Flag ) - 䫠 ; - TF ( Trap Flag ) - 䫠 誨; - IF ( Interrupt-Enable Flag ) - 䫠 ࠧ襭 뢠; - DF ( Direction Flag ) - 䫠 ࠢ; - OF ( Overflow Flag ) - 䫠 ९. - - - - - - - 5 - - - _࣠ - - 㥬 (᭮ ࠭⢮) ।⠢ ᮡ - 1 ( ॠ쭮 ० ࠡ ய஢ -i80286 ). ᬥ ࠧ ᫮. ᮬ ᫮ -⠥ 襣 . 8086 뢠 ଠ - 16 .᫮, 稭騬 ᮢ, - ᫮ ᯮ  . - ᪨ 20 , - -뢠 ॣ 稭 16 . ନ- -஢ 䨧᪨ ᮢ ᯮ 堭 ᥣ樨 - -. ࠭⢮ 1 㯭 १ 4 "" -(ᥣ) ࠧ஬ 64 . 砫 ᥣ- - ᮤন  ᥣ ॣ஢. - ⠬ ᫮ । ᥣ⮢, ᯮ ⭮- -⥫ (ᥣ) . - - _騩 ଠ ᫥騩: - -[䨪] [⡠ 樨] [ᬥ饭] [.࠭] - ᪮ ⢮. - - 祭 ⮢ : - -_䨪.. 1 . - )䨪 ७祭 ᥣ ७ ᥣ - , ஬ ந室 饭.᫨ 䨪 ७祭 - ᥣ , ᥣ 롨ࠥ 㬮砭. - )䨪 ७ ⢨ ப -_. - 樨. 1 . 0- ( ) - 뢠, ந ᫮ ( =1) - ⮬ ( =0). 1- 堤 㪠뢠, - ࠭  ਥ. -_⡠ 樨.. 1 . ⡠ 樨 뢠, - 室 ࠭. ⥬ 樨 8086 - 宯࠭ ᨬ筠. ࠭ () - ᯮ ॣ (ॣ஢ ) ந쭮 - 祩 ( ᯮᮡ 樨 ஬ ।⢥). - ன ࠭ 室 ⥫ (।⢥ - ) ॣ (ॣ஢ ). - ࠭ 筨 ⠪ ਥ ( ᪫祭 - ।⢥ 樨: ।⢥ ࠭ - ⮫쪮 筨). ⡠ 樨 ᫥: - - 7 6 5 4 3 2 1 0 - ! mod ! reg ! r/m ! - !-----!-----!-----!-----!-----!-----!-----!----! - - mod r/m ᯮ ࢮ ࠭ ( - ⢥ ᭮ ). reg - ண ࠭ 堤 , ᯮ - ७ . - 祭 mod: - 11 - ࠭ ॣ - ( ⠫ mod ࠭ , ॣ, - 㪠뢠 mod r/m, ᮤঠ - ࠭) - 10 - ᬥ饭 ( ) - - - 6 - - - 01 - ᬥ饭 ( ) - 00 - ᬥ饭 - - 祭 reg ⠪ r/m mod=0 (.. ॣ஢ - 樨 ᫥騥: - - reg r/m - 000 AL AX - 001 CL CX - 010 DL DX - 011 BL BX - 100 AH SP - 101 CH BP - 110 DH SI - 111 BH DI - - 樨 祭 mod r/m । ᯮᮡ - ᫥ ᫥騬 ࠧ: - - r/m mod=00 mod=01 10 - 000 BX+SI BX+SI+ᬥ饭 - 001 BX+DI BX+DI+ᬥ饭 - 010 BP+SI BP+DI+ᬥ饭 - 011 BP+DI BP+DI+ᬥ饭 - 100 SI SI+ᬥ饭 - 101 DI DI+ᬥ饭 - 110 direct BP+ᬥ饭 - 111 BX BX+ᬥ饭 - -饭. 1 ( mod-01) 2 ( mod=10). -।⢥ ࠭. 1 2 - ࠧ, । 1 7 ⮢. - -*/ -}; +// Шаблон программы для лаб работы LAB2 +// Изучение системы команд + +#include +#include + +int main (void) +{ int aa; + + clrscr(); +/* +******************************************************** + 1 2 3 Напишите программы, иллюстрирующие работу след команд: + +1. Команда JL. + JL metka. + Осуществляет переход на указанную метку, + если результат предыдущего сравнения: БОЛЬШЕ + (Переход осуществляется, если флаги SF=0 и OF =0) + + asm { + cmp ax, 13 + JL metka + ..... ; какой-то блок команд + + metka: + ...... ; какой-то блок команд + }; + +2. Команда ROL + Rol ax, 1 + Rol bx, cl + + Команда циклического сдвига влево. + Если второй операнд - CL, то число разрядов, на которые + осуществляется сдвиг, определяется содержимым регистра CL. + +3. Команда LEA. + По этой команде адрес второго операнда передается в регистр + первого операнда. + lea ax, a; + +4. Команда NOP + Команда нет операции + +5. Команда AND + and ax,bx + Команда логического умножения + Первый операнд лог умножается (конъюнкция) на второй + результат в первый */ +/* +******************************************************** + 4 Напишите программу со строковыми командами + Команда MOVS. + Команда пересылки строки. + Направление пересылки определяется значением флага DF - флага направления. + + Для операций с байтами - MOVSB + Для операций со словами - MOVSW + + Не имеет операндов. Не воздействует на флаги. + + Пересылает из области памяти, адресуемой регистром SI - sourse + в область памяти, адресуемую регистром DI - destination. + + */ +// Ниже приведен пример программы + int A[10]={2,1,2,3,4,5,6,7,8,9}; + int B[10]={1,1,0,0,0,0,0,0,0,0}; + + asm { + cld //сбрасываем флаг направления + lea si,A + lea di,B +// mov dx,di + }; +// Задание: Распечатайте значения индексных регистров +// до передачи +// printf ("\n значения индекс регистров is, di = %x %x ", _SI, _DI); + asm mov cx,1 ; // ???? + asm movsb ; // ????? + +// Задание: Распечатайте значения индексных регистров +// после передачи Передача прошла? Сколько слов передано? + +printf ("\n значения индекс регистров is, di = %x %x ", _SI, _DI); + printf ("\n Вывод массива В после строковой передачи"); + for (int i=0; i<10; i++) + { + printf (" \n %d ", B[i]); + } + + getch(); + +//******************************************************** +// 5 Программа поиска в видеопамяти символа + printf (" \n Поиск символа "); +/* asm + asm +e1: asm { + mov ax, 0xb800 + mov es, ax + mov + cmp es:[di],al + jnz e2 }; + printf (" \n Нашли символ "); +e2: asm add di, 2 + asm loop e1 + printf (" \n Не нашли символ "); + getch(); + + */ +// return (0); +//***************** Задания ****************** +// +// 1 Проиллюстрируйте программами указанные выше команды +// 2 Рассмотрите двоичный код этих команд +// 3 Заполните таблицу, используя TD. Должны присутствовать +// все поля формата команды. +/* + Мнемоника Префикс КОП Постбайт Смещение Непоср.операнд + │ │ │ │ │адресации │ │ │ + ├────┼─────────────┼──────┼──────┼────────────┼─────────┼─────────────┤ + │ 1 │and ax,bx │ - │ │ │ - │ - │ + │ 2 │rep and bx,ax│ │ │ │ │ │ + │ 3 │add ax,16 │ - │ │ │ - │ │ + 4 add al,[bx+si] +*/ + +// 4. Напишите программу со строковыми командами при 10 передачах +// 5. Разработайте блок-схему и напишите программу +// поиска символа в видеопамяти на первых 4-х видеостраницах +// 6. Ответьте на вопросы: Какая мнемоника двухоперандной команды 00FF. +// Как выполняется команда LDS BX,PtriA + +/* + +  _Структура процессора i8086 + + Программисту на уровне команд доступны четырнадцать регист- +ров. Их удобно разбить на четыре группы: 1)Регистры данных, 2)ад- +ресные, 3)сегментные 4)указатель команд и регистр флажков(призна- +ков). +1) Регистры данных (в некоторых книгах их называют регистрами общего + назначения). Операнды в этих регистрах могут быть как слова так и + байты. Если операнд - байт, может быть указана любая половина + регистра. Есть ряд команд, в которых функции отдельных регистров + специализированы (см.табл.) +2) Указатели и индексные регистры (адресные регистры, используются для + хранения 16-разрядных адресов). Адресные регистры во многих командах + также специализированы (см.табл.) +3) Сегментные регистры (указывают начала четырех сегментов - участков + по 64 К байт в 1М ОЗУ: сегмент команд CS, сегмент стека SS и два + сегмента данных - DS и ES extra) +4) Указатель команд и регистр флажков + + Специальные функции регистров 8086 + +AX Аккумулятор Умножение, деление и ввод-вывод слов +AL Аккумулятор(мл) Умножение, деление и ввод-вывод байтов +AH Аккумулятор(ст) Умножение и деление байтов +BX База Базовый регистр, преобразование (?) +CX Счетчик Операции с цепочками, циклы +CL Счетчик (мл) Динамические сдвиги и ротации +DX Данные Умножение и деление слов, + косвенный ввод-вывод +SP Указатель стека Стековые операции +BP Указатель базы Базовый регистр +SI Индекс источника Операции с цепочками, индексный регистр +DI Индекс получателя Операции с цепочками, + +  _Регистр флагов процессора + + 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤ + OF DF IF TF SF ZF AF PF CF + + CF ( Carry Flag ) - флаг переноса; + PF ( Parity Flag ) - флаг четности; + AF ( Auxiliary Carry Flag ) - флаг вспомогательного переноса; + ZF ( Zero Flag ) - флаг нуля; + SF ( Sign Flag ) - флаг знака; + TF ( Trap Flag ) - флаг ловушки; + IF ( Interrupt-Enable Flag ) - флаг разрешения прерывания; + DF ( Direction Flag ) - флаг направления; + OF ( Overflow Flag ) - флаг переполнения. + + + + + + - 5 - + +  _Организация памяти + + Адресуемая память (адресное пространство) представляет собой +область из 1М байт(в реальном режиме работы для микропроцессоров +i80286 и старше). Два смежных байта образуют слово. Адресом слова +считается адрес младшего байта. МП 8086 считывает информацию из +ОЗУ 16 бит.словами, начинающимися с четных адресов, хотя команда +или слово данных могут быть расположены в ОЗУ в любом адресе. + Физический адрес памяти имеет длину 20 бит, однако все обра- +батываемые в регистрах МП величины имеют длину 16 бит. Для форми- +рования физических адресов используется механизм сегментации памя- +ти. Пространство памяти 1 М доступно процессору через 4 "окна" +(сегмента) каждый размером 64 К байт. Начальный адрес каждого сег- +мента содержится в оюном из четырех сегментных регистров. Команды +обращаются к байтам и словам в пределах сегментов, используя отно- +сительный (внутрисегментный) адрес. + +  _Общий формат команды следующий: + +[Префикс] КОП [постбайт адресации] [смещение] [непоср.операнд] +Элементы в квадратных скобках могут отсутствовать. + + Назначение элементов команды: + + _Префикс .. Длина 1 байт. + а)Префикс переназначения сегмента позволяет переназначить сегмент + ОЗУ, к которому происходит обращение.Если префикс переназначения + сегмента отсутствует, сегмент выбирается по умолчанию. + б)Префикс повторения действия для строковых команд + _КОП . - код операции. Длина 1 байт. 0-й бит КОП во многих (но не во всех) + командах показывает, производится ли операция со словом ( =1) или с + байтом ( =0). 1-й бит КОП в двухадресных командах указывает, какой + из операндов является приемником. + _Постбайт адресации .. Длина 1 байт. Постбайт адресации показывает, где + находятся операнды. Структура системы адресации МП 8086 в + двухоперандной команде несимметрична. Один из операндов (первый) может + быть расположен в регистре (регистровая адресация) или в произвольной + ячейке ОЗУ (все способы адресации кроме непосредственной). + Второй операнд может находиться в теле команды (непосредственная + адресация) или в регистре (регистровая адресация). Каждый из + операндов может быть как источником так и приемником (за исключением + непосредственной адресации: непосредственный операнд может быть + только источником). Структура постбайта адресации следующая: + + 7 6 5 4 3 2 1 0 + ! mod ! reg ! r/m ! + !-----!-----!-----!-----!-----!-----!-----!----! + + Поля mod и r/m задают место расположения первого операнда (или + едиственного в одноадресной команде). Поле reg задает положение + второго операнда в двухадресных командах, или используется для + расширения КОП в одноадресных командах. + Значения поля mod: + 11 - операнд в регистре + (при остальных mod операнд в ОЗУ, а регистры, на + которые указывают поля mod и r/m, содержат компоненты + адреса операнда) + 10 - смещение два байта (без знака) + + - 6 - + + 01 - смещение один байт (со знаком) + 00 - смещение в команде отстутствует + + Значения поля reg а также поля r/m при mod=0 (т.е. при регистровой + адресации следующие: + + reg или r/m Байт Слово + 000 AL AX + 001 CL CX + 010 DL DX + 011 BL BX + 100 AH SP + 101 CH BP + 110 DH SI + 111 BH DI + + При адресации в память значения mod и r/m определяют способ + вычисления адреса следующим образом: + + r/m mod=00 mod=01 или 10 + 000 BX+SI BX+SI+смещение + 001 BX+DI BX+DI+смещение + 010 BP+SI BP+DI+смещение + 011 BP+DI BP+DI+смещение + 100 SI SI+смещение + 101 DI DI+смещение + 110 direct BP+смещение + 111 BX BX+смещение + +Смещение. Длина 1 байт (при mod-01) или 2 байта(при mod=10). +Непосредственный операнд. Длина 1 или 2 байта +Таким образом, длина команды лежит в пределах от 1 до 7 байтов. + +*/ +}; diff --git a/Labv3.cpp b/Labv3.cpp index 6cb7aaa..65742f2 100755 --- a/Labv3.cpp +++ b/Labv3.cpp @@ -1,69 +1,69 @@ -// LAB3 -// ணࠬ -// ᨢ ᯮᮡ 樨 - -// ४⨢ ९ -// 祭 䠩 ᠭ ⨯ -権 -// 楫 ᮮ饭 ⨯ -権 㬥 -#include -#include -#include -#include -// #pragma inline // 祭 ஥ ᥬ - -//  ६ -int iB=0x1234; -int A[90]={0,1,2,3,4,5,6,7,8,9}; - -// ᭮ ணࠬ - 㭪 -// void - 祭 -void main(void) -{ -//  ६ -int iA=0x5678; - clrscr(); - printf ("\n ணࠬ ᨢ \n"); -// 塞 ᨢ ஢ - for (int i=0; i<10; i++) - { - // ??????? ⠢ - printf (" \n %d ", A[i]); - } - getch(); -// 塞 ᨢ ᥬ -asm mov si,0 -e2: -asm { - lea bx,A - mov cx,10 - mov ax,0 - }; -e1: asm mov [bx],ax // ???? 롥 ᯮᮡ 樨 - asm add bx,2 - asm loop e1 -// ??? 뢥 ᨢ - asm add si,10 // 蠣 ᨢ - asm mov ax,100 - asm cmp ax,si - asm ja e2 -// ??? 뢥 㬥 ᨢ - for (i=0; i<20; i=i+4) - { printf (" \n "); - for (int j=0; j<4; j++) - { printf (" "); // ???? ⠢ - } - } - getch(); -} - -// -// 1. ணࠬ ୮ ᨢ -// 뢥 ࠭ 祭 ⮢ ᨢ -// 2. ⠩ ᨢ 㬥. ப ᫮, -// ᯮ ࠧ ᯮᮡ 樨 -// - ᢥ-ॣ஢ -// - -᭠ -// ࠢ ⢮ ᯮᮡ 樨. -// 3. । ᨢ ᥣ ᯮ짮. TD -// 4. ணࠬ, ࠧ १ ࠧ -// . \ No newline at end of file +// Работа LAB3 +// Шаблон программы +// Массивы и способы адресации + +// Директивы Препроцессора +// Включение файлов в которых описаны прототипы ф-ций +// с целью сообщения компилятору о типах ф-ций и их аргументах +#include +#include +#include +#include +// #pragma inline // Подключение встроенного Ассемблера + +// Объявление переменных +int iB=0x1234; +int A[90]={0,1,2,3,4,5,6,7,8,9}; + +// Основная программа - функция +// void - она не возвращ значений +void main(void) +{ +// Объявление переменных +int iA=0x5678; + clrscr(); + printf ("\n Программа заполнения массива \n"); +// Заполняем массив на уровне команд Си + for (int i=0; i<10; i++) + { + // ??????? Вставте команды + printf (" \n %d ", A[i]); + } + getch(); +// Заполняем массив из ассемблера +asm mov si,0 +e2: +asm { + lea bx,A + mov cx,10 + mov ax,0 + }; +e1: asm mov [bx],ax // ???? Выберите способ адресации + asm add bx,2 + asm loop e1 +// ??? Выведите одном массив + asm add si,10 // Задается шаг массива + asm mov ax,100 + asm cmp ax,si + asm ja e2 +// ??? Выведите двумерный массив + for (i=0; i<20; i=i+4) + { printf (" \n "); + for (int j=0; j<4; j++) + { printf (" "); // ???? Вставте команду + } + } + getch(); +} + +// Задания +// 1. Напишите две программы заполнения одномерного массива на Си и Асс +// выведите на экран значения элементов массива +// 2. Считайте массив двумерным. Заполните его четные строки любым числом, +// используя разные способы адресации +// - косвенно-регистровая адресация +// - базово-индексная адресация +// Сравните количество команд при двух способах адресации. +// 3. Определите место массива в сегменте данных с использов. TD +// 4. Напишите программу, которая дает разный результат в разных +// моделях памяти. \ No newline at end of file diff --git a/Labv4.cpp b/Labv4.cpp index 1890649..2b2d949 100755 --- a/Labv4.cpp +++ b/Labv4.cpp @@ -1,141 +1,141 @@ -// ୠ Lab 4 -// . ७ ६. -// - - -#include -#include -#include - -void main() -{ - long int cl2,cl1,c1,c2; - unsigned long int t1,t2,t3; - -// ⠭ 稪 -/* asm{ - mov ax,00110110B // 00 11 011 0 - out 43h,ax - mov ax,0000000000000000B - out 40h,al - mov al,ah - out 40h,al - } - */ - - // ७ ६ 믮 ⮢ ணࠬ 1 -// ⨪ ( 뢠 0- ⠩) -// 稪 ⨪ 祩 46 - 訩 - asm{ - mov ax,0x46 - mov es,ax - mov bx,0xC - mov ax,[es:bx] - mov cx,[es:(bx+2)] - } -// 砫쭮 祭 襥 襥 ??? -// cl2= ; cl1= ; - c1=cl2+cl1*0x10000; - - //⮢ ணࠬ 1 - asm mov cx,1000 - met1: asm { - push cx - mov cx,1000 - } - met2: asm { - loop met2 - pop cx - loop met1 - } - -// - asm{ - mov ax,0x46 - mov es,ax - mov bx,0xC - mov ax,[es:bx] - mov cx,[es:(bx+2)] - } -// 筮 祭 ??? -// cl2=_AX; cl1= ; -// 楫 - -c2=cl2+cl1*0x10000; - -// clrscr(); -// printf("\nࢮ - %d\n",c1); -// printf("஥ - %d\n",c2); - cout<<"\n६ 믮 ⮢ ணࠬ 1\n"; - cout<<"COUNTs: "< +#include +#include + +void main() +{ + long int cl2,cl1,c1,c2; + unsigned long int t1,t2,t3; + +// Изменение константы счетчика +/* asm{ + mov ax,00110110B // 00 11 011 0 + out 43h,ax + mov ax,0000000000000000B + out 40h,al + mov al,ah + out 40h,al + } + */ + + // Измерение времени выполнения тестовой программы 1 +// в тиках (в прерываниях от 0-го канала таймера) +// Счетчик тиков ячейка 46С - младший байт первый + asm{ + mov ax,0x46 + mov es,ax + mov bx,0xC + mov ax,[es:bx] + mov cx,[es:(bx+2)] + } +// Запомните начальное значение младшее и старшее ??? +// cl2= ; cl1= ; + c1=cl2+cl1*0x10000; + + //Тестовая программа 1 + asm mov cx,1000 + met1: asm { + push cx + mov cx,1000 + } + met2: asm { + loop met2 + pop cx + loop met1 + } + +// + asm{ + mov ax,0x46 + mov es,ax + mov bx,0xC + mov ax,[es:bx] + mov cx,[es:(bx+2)] + } +// Запомните конечное значение ??? +// cl2=_AX; cl1= ; +// Длинное целое - +c2=cl2+cl1*0x10000; + +// clrscr(); +// printf("\nПервое - %d\n",c1); +// printf("Второе - %d\n",c2); + cout<<"\nВремя выполнения тестовой программы 1\n"; + cout<<"COUNTs: "< -#include -#include -#include - - -#include - -void page(char a) // ⠭ ⨢ ᯫ . -{ - asm { - mov ah,0x05 - mov al,a - int 0x10 - } - -} - -void main() -{ -// ⠭ ० -asm{ - mov al,02h - mov ah,00h - int 10h - } page(0); - clrscr(); -// 뢮 ⥪ ।⢠ - for(char n = 1; n <= 100; n++) -// -- ᠬ 뢮 - - -// 뮤 ⥪ ० । ࠡ - page(0); - asm mov cx,1000 // ⢮ ᨬ - asm mov di,0 // 塞 -e1: asm { add di, 2 - mov ax, 0xb800 // ।塞 砫 - mov es, ax - mov al, cl - mov es: [di],al // 뫠 - mov al, 4 - mov es: [di+1],al // 뫠 ன - }; - asm loop e1 - - getch(); - - -// -// 1 뢥 ⥪ ᯮ . -// 梥⮬ ᯮ짮 . -// । ६ 뢮 -// 2 ࠧ ⥪⮢ ᯫ ࠭.( -// ணࠬ 뢮 ᨬ 砫 ᯫ ࠭) -// 3 뢥 ⥪ ࠭ -// 4 ࣠ ४祭 ࠭ -/* while (bioskey(1) == 0) -{ - page(0); delay(1000); - -} */ -return; -} +/* Labv8: Ass, and Ci functions + Шаблон программы для работы с видеосистемой + Текстовый режим +*/ + +#include +#include +#include +#include + + +#include + +void page(char a) // Установка номера активной дисплейной стр. +{ + asm { + mov ah,0x05 + mov al,a + int 0x10 + } + +} + +void main() +{ +// установка видеорежима +asm{ + mov al,02h + mov ah,00h + int 10h + } page(0); + clrscr(); +// Вывод текста средствами Си + for(char n = 1; n <= 100; n++) +// -- здесь сам вывод - + +// Выод текста в режиме непосредств работы с видеопамятью + page(0); + asm mov cx,1000 // Задаем количество символов + asm mov di,0 // Обнуляем индекс +e1: asm { add di, 2 + mov ax, 0xb800 // Определяем начальный адрес + mov es, ax + mov al, cl + mov es: [di],al // Пересылаем четный первый байт в видеопамять + mov al, 4 + mov es: [di+1],al // Пересылаем нечетный второй байт + }; + asm loop e1 + + getch(); + + +// Задания +// 1 Выведите текст с использ Си. +// Раскрасте его зеленым цветом с использованием Асс. +// Определите время вывода в обоих случаях +// 2 Протестируйте размер текстовой дисплейной страницы.(Напишите +// программу на Асс вывода символов в начале и в конце дисплейной страницы) +// 3 Выведите текст на вторую дисп страницу +// 4 Организуйте переключение страниц +/* while (bioskey(1) == 0) +{ + page(0); delay(1000); + +} */ +return; +} diff --git a/MTASK.CPP b/MTASK.CPP index 06bf5f1..3d675e3 100755 --- a/MTASK.CPP +++ b/MTASK.CPP @@ -1,166 +1,166 @@ -#include -#include -#include -#include - -struct ProcStats //struktura soderjashaya kontext zadachi -{ - unsigned int rax, rbx, rcx, rdx; // 0 2 4 6 - unsigned int rsi, rdi, rbp, rsp; // 8 10 12 14 - unsigned int rcs, rds, res, rss; //16 18 20 22 - unsigned int rip, rflags, a, b; //24 26 28 30 -} Stats[3]; //massiv iz treh takih struktur - -unsigned int current_proc; //nomer tekushey zadachi -unsigned int stats_offset; //adres konteksta zadachi -void interrupt (*oldHandler)(...); //ukazatel na staryi obrabotchik preryvaniya - -void interrupt IntHandler(...) //svoy obrabotchik -{ - asm { - mov si, [current_proc]; //nomer procedury - mov cl, 5 //umnojaem nar 32 (razmer struktury) - shl si, cl - //mov ax, offset Stats - mov ax, [stats_offset] //pribavlyaem adres nachala massiva struktur - add si, ax //poluchaem adres nujnogo konteksta - pop ax //zapisyvaem v nego registry - mov [si+12], ax //bp - pop ax - mov [si+10], ax //di - pop ax - mov [si+ 8], ax //si - pop ax - mov [si+18], ax //ds - pop ax - mov [si+20], ax //es - pop ax - mov [si+ 6], ax //dx - pop ax - mov [si+ 4], ax //cx - pop ax - mov [si+ 2], ax //bx - pop ax - mov [si+ 0], ax //ax - pop ax - mov [si+24], ax //ip - pop ax - mov [si+16], ax //cs - pop ax - mov [si+26], ax //flags - mov ax, sp - mov [si+14], ax //sp - mov ax, ss - mov [si+22], ax //ss - - mov ax, [current_proc] //perehodim k sleduyushey zadache - inc ax - cmp ax, 3 - jb label1 - mov ax, 0 - } - label1: - asm { - mov [current_proc], ax //vychislyaem adres eyo konteksta - mov si, ax - mov cl, 5 - shl si, cl - //mov ax, offset Stats - mov ax, [stats_offset] - add si, ax //zagrujaem registry - mov ax, [si+22] //ss - mov ss, ax - mov ax, [si+14] //sp - mov sp, ax - mov ax, [si+26] //flags - push ax - mov ax, [si+16] //cs - push ax - mov ax, [si+24] //ip - push ax - mov ax, [si+ 0] //ax - push ax - mov ax, [si+ 2] //bx - push ax - mov ax, [si+ 4] //cx - push ax - mov ax, [si+ 6] //dx - push ax - mov ax, [si+20] //es - push ax - mov ax, [si+18] //ds - push ax - mov ax, [si+ 8] //si - push ax - mov ax, [si+10] //di - push ax - mov ax, [si+12] //bp - push ax - } - oldHandler(); //vyzyvaem staryi obrabotchik -} - -void Proc1(void); -void Proc2(void); -void Proc3(void); - -int main(void) -{ - unsigned int i, rd, rc, re, rs, ri0, ri1, ri2, f; - - for(i=0;i<3;i++) - memset(&Stats[i],0,sizeof(ProcStats)); - asm { //zapisyvaem registry vo vremennye peremennye - mov ax, cs - mov [rc], ax - mov ax, ds - mov [rd], ax - mov ax, es - mov [re], ax - mov ax, ss - mov [rs], ax - mov [ri0], offset Proc1 //adresa nachala procedur - mov [ri1], offset Proc2 - mov [ri2], offset Proc3 - pushf - pop ax - mov [f], ax - } - for(i=0;i<3;i++) //zapisyvaem znacheniya segmentnyh registrov, - { //flagov - Stats[i].rcs = rc; //i adresa nacha procedur - Stats[i].rds = rd; //v sootvetstvuyushye konteksty - Stats[i].res = re; - Stats[i].rss = rs; - Stats[i].rflags = f; - } - Stats[0].rip = ri0; - Stats[1].rip = ri1; - Stats[2].rip = ri2; - current_proc = 0; //tekushaya procedura - pervaya - stats_offset = (unsigned)&Stats; //adres nachala massiva - oldHandler = getvect(0x9); //perekluchaemsya po najatiyu klavishy - setvect(0x9,IntHandler); - Proc1(); - setvect(0x9,oldHandler); - - return 0; -} - -void Proc1(void) -{ - while(1) - printf("Proc1 is working %d\n",current_proc); - } - -void Proc2(void) -{ - while(1) - printf("Proc2 is working %d\n",current_proc); -} - -void Proc3(void) -{ - while(1) - printf("Proc3 is working %d\n",current_proc); +#include +#include +#include +#include + +struct ProcStats //struktura soderjashaya kontext zadachi +{ + unsigned int rax, rbx, rcx, rdx; // 0 2 4 6 + unsigned int rsi, rdi, rbp, rsp; // 8 10 12 14 + unsigned int rcs, rds, res, rss; //16 18 20 22 + unsigned int rip, rflags, a, b; //24 26 28 30 +} Stats[3]; //massiv iz treh takih struktur + +unsigned int current_proc; //nomer tekushey zadachi +unsigned int stats_offset; //adres konteksta zadachi +void interrupt (*oldHandler)(...); //ukazatel na staryi obrabotchik preryvaniya + +void interrupt IntHandler(...) //svoy obrabotchik +{ + asm { + mov si, [current_proc]; //nomer procedury + mov cl, 5 //umnojaem nar 32 (razmer struktury) + shl si, cl + //mov ax, offset Stats + mov ax, [stats_offset] //pribavlyaem adres nachala massiva struktur + add si, ax //poluchaem adres nujnogo konteksta + pop ax //zapisyvaem v nego registry + mov [si+12], ax //bp + pop ax + mov [si+10], ax //di + pop ax + mov [si+ 8], ax //si + pop ax + mov [si+18], ax //ds + pop ax + mov [si+20], ax //es + pop ax + mov [si+ 6], ax //dx + pop ax + mov [si+ 4], ax //cx + pop ax + mov [si+ 2], ax //bx + pop ax + mov [si+ 0], ax //ax + pop ax + mov [si+24], ax //ip + pop ax + mov [si+16], ax //cs + pop ax + mov [si+26], ax //flags + mov ax, sp + mov [si+14], ax //sp + mov ax, ss + mov [si+22], ax //ss + + mov ax, [current_proc] //perehodim k sleduyushey zadache + inc ax + cmp ax, 3 + jb label1 + mov ax, 0 + } + label1: + asm { + mov [current_proc], ax //vychislyaem adres eyo konteksta + mov si, ax + mov cl, 5 + shl si, cl + //mov ax, offset Stats + mov ax, [stats_offset] + add si, ax //zagrujaem registry + mov ax, [si+22] //ss + mov ss, ax + mov ax, [si+14] //sp + mov sp, ax + mov ax, [si+26] //flags + push ax + mov ax, [si+16] //cs + push ax + mov ax, [si+24] //ip + push ax + mov ax, [si+ 0] //ax + push ax + mov ax, [si+ 2] //bx + push ax + mov ax, [si+ 4] //cx + push ax + mov ax, [si+ 6] //dx + push ax + mov ax, [si+20] //es + push ax + mov ax, [si+18] //ds + push ax + mov ax, [si+ 8] //si + push ax + mov ax, [si+10] //di + push ax + mov ax, [si+12] //bp + push ax + } + oldHandler(); //vyzyvaem staryi obrabotchik +} + +void Proc1(void); +void Proc2(void); +void Proc3(void); + +int main(void) +{ + unsigned int i, rd, rc, re, rs, ri0, ri1, ri2, f; + + for(i=0;i<3;i++) + memset(&Stats[i],0,sizeof(ProcStats)); + asm { //zapisyvaem registry vo vremennye peremennye + mov ax, cs + mov [rc], ax + mov ax, ds + mov [rd], ax + mov ax, es + mov [re], ax + mov ax, ss + mov [rs], ax + mov [ri0], offset Proc1 //adresa nachala procedur + mov [ri1], offset Proc2 + mov [ri2], offset Proc3 + pushf + pop ax + mov [f], ax + } + for(i=0;i<3;i++) //zapisyvaem znacheniya segmentnyh registrov, + { //flagov + Stats[i].rcs = rc; //i adresa nacha procedur + Stats[i].rds = rd; //v sootvetstvuyushye konteksty + Stats[i].res = re; + Stats[i].rss = rs; + Stats[i].rflags = f; + } + Stats[0].rip = ri0; + Stats[1].rip = ri1; + Stats[2].rip = ri2; + current_proc = 0; //tekushaya procedura - pervaya + stats_offset = (unsigned)&Stats; //adres nachala massiva + oldHandler = getvect(0x9); //perekluchaemsya po najatiyu klavishy + setvect(0x9,IntHandler); + Proc1(); + setvect(0x9,oldHandler); + + return 0; +} + +void Proc1(void) +{ + while(1) + printf("Proc1 is working %d\n",current_proc); + } + +void Proc2(void) +{ + while(1) + printf("Proc2 is working %d\n",current_proc); +} + +void Proc3(void) +{ + while(1) + printf("Proc3 is working %d\n",current_proc); } \ No newline at end of file diff --git a/asm/p_2.asm b/asm/p_2.asm index ee27d7a..44357f8 100755 --- a/asm/p_2.asm +++ b/asm/p_2.asm @@ -14,27 +14,27 @@ main: mov ax,@data mov ds,ax mov es,0b:8000h -;------------------ ------------- +;------------------Открываем файл------------- mov di,30h - xor cx,cx ; - - mov bx,2 ; - - - mov dx,1 ; , . - mov dx,offset filename ; - mov ah,3dh ; DOS - int 21h ; - mov [Handle], ax ; + xor cx,cx ;атрибуты файла - обычный файл + mov bx,2 ;режим доступа обычный - доступ для чтения-записи + mov dx,1 ;если файл существует, то открыть его. в обратной случае вернуть ошибку + mov dx,offset filename ;формируем указатель на имя файла + mov ah,3dh ;номер функции DOS + int 21h ;открываем файл + mov [Handle], ax ;сохраним дескриптор файла mov bx,ax - jnc read ; , - jc ex ; + jnc read ;если файл существовал, то переход + jc ex ;переход в случае ошибки read: mov ah, 3Fh mov cx,1 mov dx, buffer int 21h - cmp ax, cx ; EOF - jne eof ; EOF, + cmp ax, cx ; Проверка EOF + jne eof ; Если EOF, то выходим push ax push bx @@ -45,12 +45,12 @@ read: mov ah, 3Fh pop ax inc di - ; cmp [buffer], 13 ; 13- + ; cmp [buffer], 13 ; Пропускаем 13-ый символ ; je read - ; cmp [buffer], 10 ; + ; cmp [buffer], 10 ; Проверка конца строки ; je exit jmp read -eof: mov bx, Handle ; +eof: mov bx, Handle ; закрываем файл mov ah, 3Eh int 21h @@ -89,28 +89,28 @@ found2: mov di,bx jmp found -write: ; xor cx,cx ; - - ; mov bx,1 ; - - +write: ; xor cx,cx ;атрибуты файла - обычный файл + ; mov bx,1 ;режим доступа обычный - доступ для чтения-записи ; mov dx,1 - ; mov dx,offset filename2 ; + ; mov dx,offset filename2 ;формируем указатель на имя файла ; mov cx,5 - ; mov ah,5bh ; DOS - ; int 21h ; + ; mov ah,5bh ;номер функции DOS + ; int 21h ;создаём и открываем файл - ; mov [Handle2], ax ; + ; mov [Handle2], ax ;сохраним дескриптор файла ; mov bx,ax - xor cx,cx ; - - mov bx,0002h ; - - - mov dx,1 ; , . - mov dx,offset filename2 ; + xor cx,cx ;атрибуты файла - обычный файл + mov bx,0002h ;режим доступа обычный - доступ для чтения-записи + mov dx,1 ;если файл существует, то открыть его. в обратной случае вернуть ошибку + mov dx,offset filename2 ;формируем указатель на имя файла mov al,0001h - mov ah,3dh ; DOS - int 21h ; - mov [Handle2], ax ; + mov ah,3dh ;номер функции DOS + int 21h ;открываем файл + mov [Handle2], ax ;сохраним дескриптор файла mov bx,ax @@ -126,12 +126,12 @@ xor ax,ax mov ah,0dh int 21h - cmp ax, cx ; EOF + cmp ax, cx ; Проверка EOF - mov bx, Handle2 ; + mov bx, Handle2 ; закрываем файл mov ah, 3Eh int 21h - jc exit ; + jc exit ;переход в случае ошибки exit: mov ax,4c00h