ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 19.07.2020
Просмотров: 505
Скачиваний: 4
2
.3.
Текст программы
.386
data segment use16
buff_tx db 2048 dup (?) ;Текстовый буфер
point_o dw ? ;Указатель в выходном буфере
cur_n dw ? ;Адрес начала тек. числа в ASCII формате
next_n dw ? ;Адрес начала след. числа
exit db 0 ;Указатель выход/не выход из процедуры
error db 0 ;Указатель ошибки
summ1 dd 0 ;Рез. суммир-ия чисел / на 5 и не / на 7
summ dd 0 ;Результат сложения двух 32-битных чисел
count db 0 ;Кол. чисел / на 5 и не / на 7
del dd 10 ;Делитель
F_Len dw ? ;Длина входного файла
File_in db 'task2_in.txt',0 ;Имя входного файла
Handle1 dw 1 ;Описатель 1-го файла
File_ou db 'task2_ou.txt',0 ;Имя входного файла
Handle2 dw 1 ;Описатель 2-го файла
mes1 db 'Ошибка. Невозможно открыть файла "task2_in.txt".',0ah,0dh,'$'
mes2 db 'Ошибка. Недостаточно данных в исходном файле.',0ah,0dh,'$'
mes3 db 'Ошибка. Разрядность исходного числа превышает формат короткого целого.',0ah,0dh,'$'
mes4 db 'Ошибка. Разрядность результата сложения больше разрядности короткого целого.',0ah,0dh,'$'
mes5 db 'Ошибка. Размер файла больше 2048 байт.'
mes6 db 'Ошибка. Невозможно создать файл "task2_ou.txt".',0ah,0dh,'$'
mes7 db 'Ошибка. Невозможно записать в файл "task2_ou.txt".',0ah,0dh,'$'
mes8 db 'Ошибка. Исходный файл "task2_in.txt" пустой.',0ah,0dh,'$'
mes9 db 'Нет ниодного числа, которое делится на 5 и не делится на 7',0Ah,0Dh,'$'
data ends
stack segment use16 stack
db 100 DUP(?)
stack ends
code segment use16
assume cs:code,ds:data,es:data,ss:stack;
main:
mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
lea dx,File_in
mov ah,3Dh
mov al,0
int 21h ; Открытие файла 'task2_in.txt'
jc Open_e
mov Handle1,ax
mov bx,ax
mov ah,3Fh
mov cx,2048
lea dx,buff_tx
int 21h ; Чтение 2048 байт файла
mov F_len,ax
mov ah,3Eh
mov bx,handle1
int 21h ; Закрытие файла
mov ax,F_len ;Проверка на пустой файл
cmp ax,0
jz err7
cmp ax,2048 ;Проверка на слишком большой файл
jz err3
mov ah,3ch ;Создаём новый файл
lea dx,file_ou ;С именем 'task2_ou.txt
xor cx,cx ;
int 21h
jc err5 ;Если ошибка,идём на обработку
mov Handle2,ax
;-----------------------------------------------------------------------------
;Начинаем обработку входного файла
lea bx,buff_tx ;В ВХ адрес начала буфера
rep1: mov cur_n,bx
call find_n ;Определяем кол-во цифр первого числа
cmp ah,0
jz rep1 ;Повтрить, если число не найдено
mov si,cur_n ;SI-расположение переводимого числа
call ASC_N ;Перевод числа в двойчный формат
cmp error,1
jz term ;Если ошибка, то выходим
mov cx,ax ;В СХ-количество чисел для обработки
mov point_o,offset Buff_tx ;Указатель в буф. для записи уст на нач.
repeat: mov bx,next_n
mov cur_n,bx
call find_n ;Выясняем количество символов числа
mov si,cur_n
call ASC_N ;Переводим число в двойчный формат
cmp error,1
jz term
push eax
xor edx,edx
mov ebx,5
div ebx ;Делим число на 5
cmp edx,0
pop eax
jnz rep3 ;Если не делится, то переходим к след.
push eax
mov ebx,7
div ebx ;Делим число на 7
cmp edx,0
pop eax
jz rep3 ;Если делится на 7, то переходим к след.
inc count ;Увеличиваем счётчик количества чисел
add summ1,eax ;Суммируем числа
jc err2 ;Если переполнение идём на обработку
mov di,point_o
call N_ASC ;Записываем числа в ASCII формате в буф.
add bx,point_o
mov [bx],byte ptr ','
inc bx
mov point_o,bx ;Увеличиваем указатель в буфере
rep3:
mov bx,next_n
sub bx,offset buff_tx
cmp bx,F_len ;Если достигнут конец файла, то выходим
ja err4
rep4: loop repeat
cmp count,0
jz err8
dec point_o ;Уменьшаем указатель, затирая запятую
mov bx,point_o ;
mov [bx],word ptr 0d0ah ;Заносим в буфер LF и CR
inc point_o ;
inc point_o ;Увеличиваем указатель на 2
xor eax,eax
mov al,count
mov di,point_o
call N_ASC ;Выводим количество чисел
add point_o,bx
mov bx,point_o
mov [bx],word ptr 0d0ah
inc point_o
inc point_o
mov eax,summ1
mov di,point_o
call N_ASC ;Выводим их сумму
add point_o,bx
lea dx,buff_tx
mov cx,point_o
sub cx,offset buff_tx
output: mov bx,Handle2
mov ah,40h ;Записываем в файл
int 21h
jc err6 ;Если ошибка идём на обработку
jmp end_p
Open_e: ; Вывод сообщения об ошибке открытия
lea dx,mes1
mov ah,09h
int 21h
jmp end_p
err2: lea dx,mes4 ;Вывод сообщения об ошибке сложения
mov ah,09
int 21h
lea dx,mes4
jmp end_p
err3: lea dx,mes5 ;Вывод сообщения о большом размере файла
mov ah,09
int 21h
jmp end_p
err4: cmp cx,1 ;Если все заявленные в начале числа про-
jz rep4 ;верены, то завершаем цикл.
lea dx,mes2 ;Вывод сообщ. о недостатке данных
mov ah,09
int 21h
jmp end_p
err5: lea dx,mes6 ;Выв. сообщения об ошибке создания файла
mov ah,09
int 21h
jmp end_p
err6: lea dx,mes7 ;Выв. сообщения об ошибке записи в файл
mov ah,09
int 21h
mov bx,Handle2 ;Закрытие файла
mov ah,3eh
int 21h
jmp end_p
err7: lea dx,mes8 ;Вывод сообщения о пустом исходном файле
mov ah,09h
int 21h
jmp end_p
err8: lea dx,mes9 ;Нет ниодного числа / на 5 и не / на 7
mov ah,09
int 21h
jmp end_p
Term: jmp end_p
;-----------------------------------------------------------------------------
;Процедура ищет в строке с адресом [bx] число, занося в AH кол-во цифр числа, и занося
;в ячейку next_n и регистр BX адрес след. числа
find_n proc near
push cx
mov exit,0
mov ah,0
begin:
push bx
sub bx,offset buff_tx
cmp bx,F_len ;Проверяем достигнут ли конец файла
pop bx
ja f_exit
mov al,[bx]
cmp al,30h
jnc down1 ; Если выше или равно
inc bx
mov exit,1
jmp begin
down1: cmp al,3Ah
jc adding ; Если ниже
inc bx
mov exit,1
jmp begin
adding:
cmp exit,1
jz f_exit ; Выход, если BX на позиции след. числа
inc ah ; Увеличиваем счётчик кол-ва цифр
inc bx ; Сдвигаем указатель
jmp begin ; На начало
f_exit: mov next_n,bx
pop cx
ret
find_n endp
;------------------------------------------------------------------------------
;Процедура преобразует число в ASCII символах длины AH, по адресу [SI]
;в двоичный формат, помещая его в EAX, error=1 означает ошибку
ASC_N proc near
push cx
mov summ,dword ptr 0
mov bl,ah
xor bh,bh
mov ecx,1
xor dx,dx
rep2:
cmp bl,0
jz end2
xor eax,eax
mov al,[SI+BX-1]
xor ax,30h
mul ecx
add summ,eax
jc err1 ;Если ошибка переполнения
mov eax,ecx
mul del
mov ecx,eax
dec bx
jmp rep2
err1: mov error,1
mov ah,09
lea dx,mes3
int 21h
end2: mov eax,summ
pop cx
ret
ASC_N endp
;------------------------------------------------------------------------------
;Процедура преобразует число (короткое целое) из 2-го формата из рег-ра EAX
;в набор ASCII символов и размещает их по адресу DI, BX содержит кол-во цифр.
N_ASC proc near
xor bx,bx
beg1:
xor edx,edx
div del ;Делим на 10
or dx,30h ;Прибавляем к остатку 30h
push dx ;Сохраняем в стеке
inc bx ;Увеличиваем счётчик кол-ва цифр
cmp eax,0
jnz beg1 ;Если частное>0 то перевод не закончен
mov dx,bx
xor bx,bx
fill: ;Размещаем символы из стека по адресу DI
pop ax
dec dx
mov byte ptr [di+bx],al
inc bx
cmp dx,0
jnz fill
ret
N_ASC endp
end_p:
mov bx,Handle2 ;Закрытие выходного файла
mov ah,3eh
int 21h
mov ax,4c00h
int 21h
code ends
end main
2.4 Результаты работы программы
Тест 1.
Исходный файл task2_in.txt
14,145,70,90,19,14,20,35,90,5,15,190,280,98,28
Полученный файл task2_ou.txt
145,90,20,90,5,15,190
7
555
Тест 2.
Исходный файл task2_in.txt
3,4110212900,3500000000,100000
Полученный файл task2_ou.txt
4110212900,100000
2
4110312900
Тест 3.
Исходный файл task2_in.txt
4,4110212900,3500000000,100000
Полученный файл task2_ou.txt
Ошибка. Недостаточно данных в исходном файле.
Тест 4.
Исходный файл task2_in.txt
2,4110212900000,35
Полученный файл task2_ou.txt
Ошибка. Разрядность исходного числа превышает формат короткого целого.
3. Лабораторная работа №10
3.1. Задание
Даны 2 символьных файла f1 и f2. Файл f1 содержит произвольный текст. Слова в тексте разделены пробелами и знаками препинания. Файл f2 содержит слова, разделённые запятыми. Эти слова образуют пары: каждое первое слово считается заменяемым, каждое второе заменяющим. Найти в файле f1 все заменяемые слова и заменить их на соответствующие заменяющие. Результат поместить в файл g. После преобразования тестовый файл g необходимо сформатировать.
3
.2.
Блок-схема алгоритма