Автор работы: Пользователь скрыл имя, 26 Января 2014 в 09:55, контрольная работа
Разработать программу на языке Ассемблера Intel x86 для ОС MS-DOS. Программа при запуске выводит приветствие с ФИО исполнителя и текст задания и ожидает ввода строки от пользователя, затем находит в файле otchet.txt введенную строку. Успех/неуспех сообщается на экране.
КОНТРОЛЬНАЯ РАБОТА
по дисциплине
«Машинно-ориентированные языки»
тема
«Поиск подстроки в файле»
Выполнил:
Проверил:
ЗАДАНИЕ
Разработать программу на языке Ассемблера Intel x86 для ОС MS-DOS. Программа при запуске выводит приветствие с ФИО исполнителя и текст задания и ожидает ввода строки от пользователя, затем находит в файле otchet.txt введенную строку. Успех/неуспех сообщается на экране.
ЛИСТИНГ ПРОГРАММЫ
.model tiny ; Модель tiny - вся программа размещается в 1-ом
.code ; сегменте (менее 64КБ)
org 100h
PRINT MACRO STR ; макроподстановка для печати сообщений
lea DX, STR
mov AH, 9h ; 09h - функция вывода на экран
int 21h
ENDM
start:
mov AX, CS ; данные и код находятся в одном сегменте
mov DS, AX
mov ES, AX
PRINT s1
lea dx,in_buf ; ввод строки с клавиатуры
mov ah,0ah
int 21h
call read_file ; считываем содержимое файла
cmp in_size,1 ; проверим размер введенной подстроки
ja norm_find
call find_single ; тривиальный поиск одного символа
jmp rezult
norm_find:
mov al,in_size ; проверим: размер файла больше строки ?
xor ah,ah
cmp ax,read_size
ja rezult ; строка для поиска меньше размера файла
call find_string ; поиск подстроки
rezult: ; результат поиска передаем во флагах
lea dx,res_yes
je r_yes ; проверяем переданный из процедур флаг
lea dx,res_no
r_yes:
mov AH, 9h ; 09h - функция вывода на экран
int 21h
mov ah,01h ; ожидаем ознакомления пользователя с результатом
int 21h
mov ax, 4c00h ; корректное завершение программы
int 21h
error: ; обработчик ошибок файловой подсистемы
PRINT s_err
mov ah,01h ; ожидаем ознакомления пользователя с ошибкой
int 21h
mov ax, 4c01h ; завершение программы c кодом ошибки
int 21h
ret
;-----------------------------
read_file PROC ; процедура открывает файл, определяет размер, считывает в буфер
lea dx,fname ; открываем на чтение файл otchet.txt
mov ax,3d00h
int 21h
jc error
mov f_handle,ax ; сохраним дескриптор файла
mov ax,4202h ; определяем размер файла
mov bx,f_handle
xor cx,cx
xor dx,dx
int 21h
jc error ; размер в DX:AX
mov read_size,800h ; на всякий случай продублируем максимальный размер
cmp dx,0 ; если dx=0, то файл маленький
jne large_file
cmp ax,800h ; сравниваем с размером буфера
ja large_file
mov read_size,ax ;если файл помещается в буфер, то считываем
; файл целиком
large_file:
mov ax,4200h ; возвращаем указатель на начало файла
mov bx,f_handle
xor cx,cx
xor dx,dx
int 21h
jc error
mov ah,3fh ; читаем из файла
mov bx,f_handle
lea dx,file_buffer
mov cx,read_size
int 21h
jc error
mov ah,3eh ; закрываем файл
mov bx,f_handle
int 21h
jc error
ret ; возвращаемся в основную программу
ENDP
;-----------------------------
; процедура поиска одиночного символа в массиве
find_single PROC
mov al,in_str
mov cx,read_size
lea si,file_buffer
sing_loop:
cmp al,[si]
; сравниваем наш символ с
je single_ret ; если флаг выставлен - сразу выходим
inc si
loop sing_loop
cmp al,file_buffer ; сбрасываем флаг после команды loop
single_ret:
ret
ENDP
;-----------------------------
; процедура поиска подстроки в массиве
find_string PROC
mov ax,word ptr in_str ; сначала ищем пару начальных символов в буфере и
; введенной строке (для скорости)
mov cx,read_size
xor dh,dh
mov dl,in_size
sub cx,dx ; нет смысла искать начало строки там,
inc cx ; где строка уже не помещается
lea bx,file_buffer
first_loop:
cmp ax,[bx] ; сравниваем нашу пару символов с содержимым буфера
je full_find ; если совпали первые 2 символа - пытаемся сравнивать
; все строку
body_loop:
inc bx
loop first_loop
cmp ax,word ptr file_buffer ; сбрасываем флаг после команды loop
ret
; блок кода сравнения всей строки
full_find: ; используем команды работы со строками для полного сравнения строк
push cx ; сохраняем счетчик основного цикла в стеке
cld
lea si,in_str
xor ch,ch
mov cl,in_size
mov di,bx
rep cmpsb ; сравнение двух строк
pop cx ; забираем значение из стека
jne body_loop ; если строки не совпали - возвращаемся в основной цикл
ret
ENDP
;=============================
;-------------------- Данные --------------
;Буфер для ввода с клавиатуры
in_buf DB 50d
in_size DB 0
in_str DB 52 DUP(?)
; имя файла
fname DB 'otchet.txt',0
; дескриптор файла
f_handle dw ?
; строка приветствия
s1 DB 10,13,10,13,10,13,10,13
DB '
г=============================
DB ' │ Семестровая работа №2 │ ',10,13
DB ' │ Поиск введенной подстроки в файле otchet.txt│ ',10,13
DB ' │ Выполнил студент .... │ ',10,13
DB '
L=============================
DB 10,13,10,13,10,13,10,13
DB ' Введите искомую подстроку (не более 50 символов) ! ',10,13,10,13,'$'
; Сообщение о файловой ошибке
s_err db 10,13,10,13
DB 'Файловая ошибка, программа завершена аварийно !!!$'
res_yes db 10,13
db 'Введенная подстрока в файле otchet.txt найдена $'
res_no db 10,13
db 'Введенная подстрока НЕ найдена в файле otchet.txt $'
; считываемый размер данных из файла
read_size dw 800h
; сюда считываем файл
file_buffer db ?
org 800h
end start