.
Выход: ---
(используется в программе для вывода информации о проекте, приглашения на ввод строки, а так же для вывода сообщений об ошибках).
Функция 3dh прерывания 21h. Открыть файл.
Вход:AL = код доступа (0 - чтение, 1 - запись, 2 - чтение запись).:DX = адрес на строку в формате ASCIZ.
Выход:CF = 1 - есть ошибка, AX = код ошибки.= 0 - нет ошибки, AX = номер файла.
Функция 3сh прерывания 21h. Создать файл.
Вход:СХ = атрибут.:DX = адрес на строку в формате ASCIZ.
Выход:CF = 1 - есть ошибка, AX = код ошибки.= 0 - нет ошибки, AX = номер файла.
Функция 3eh прерывания 21h. Закрыть файл.
Вход:BX = номер файла.
Выход:CF = 1 - есть ошибка, AX = код ошибки.
Функция 3fh прерывания 21h. Чтение из файла.
Вход:BX = номер файла.= количество байт, которые необходимо считать.:DX = адрес буфера.
Выход:CF = 1 - есть ошибка, AX = код ошибки.= 0 - нет ошибки, AX = количество считанных байт.
Функция 40h прерывания 21h. Запись в файла.
Вход:BX = номер файла.= количество байт, которые необходимо записать.:DX = адрес буфера.
Выход:CF = 1 - есть ошибка, AX = код ошибки.= 0 - нет ошибки, AX = количество записанных байт.
Функция 4ch прерывания 21h. Завершение программы.
Вход:AL = код завершения.
Выход: ---
6. Тестирование и отладка
Тестирование на ошибочный ввод параметров.
Ввод несуществующего файла в качестве Input file.
Ввод некорректного пути к создаваемому фалу Output file.
Тестирование правильной работы.
Для тестирования правильной работы программы был выбран текстовый документ 1.txt с различными строками, сортировка была произведена в файл 2.txt сначала по возрастанию, потом по убыванию.
Результат тестирования на ошибочный ввод параметров.
Программы выполнила все тесты, выводя соответствующие сообщения об ошибках, тесты не привели к критическому завершению программы.
Результат тестирования правильной работы.
После сортировки файла 1.txt в 2.txt строки были отсортированы в зависимости от выбранного типа сортировки.
Заключение
Программа работоспособна и соответствует предъявленным требованиям. Проделано тестирование программы и соответствующая отладка по устранению ошибок.
Список литературы
1. П. Абель Язык ассемблера для IBM PC и программирования - М.: ЭНТРОП, 2007. -447с.
. Файл руководства по системным функциям - interrup.lst
Приложение А
«Листинг программы»
;Курсовой проект
;Выполнил:Филюк Андрей
;Группа:А-8-07
;Тема:Сортировка строк в текстовом файле
;макрос вывода строки, заканчивающейся $str;в str - адрес выводимой структурыah, 09h;выбор функции вывода строки, заканчивающейся $dx, str;сохраняем адрес в dx
int 21h;выводим строку
.model small
.stack 100h
.datadb 13,10,'Filuk Andrew A-8-07 ',' File sorting ',13,10,'$'db13,10,'Input file: $'db13,10,'Output file: $'db 13,10,'For descending sort need enter key D',13,10,'For ascending sort need enter key A',13,10,'$'db 13,10,'Input key [D/A]:? $'db13,10, 'Press any key.. $'db13,10, 'Done$'db13,10, 'Incorrect input, please try again $'db13,10, 'Sorry, try next time $'
;сообщения об ошибках_0db13,10, ' Error 0: Can not open file $'_1db13,10, ' Error 1: Can not create file $'_2db13,10, ' Error 2: Can not read file $'_3db13,10, ' Error 3: Can not write file $'_4db13,10, ' Error 4: Can not close file $'_5db13,10, ' Error 5: File have only null string $'
num1 EQU 80hdbnum1 DUP(0);путь к файлу, который надо отсортироватьdbnum1 DUP(0);куда сохранить отсортированный файл
flag db 2;флагEQU 1000h
handle1 dw 0;заголовок файла, который надо отсортироватьdw 0;заголовок файла,в который записываем отсортированные строки_file dw 0;кол-во символов в файле_str dw 0;кол-во строк в файлеdb num2 DUP('D') ;данныеdw 100h DUP('#');массив адресов начала строк_num dw 100h DUP('*');массив кол-ва символов в строках
.code:ax, @data;сохраним адрес на сегмент данных в AXds, ax;инициализация сегмента данныхes, ax;инициализация сегмента дополнительных данныхclear;процедура очистки экранаmsg0;вывод сообщенияо о проекте
msg1 ;вывод сообщения на ввод пути вх. файлаdi, file1;сохраним адрес на структуру file1 в diinput_line;вызываем процедуру ввода строкиmsg2;вывод сообщения на вывод пути вых. файлаdi, file2;сохраним адрес на структуру file2 в diinput_line;вызываем процедуру ввода строкиreception_type;процедура определения типа сортировки(по озрастанию или убыванию)open_file;открытие файла, который надо отсортироватьread_file;чтение файлаmake_mas;создание массива начала адресов строкsort;сортировкаmake_mas_num;создание массива кол-ва символов в уже отсортированном массиве адресов строкcreate_file;создание файла для вывода
call write_file;запись в файл
print msg6;вывод сообщенияexit;выход с закрытием файлов
;------------------Получение типа сортировки------------------------_type proc ax;ах в стекmsg3;вывод сообщенияcx,2;кол-во попыток неправильного ввода:msg4;вывод сообщенияdx, flag ;dx указывает на первый байт буфераah,0ah;буферизованный ввод с клавиатуры21hah,02h ;ывод символа на экранdl,0dh;символ возврата коретки (для буфера)
int 21hflag+2, 65;введена клавиша A?
jne k1;нет, переход по метке сравнения с клавишей Dflag,0 ;иначе устанавливаем флаг в 0k3 ;на выход
: cmp flag+2, 68 ;введена ли клавиша D?k2;нет, переход по метке k2flag,1;иначе устанавливаем флаг в 1k3 ;переход по метке: msg7;вывод сообщенияk0 msg8;вывод сообщенияexit2 ;Не введено ни A, ни D, - выход:ax;возврат значения из стека
ret
;------------------------------ Очистка экрана ------------------------------proc
mov ah,00h; Установка видеорежима дисплеяal,03h; Номер видеорежима10h
ret endp
;--------------------------------Ввод строки----------------------------------
input_line proccx, 0;в CX будет храниться количество введенных символов:ah, 07h;выбор функции ввод с клавиатуры без ЭХО21h;ждемal, 08h;проверяем на BackSpacem2;если да - переходим на m2cx, 0;если нет - проверяем есть ли что удалять m0;если строка пуста - возвращаемся на начало и ждем вводаdelete_char;если строка не пуста - стираем с экрана последний введенный символdi;уменьшаем адрес, где сохранен путь на 1cx;уменьшаем количество введенных символов на 1m0;возвращаемся на начало и ждем ввода:ah, 02h;выбор функции вывода символа на экранdl, al;считанный ранее символ хранится в al - записываем его в dl21h;выводим его[di], al;сохраняем по адресу didi;переходим на следующую ячейкуcx;увеличиваем количество введенных символов на 1cl, num1;огранисчение на 80 символовm1;если ввели 80 символом, то считаем что строка введенаal, 0dh;проверяем не нажат ли Enterm0di;возвращаемся в предыдущую ячейку:al, 00h;что бы записать символ конца строки - 0[di], al;записываем
;---------Стереть символ с экрана---------------_charproc
;при работе испортится регистр axax;сохраним его в стекah, 02h;функция вывода символа на экранdl, 08h;символ - Backspace21h;выводим, тем самым переместим курсор влево на 1dl, 20h;символ - space21h;выводим, тем самым сотрем с экрана символ на котором находится курсор
endp
;-----------------Открытие файла-----------------------
open_fileprocnearah, 3dh;функция открытия файлаal, 00; 00 - для чтенияdx, file1;путь к файлу в file121h ;открываемm3;если не было ошибки - то на метку m3err_0;если была ошибка - выводим соотв. сообщениеexit2;завершаем работу:handle1, ax;сохраняем номер файла в handle1
;-----------------Чтение из файла----------------------_fileprocah, 3fh;функция чтения из файлаbx, handle1;номер файла - откуда считатьcx, num2;количество байт, которые надо считатьdx, D;буфер для данных
int 21h;считываемlen_file, ax
jnc m4;если не было ошибки - то на метку m4err_2;если была ошибка - выводим соотв. сообщениеexit;завершаем работу:
;-----------------Создание массива адресов строк-------_mas procax;сохраним его в стекax, len_file;в ах кол-о символов в файлеax,ax;сравнение на нулевой файлm51;нет -> идем по метке создания массиваerr_5;если была ошибка - выводим соотв. сообщениеexit;на выход:bx,bx;обнуляем bxdx,dx;обнуляем dxdi,D;в di адрес начала первой строкиmas[bx],di;заносим её адрес в массивal,0Ah ;поиск ведем по символу конца строки cx,len_file;загрузим кол-во символов в файле;сканирование осуществляем вперед:repne scasb;сканирование в поиcке заданного символа, пока счетчик не обнулиться, остановиться когда найдет символ 0, записанный в albx,2;организация перехода на след. элемент массиваmas[bx],di;заносим адрес начала след. строки в массива
inc dx;+1cx;+1m5
mov num_str, dx;в переменную num_str сохраняем кол-во строкbyte ptr [di],0Dh;добавляем концевой символbyte ptr [di+1],0Ah;добавляем концевой символax;восстановим регистр ax
;-----------------Сортировка строк--------------------procax;заносим ах стек
sort1: si,si;обнуляем si
mov bh, 0;используем bh как флаг, если строки перемещались, то флаг установился в 1cx,num_str;в сх кол-во строк для организации циклаcx;-1cx,0;если в файле одна строка, то сортировка не нужнаsort2;если нет -> сортируемend_sort;иначе выход:ax,ax;обнуляем ахcx;сх стекax,mas[si];адрес начала строки в axdx,mas[si+2];адрес начала след. строки в dxsi;si в стекsi,ax;в si адрес начала строкиdi,dx;в di адрес начала след. строки
dec si;-1di;-1_string:
mov cl,byte[si];в cl заносим символ строкиch,byte[di];в ch заносим символ след. строкиflag,0;определяем тип сравнения. по возрастанию?increase;да -> переход на алгоритм сортировки по возрастанию, иначе по убываниюch,0Dh;сравниваем символ строки с адресом конца строкиnext_string;если равен -> перех к сравнению след. строкcl,0Dh;сравниваем символ след строки с адресом конца строкиchange;если да -> меняемcl,ch;производим сравнение символов находящихся не в концах строк next_simbol;равны следовательно переход по метке к сравнению след символа в строкахcl,ch;сравниваем какой из них "больше"
ja next_string;переход если сl > сh
jmp change;иначе меняем строки : cl,0Dh;сравниваем символ след строки с адресом конца строкиnext_string;если равен -> перех к сравнению след. строкch,0Dh;сравниваем символ строки с адресом конца строкиchange;если да -> меняемcl,ch;производим сравнение символов находящихся не в концах строк next_simbol;равны следовательно переход по метке к сравнению след символа в строкахcl,ch;сравниваем какой из них "больше"
jb next_string;переход если сl < сh
jmp change;иначе меняем строки :ax,dx;меняем адреса строкbh,1;устанавливаем флагnext_string;переход к след. строке_simbol:si;переход к след символу строкиdi;переход к след символу строкиcompare_string;на метку сравнения строк_string:si;возращаем из стека simas[si],ax;заносим адреса отсортированных строк в массив mas[si+2],dx;заносим адреса отсортированных строк в массив cx;возращаем из стека схsi,2;организация перехода к след. строкеsort2bh,0;сравниваем флаг на перемещение строк.end_sort;если не было перемещений -> выходsort1;иначе продолжаем сравнивать_sort:ax;возращаем из стека ах
;-----Создание массива длин отсортированных строк-------
make_mas_num proc ax;заносим ах в стекsi,si;обнуляем sicx, num_str;в сх заносим кол-во строк для организации цикла:cx;заносим сх в стекdi,mas[si];адрес начала строки в axdi;заносим адрес начала в стекal,0Ah ;в al заносим символ который ищем cx,len_file;загрузим максимальный объем;сканирование осуществляем впередscasb;сканирование в поиcке заданного символа, пока счетчик не обнулиться, останоиться когда найдет символ 0, записанный в alax;возвращаем из стекаdi,ax ;вычитаем из di адрес начала строки для получения длины строкиmas_num[si],di;заносим длину строки в массивsi,2;организация перехода к след элементуcx;возращаем изз стека схm6ax;возвращаем из стека ах
ret
;------------------Cоздание файла----------------------_file proc
mov ah, 3ch;функция создания файлаcx, 00h;файл - обычныйdx, file2;file2 - путь к файлу21h;создаемm7;если не было ошибки - то на метку m7err_1;если была ошибка - выводим соотв. сообщениеexit;завершаем работу:handle2, ax;сохраняем номер файла в handle2
;------------------Запись в файл-----------------------
;при входе в процедуру в cx - количество байт для записи
write_file procsi,si;обнуляем si
mov cx, num_str;в сх заносим кол-во строк для организации цикла:cx;заносим сх в стекah,40h;функция записи в файлbx, handle2 ;номер открытого файлаcx,mas_num[si] ;количество символов которые надо dx,mas[si]21h ;записываемm9;если не было ошибки - то на метку m9err_3;если была ошибка - выводим соотв. сообщениеexit;завершаем работу:si,2;переход к след. элементуcx;возвращаем из стека схm8;пока сх не равен нулю возврат по метке m8
ret
;------------------Закрытие файлов-----------------------_file proc
cmp handle1, 0;проверяем был ли открыт файлm10;если нет - закрывать нечего, переходим на m10ah, 3eh;функция закрытия файлаbx, handle1;номер файла21h;закрываемm10;если не было ошибки - то на метку m10err_4;если была ошика - выводим соотв. сообщениеexit;завершаем работу:handle2, 0;проверяем был ли создан файлm11;если нет - закрывать нечего, переходим на m11ah, 3eh;функция закрытия файлаbx, handle2;номер файла21h;закрываемm11;если не было ошибки - то на метку m11err_4;если была ошибка - выводим соотв. сообщениеexit;завершаем работу:
;------------------Выход------------------------------proc
close_file;вызров процедуры закрытия файлов
exit2:msg5;вывод сообщения "Press any key.."
mov ah, 07h;функция ввода с клавиатуры бех ЭХО21h;ждем нажатия клавишиax, 4c00h;выход из программы с кодом возврата 0
int 21h;выходимStart