|
Програма для перегляду великих текстових файлів, розмір яких більший за 64 кілобайти
Програма для перегляду великих текстових файлів, розмір яких більший за 64 кілобайти
Міністерство освіти та науки України Кіровоградський Державний Технічний університетКафедра програмного забезпеченняКурсовий проект з дисципліни “Програмування на мові ASM-86” на тему: “Програма для перегляду великих текстових файлів, розмір яких більший за 64 кілобайти” ЗМІСТ Завдання 1. Вступ 2. Постановка задачі 3. Обґрунтування вибору методів розв'язку задачі 4. Алгоритм програми 5. Реалізація програми 6. Системні вимоги 7. Інструкція для користувача 8. Висновки. 9. Використана література. Лістинг програми. 1. Вступ Для перегляду текстових файлів використовуються програми - переглядачі. Вони дозволяють користувачу роздивлятись будь-яку частину файла у зручному для нього вигляді. Деякі переглядачі мають різні обмеження, наприклад на об'єм файла. Інші можуть переглядати файли будь-якої довжини. Мета цієї роботи - показати програму-переглядач саме для великих файлів. 2. Постановка задачі Необхідно створити програму, з допомогою якої можна було б переглядати текстові файли, за об'ємом більші за 64 кілобайти. 3. Обґрунтування вибору методів розв'язку задачі При перегляді маленьких файлів зручно їх повністю прочитати з диска у пам'ять і виводити на екран звідти. Звичайно, можна застосувати такий спосіб і для великих файлів, але при цьому буде витрачатися багато оперативної пам'яті в машині. Для того щоб не читати файл повністю, його читають по частинах. Читають якийсь блок і переглядають його. Коли перегляд блоку завершується, то з диска підчитується наступний блок або попередній. Отже, це дає змогу переглядати великі файли при невеликому об'ємі пам'яті. 4. Алгоритм програми 1. Ввести ім'я файла 2. Відкрити файл і прочитати перший блок. 3. При натисненні клавіші “вниз” прокрутити текст вниз. 4. При натисненні клавіші “вгору” прокрутити текст вгору. 5. Вивести на екран зміст файлу. 6. Якщо область перегляду вийшла за межі блоку, то прочитати наступний або попередній блок. 7. Якщо користувач не натиснув ESC, перейти до пункту 3. 8. Стоп 5. Реалізація програми Для операцій з файлами використовуються засоби ДОС. Програма складається з таких процедур: key_up - обробка “клавіша вгору” key_down - обробка “клавіша вниз” openfile - відкриття файла closefile - закриття файла readnextblock - читання наступного блоку readprevblock - читання попереднього блоку initblocks - ініціалізація програми cleanup - очистка showframe - відображення кадру key_pgup - обробка клавіші Page Up key_pgdn - обробка клавіші Page Down 6. Системні вимоги Операційна система МS-DOS Процесор 8086 або старший Екран CGA або старший Пам'ять 640 К 7. Інструкція для користувачаДля запуску програми необхідно виконати файл view64.exe. Після нього в командному рядку вводиться ім'я файла. Наприклад, “view64 big_text.txt”. Після цього на екрані з'явиться зміст файлу. Його можна “гортати” клавішами “Page Up”, “Page Down”, “Up”, “Down”.Для виходу з програми треба натиснути клавішу “ESC”.8. ВисновкиОтже, на мові Асемблера для процесорів сімейства INTEL x86 створена програма, яка призначена для перегляду в текстовому режимі файлів. Її особливістю є те, що розмір файлів може бути більшим за 64 кілобайти.Програма працює, але все ж таки може містити помилки. Але робота з нею не вимагає від користувача якихось спеціальних навичок, вона проста в користуванні.9. Використана література1. Р. Журден. Справ очник программиста на персональном компьютере фирмы IBM.2. П. Абель. Асемблер и программирование для IBM PC.Додаток. ЛІСТИНГ ПРОГРАМИ.model compact.stack 1024.386.data;буфериpvideobuffer db 4000 dup(0)fileblock db 32000 dup(0) ;блок з файлаvideo db 2000 dup(0) ;копiя кадраerrormsg db 'Помилка читання файла!$'filename0 db 50 dup(0)msg1 db 'Введiть iм`я файла. $',10,13filehandle dw 0 ;зсилкаnblock dw 0currentposbegin dw 0 ;початок блокуcurrentposend dw 0 ;кiнець блокуblocklength dw 0 ;фактична довжина блокуlastkey db 0 ;останнiй рух: 0 = вниз, 1 - вгоруsym_count dw 0 ;кiлькiсть символiв на екранiupperend dw 0block_num dw 0.codestart:jmp begin;====================ОБРОБКА КЛАВIШ;====================KEY_UPkey_up procpushacmp word ptr fs:[lastkey],0jne ok_up1;перевiрка: якщо end<begin то пiдчитати попереднiй блокmov si,word ptr fs:[currentposend]mov di,word ptr fs:[currentposbegin]cmp si,dija ok_up1cmp word ptr fs:[block_num],1jne ok_up1;пiдчиткаcall readprevblockmov si,word ptr fs:[blocklength]add si,offset fileblock;sub si,word ptr fs:[sym_count]mov word ptr fs:[currentposend],siok_up1:mov word ptr fs:[lastkey],1;зсовуємо video вниз на length(рядка який вище) байт;пiдраховуємо lengthmov ax,seg videomov es,axmov ds,axxor dx,dx ;dx=length[0]mov bx,word ptr fs:[currentposbegin]dec bxget_len24:dec bxcmp byte ptr [bx],10 ;кiнець рядкаje stop_len24 ;стоп - циклgood_sym:inc dxcmp dx,79jb get_len24stop_len24:inc dx;тепер dx - довжина 1 рядка;зсунути video на dx байт внизmov di,offset video+2000mov si,offset video+2000sub si,dxstdmov cx,2000+1rep movsb;дописати dx байт;встановлюємо 2000-dxpush dsmov ax,seg currentposbeginmov ds,axmov si,word ptr ds:[currentposbegin]mov bx,word ptr ds:[currentposend]mov di,offset videoadd di,dxpop dsmov ax,seg fileblockmov ds,axmov cx,dx;переносtrans_u:dec sidec dimov al,byte ptr ds:[si]mov byte ptr es:[di],alcmp bx,offset fileblockjae line_u_ok1mov bx,offset fileblockadd bx,word ptr fs:[blocklength]line_u_ok1:cmp si,offset fileblockjae line_u_ok;пiдчитати попереднiй блокmov word ptr fs:[upperend],1call readprevblockmov si,offset fileblockadd si,word ptr fs:[blocklength]line_u_ok:dec bxloop trans_ustop_u:push dsmov ax,seg currentposendmov ds,axmov word ptr ds:[currentposend],bxmov word ptr ds:[currentposbegin],sipop dscall showframepoparetkey_up endp;====================KEY_DOWNkey_DOWN procpushamov word ptr fs:[upperend],0cmp word ptr fs:[lastkey],1jne ok_down1;перевiрка: якщо end<begin то пiдчитати наступний блокmov si,word ptr fs:[currentposend]mov di,word ptr fs:[currentposbegin]cmp si,dija ok_down1;пiдчиткаcall readnextblockmov si,offset fileblock;add si,word ptr fs:[sym_count]mov word ptr fs:[currentposbegin],siok_down1:mov word ptr fs:[lastkey],0;зсовуємо video вгору на length[0] байт;пiдраховуємо length[0]mov ax,seg videomov es,axmov ds,axxor dx,dx ;dx=length[0]mov bx,offset videoget_len0:cmp byte ptr [bx],10 ;кiнець рядкаje stop_len0 ;стоп - циклinc bxinc dxcmp dx,79jb get_len0stop_len0:inc dx;тепер dx - довжина 1 рядка;зсунути video на dx байт вгоруmov di,offset videomov si,offset videocldadd si,dxmov cx,1000rep movsw;дописати dx байт;встановлюємо 2000-dxpush dsmov ax,seg currentposendmov ds,axmov si,word ptr ds:[currentposend]mov bx,word ptr ds:[currentposbegin]mov di,2000+offset videosub di,dxpop dsmov ax,seg fileblockmov ds,axmov cx,dx;переносtrans_d:mov al,byte ptr ds:[si]mov byte ptr es:[di],alinc siinc diinc bxmov bp,offset fileblockadd bp,word ptr fs:[blocklength]cmp bx,bpjbe line_d_ok1mov bx,offset fileblockline_d_ok1:cmp si,bpjbe line_d_ok;пiдчитати наступний блокcall readnextblockmov si,offset fileblock;EOFline_d_ok:loop trans_dstop_d:push dsmov ax,seg currentposendmov ds,axmov word ptr ds:[currentposend],simov word ptr ds:[currentposbegin],bxpop dscall showframepoparetkey_DOWN endp;===================вiдкриття файлаopenfile procpushamov ah,3dhxor al,almov dx,seg filename0mov ds,dxmov dx,offset filename0int 21hjc errormov word ptr ds:[filehandle],axpopareterror:call cleanupmov ah,9mov dx,seg errormsgmov ds,dxmov dx,offset errormsgint 21hpopamov ah,4chint 21hopenfile endp;===================закриття файлаclosefile procpushamov ah,3ehmov dx,seg filehandlemov ds,dxmov bx,word ptr ds:[filehandle]int 21hpoparetclosefile endp;===================читання наступного блоку з файлаreadnextblock procpushamov ax,seg filehandlemov ds,axmov ax,word ptr fs:[block_num]inc axmov word ptr fs:[block_num],axretry_n:mov ah,3fhmov bx,word ptr ds:[filehandle]mov cx,32000mov dx,seg fileblockmov ds,dxmov dx,offset fileblockint 21h;EOF - заповнити 0cmp ax,0jne read_nemov ah,42hmov al,0mov bx,word ptr ds:[filehandle]xor cx,cxxor dx,dxint 21h ;==> на початокjmp retry_nread_ne:mov dx,seg blocklengthmov ds,dxmov word ptr ds:[blocklength],ax ;довжина блокуpoparetreadnextblock endp;===================читання попереднього блоку з файлаreadprevblock procpushamov ax,seg filehandlemov ds,axmov ax,word ptr fs:[block_num]dec axmov word ptr fs:[block_num],ax;seek - спочатку поточне змiщенняmov ah,42hmov al,1mov bx,word ptr ds:[filehandle]xor cx,cxxor dx,dxint 21h ;==> DX:AX - поточне;перевiрити, чи є нуль - початок файла. Тодi - змiстити;на кiнецьcmp dx,0jne norm_readcmp ax,32000jbe make_lastposjmp norm_read;на кiнецьmake_lastpos:mov ah,42hmov al,2mov bx,word ptr ds:[filehandle]xor cx,cxxor dx,dxint 21h ;==> DX:AX - поточнеjmp setposnorm_read:setpos:sub ax,64000sbb dx,0mov cx,dxmov dx,axmov ah,42hmov al,0mov bx,word ptr ds:[filehandle]int 21h ;==> змiстилиmov ah,3fhmov bx,word ptr ds:[filehandle]mov cx,32000mov dx,seg fileblockmov ds,dxmov dx,offset fileblockint 21hmov dx,seg blocklengthmov ds,dxmov word ptr ds:[blocklength],ax ;довжина блокуpoparetreadprevblock endp;======================== iнiцiалiзацiя блокiвinitblocks procpushacall readnextblock;1 копiя в videomov dx,seg videomov es,dxmov di,offset videomov dx,seg fileblockmov ds,dxmov si,offset fileblockcldmov cx,1000rep movsw;початковi значення кордонiв - 0 i 2000mov ax,offset fileblockmov word ptr ds:[currentposbegin],axmov bx,2000+offset fileblockmov word ptr ds:[currentposend],bxpoparetinitblocks endp;------------------------ процедура очисткиcleanup proc;очистка екранаcldpush esmov cx,80*25mov ax,0b800hmov es,axxor di,dimov ax,0700hrep stoswpop es;поставити нормальний курсорmov ah,1xor cl,clmov ch,30hint 10hretcleanup endp;---------------------- процедура вiдображення кадраshowframe procpushamov ax,seg pvideobuffermov ds,ax;настройка кольору;верхнiй рядок сiрийmov bx,offset pvideobuffermov cx,80setw: mov byte ptr ds:[bx],32mov byte ptr ds:[bx+1],70hadd bx,2loop setw;синiй фон, жовтий текстmov cx,80*24setm: mov byte ptr ds:[bx],32mov byte ptr ds:[bx+1],1ehadd bx,2loop setm;кольори;??????????????????=================================;виведення video;сегменти i вказiвники;si - номер символа в буферi;di - iндекс байта вiдеопам@ятi;виводимо всi символи як є, але!;13-й пропускаємо, 10-й - перехiд на;новий рядок, а 9 - табулюємо (10)mov ax,seg videomov ds,axmov ax,seg pvideobuffermov es,axmov si,offset videomov di,offset pvideobuffer;пропустити 1 рядокadd di,80*2symb:mov al,byte ptr ds:[si] ;символcmp al,10 ;перехiд на новий рядокjne normal;почати новий рядокpush axpush bxpush dxpush diadd di,160 ;di=di+ (160-((di+160) mod 160))mov ax,dixor dx,dxmov bx,160div bxmov ax,160sub ax,dxpop diadd di,axpop dxpop bxpop axjmp skip; новий рядокnormal:cmp al,13je skip;нормальний символ - виводимоmov byte ptr es:[di],aladd di,2 ;2 байта - наступнi (атрибут пропустити)skip:inc si ;наступний байт iнформацiїpush sisub si,offset videomov word ptr fs:[sym_count],sipop sicmp di,4000 ;кiнець екранаjb symb;??????????????????===================================;на екран виводимо з пам@ятicldpush esmov cx,80*25mov ax,0b800hmov es,axxor si,sixor di,direp movswpop espoparetshowframe endp;====================KEY_PGUPkey_pgup proc;24 рази викликати key_uppush cxmov cx,24scr_up:call key_uploop scr_uppop cxretkey_pgup endp;====================KEY_PGDNkey_pgdn proc;24 рази викликати key_downpush cxmov cx,24scr_dn:call key_downloop scr_dnpop cxretkey_pgdn endp;============================================begin:mov ax,seg msg1mov ds,ax;введення iменi файла 1mov ah,9mov dx,offset msg1int 21hmov bx,offset filename0ent_1:mov ah,1hint 21hmov [bx],alinc bxcmp al,13jne ent_1dec bxmov byte ptr [bx],0mov ah,2mov dl,10int 21hmov ax,seg blocklengthmov fs,ax;сховати курсорmov ah,1xor cl,clmov ch,00000010bint 10hcall openfilecall initblockscall showframe;чекаємо клавiшуwait_key:xor ah,ahint 16h;al-ascii codecmp ah,1 ;ESCje haltcmp ah,48h ;UPjne next1call key_upjmp wait_keynext1: cmp ah,50hjne next2 ;DOWNcall key_downjmp wait_keynext2: cmp ah,49h ;PGUPjne next3call key_pgupjmp wait_keynext3: cmp ah,51h ;PGDNjne wait_keycall key_pgdnjmp wait_keyhalt:call cleanupcall closefilemov ah,4chint 21hend start
|
|