Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- .model small
- .386
- .stack 100h
- .data
- ;##########################################################################
- ;################################## Данные #############################
- ;##########################################################################
- ; Информационные сообщения выдаваемые на экран
- msg0 db 'Dlya vklu4enia rezhima dekodirovania nazhmite "d": $'
- msg1 db 'Vvedite imia vhodnogo faila $'
- msg2 db 'Vvedite imia vihodnogo faila $'
- msg3 db 'Vvedite kluch (sostoyashii iz simvolov 1..'
- num label byte
- db ' ) : $'
- msg4 db 'Diestvie zaversheno! $'
- msg5 db 'rezhim - kodirovanie$'
- msg6 db 'rezhim - Dekodirovanie$'
- ; сообщения об ошибках
- open_file_error db 'ERROR: Oshibka pri otkritii faila$'
- read_file_error db 'ERROR: Oshibka pri chtenii iz faila$'
- create_file_error db 'ERROR: Oshibka sozdania faila$'
- close_file_error db 'ERROR: Oshibka pri zakritii faila$'
- write_file_error db 'ERROR: Oshibka pri zapisi v vail$'
- key_format_error db 'ERROR: Oshibka pri vvode klucha$'
- source_empty_err db 'ERROR: Ishodnii fail pust$'
- source_format_err db 'ERROR: Ishodnii fail povrezden$'
- ; Список параметров для ввода имени входного файла
- inputfilepar label byte
- max_len_in db 80 ; максимальная длина
- act_len_in db 80 ; фактическая длина
- inputf db 80 dup (0) ; область для хранения имени входного файла
- ; Список параметров для ввода имени выходного файла
- outputfilepar label byte
- max_len_out db 80 ; максимальная длина
- act_len_out db 80 ; фактическая длина
- outputf db 80 dup (0) ; область для хранения имени выходного файла
- ; Список констант задающих параметры кодирования
- bloc equ 8 ; константа длины ключа
- blocj equ 3 ; доп. параметр размера блока кодирования
- bsize equ bloc*blocj ; резервировано: должно быть bsize
- ; Список параметров для ввода значения ключа
- key_choose label byte
- nkeylen db bloc +1 ; максимальная длина
- ankeylen db bloc +1 ; фактическая длина
- nkey db bloc +1 dup (0) ; область для хранения ключа
- nbuf db bsize +1 dup (0) ; область для хранения данных выходного буфера
- fsize label dword
- fsize_low dw ?
- fsize_high dw ?
- ; Дескрипторы файлов
- input_handle dw ? ; дескриптор входного файла
- output_handle dw ? ; дескриптор выходного файла
- ; Флаги и Прочие данные
- ERRID db 0 ; флаг ошибки
- temp1 db bsize +1 dup ('0') ; для хранения блока данных
- it db ?
- jt db ?
- PARAM1_ID db 0 ; флаг ввода 1ого параметра
- PARAM2_ID db 0 ; флаг ввода 2ого параметра
- PARAM3_ID db 0 ; флаг ввода 3его параметра
- CODERING db 1 ; флаг режима работы
- ;##########################################################################
- ;################################ Макросы ##############################
- ;##########################################################################
- ; Макрос: ввод строки в буффер
- entbuff macro string
- mov ah,0Ah
- lea dx,string
- int 21h
- endm
- ; Макрос: вывод строки на экран
- dispstr macro string
- mov ah,9h
- lea dx,string
- int 21h
- endm
- ; Макрос: вывод строки на экран
- dispstr2 macro string,strl1
- mov ah,40h
- mov bx,0
- xor cx,cx
- mov cl,strl1
- lea dx,string
- int 21h
- endm
- ;##########################################################################
- ;##################### Начало основного тела программы ################
- ;##########################################################################
- .code
- start:
- push offset nkey ; адрес переменной ключа
- push offset outputf ; адрес переменной имены выходного файла
- push offset inputf ; адрес переменной имены входного файла
- call ReadCmdParam ; вызов процедуры чтения параметров запуска
- mov ax,@data ; инициализация
- mov ds,ax ; сегментных
- mov es,ax ; регистров
- call InitParams ; вызов процедуры инифиализации параметров
- call SetMode ; установка режима работы (кодирование / декодирование)
- call openf ; вызов процедуры открытия файла
- cmp ERRID,0
- jne ProgEX
- call KeyToNum ; обработка ключа
- cmp ERRID,0
- jne ProgEX
- call createf ; создание нового файла
- cmp ERRID,0
- jne ProgEX
- cmp CODERING,0 ; выбор режима работы
- je go_decode
- call WriteLn
- dispstr msg5
- call WriteLn
- call EncodeFile ; кодирование и запись нового файла
- jmp gogo
- go_decode:
- call WriteLn
- dispstr msg6
- call WriteLn
- call DecodeFile ; декодирование запись нового файла
- gogo:
- cmp ERRID,0
- jne ProgEX
- call closef ; закрытие файлов
- cmp ERRID,0
- jne ProgEX
- call WriteLn
- dispstr msg4 ; вывод конечного сообщения
- ProgEX:
- mov ah,8h ; ожидание нажатия клавиши
- int 21h
- mov ax,4C00h ; завершение программы
- int 21h
- ;##########################################################################
- ;################## процедура ввода режима работы ####################
- ;##########################################################################
- SetMode proc
- call WriteLn
- dispstr msg0 ; вывод пригласительного сообщения
- loopem:
- mov ah, 01h
- int 21h
- cmp al,'d' ; если введенный символ d, то режим - декодирование
- jne set_1 ; иначе кодирование
- mov CODERING,0
- jmp endsetmode
- set_1:
- mov CODERING,1
- jmp endsetmode
- endsetmode:
- call WriteLn
- ret
- SetMode endp
- ;##########################################################################
- ;################## процедура ввода параметров #######################
- ;##########################################################################
- InitParams proc
- call WriteLn
- dispstr msg1 ; вывод сообщения об имени исходного файла
- cmp PARAM1_ID,1
- jne h_1
- dispstr2 inputf,act_len_in
- call WriteLn
- jmp h_11
- h_1:
- entbuff inputfilepar ; ввод имени
- call WriteLn
- xor bx,bx
- mov bl,act_len_in
- mov inputf[bx],0 ; установка символа конца имени файла
- h_11:
- mov al,bloc
- add al,30h
- mov [num],al ; установка длины ключа в строку вывода сообщения
- dispstr msg2 ; запрос на ввод имени выходного фаила
- cmp PARAM2_ID,1
- jne h_2
- dispstr2 outputf,act_len_out
- call WriteLn
- jmp h_22
- h_2:
- entbuff outputfilepar ; ввод имени
- call WriteLn
- xor bx,bx
- mov bl,act_len_out
- mov outputf[bx],0 ; установка символа конца имени файла
- h_22:
- dispstr msg3 ; запрос на ввод числа изменения
- cmp PARAM3_ID,1
- jne h_3
- dispstr2 nkey,ankeylen
- call WriteLn
- jmp h_33
- h_3:
- entbuff key_choose ; запоминаем ключ в символьном виде
- call WriteLn
- h_33:
- ret
- InitParams endp
- ;##########################################################################
- ;################# процедура чтения параметров запуска ###################
- ;##########################################################################
- ReadCmdParam proc, filein:word, fileout:word, keypass:word
- push bp
- mov bp,sp
- push ds ; процедура ReadCmdParam меняет содержимое регистров ds и es
- push es ; поэтому сохраним их в стеке
- push ax ; поэтому сохраним их в стеке
- mov ax,@data
- mov es, ax ;Копируем в es адрес сегмента данных
- mov si, 81h ;Смещение в PSP строки параметров
- xor cx,cx
- mov cl, ds:[si-1] ;Загрузка длины строки параметров
- cmp cx,0 ;проверяем, есть ли параметры
- je param_error ;Выход из процедуры если их нет
- probel:
- cmp byte ptr [si], 20h ; Убираем начальные пробелы в строке параметров
- jne readpar
- inc si
- loop probel
- cmp cx,0
- jz param_error ; Если вся строка состоит из пробелов, то ошибка
- readpar:
- mov es:PARAM1_ID,1
- mov es:it,1
- mov di,filein ; Загрузка адреса переменной имени входного файла
- inF:
- cld
- movsb ; Посимвольная запись
- cmp byte ptr [si],20h ; Если пробел, переход к следующей переменной
- je keyst
- cmp byte ptr [si],0Dh ; Если конец строки, ошибка ввода параметров
- je param_error
- add es:it,1
- jmp inF
- keyst:
- mov ah,es:it
- mov es:act_len_in,ah
- mov es:PARAM2_ID,1
- mov es:it,1
- mov di,fileout ;Загрузка адреса переменной имени выходного файла
- inc si
- keyst1:
- cld
- movsb ; Посимвольная запись
- cmp byte ptr [si],20h ; Если пробел, переход к следующей переменной
- je OuF
- cmp byte ptr [si],0Dh ; Если конец строки, ошибка ввода параметров
- je param_error
- add es:it,1
- jmp keyst1
- OuF:
- mov ah,es:it
- mov es:act_len_out,ah
- mov es:it,1
- mov es:PARAM3_ID,1
- mov di,keypass ; Загрузка адреса переменной ключа
- inc si
- OuF1:
- movsb ; Посимвольная запись
- cmp byte ptr [si],20h ; Если пробел или конец строки, выход из процедуры без ошибки
- je NoErrPar
- cmp byte ptr [si],0Dh
- je NoErrPar
- add es:it,1
- jmp OuF1
- NoErrPar:
- mov ah,es:it
- mov es:ankeylen,ah
- movsb ; Посимвольная запись
- cmp byte ptr [si],20h
- clc ; Сброс флага переноса (факт верно введенных параметров)
- jmp ParEx
- param_error:
- stc ; Установка флага переноса (факт неверно введенных параметров)
- ParEx:
- pop ax
- pop es
- pop ds
- pop bp
- ret 6
- ReadCmdParam endp
- ;##########################################################################
- ;################## процедура открытия файла ############################
- ;##########################################################################
- openf proc
- mov ah,3Dh
- mov al,00
- lea dx,inputf
- int 21h ; открытие файла
- jc openf_error ; переход в случае ошибки
- mov input_handle,ax ; запоминание дескриптора файла
- ret
- openf_error:
- dispstr open_file_error ; вывод сообщения об ошибке
- mov ERRID,01 ; запись факта ошибки
- ret
- openf endp
- ;##########################################################################
- ;################# процедура перехода на следующую строку #################
- ;##########################################################################
- WriteLn proc
- mov ah, 02h
- mov dl, 0Ah
- int 21h ; переход на следующую строку
- mov ah, 02h
- mov dl, 0Dh
- int 21h ; возврат каретки
- ret
- WriteLn endp
- ;##########################################################################
- ;################ процедура перевода код ключа в число #################
- ;##########################################################################
- KeyToNum proc
- xor cx,cx ; зануление счетчика
- mov cl,bloc ; загружаем длину строки
- xor ax,ax ; обнуляем регистры ax и dx
- lea si,nkey ; загружаем адрес начала символов значения
- lea di,nkey
- key_length:
- lodsb ; загружаем символ в al
- sub al,49 ; переводим в число
- jc key_error
- mov ah,bloc
- dec ah
- cmp al,ah ; дальность пермещения не может быть больше чем (рзмер блока - 1)
- ja key_error
- stosb ; загружаем переведенные числа опять в ту же стороку
- loop key_length
- ret
- key_error:
- call WriteLn ; перевод строки
- dispstr key_format_error ; сообщение об ошибке
- mov ERRID,01 ; запись факта ошибки
- ret
- KeyToNum endp
- ;##########################################################################
- ;################# процедура создания файла #######################
- ;##########################################################################
- createf proc
- lea si,inputf ; сравниваем имена входного и выходного файлов
- lea di,outputf
- xor cx,cx
- mov cl,80
- cld
- repe cmpsb ; посимвольная проверка имен фаилов
- jz create_error ; если одинаковые - ошибка
- mov ah,5Bh
- mov cx,00
- lea dx,outputf
- int 21h ; создаем новый файл
- jc create_error ; переход, если произошла ошибка создания или фаил с таким именем существует
- mov output_handle,ax ; сохраняем дескриптор файла
- ret
- create_error:
- dispstr create_file_error; сообщение об ошибке
- mov ERRID,01 ; запись факта ошибки
- ret
- createf endp
- ;##########################################################################
- ;######################### процедура закрытия файла #####################
- ;##########################################################################
- closef proc
- mov ah,3Eh
- mov bx,input_handle ; загружаем дескриптор
- int 21h ; закрываем файл
- mov bx,output_handle ; загружаем дескриптор
- int 21h ; закрываем файл
- jc CLOUTERR
- jmp CLOSE1
- CLOUTERR:
- dispstr create_file_error ; сообщение об ошибке
- mov ERRID,01 ; запись факта ошибки
- CLOSE1:
- ret
- closef endp
- ;##########################################################################
- ;######################### процедура получения размера файла ############
- ;##########################################################################
- GetFileSize proc
- push ax ; сохранение регистров
- push bx
- push cx
- push dx
- mov ah,42H ;функция перемещения указателя
- MOV al,2 ;код установки на конец файла
- MOV bx,input_handle ;номер файла в BX
- MOV cx,0 ;0 в CX и DX
- MOV dx,0 ;
- INT 21H ;сдвигаем указатель
- MOV fsize_high,dx ;запоминаем размер файла
- MOV fsize_low,ax ;
- mov ah,42H ;функция перемещения указателя
- MOV al,0 ;код установки на начало файла
- MOV bx,input_handle ;номер файла в BX
- MOV cx,0 ;0 в CX и DX
- MOV dx,0 ;
- INT 21H ;сдвигаем указатель
- pop dx ;восстановление регистров
- pop cx
- pop bx
- pop ax
- ret
- GetFileSize endp
- ;##########################################################################
- ;######################## процедура кодирования #########################
- ;##########################################################################
- EncodeFile proc
- call GetFileSize ; получаем размер исходного файла в переменную fsize
- cmp fsize,0
- je error_empty
- mov ah,40h
- mov bx,output_handle ; загружаем дескриптор нового файла
- mov cx,4 ; записываем число обработанных байтов в счетчик
- lea dx,fsize ; адрес блока записывемый в файл
- int 21h ; переписываем в новый файл размер исходного файла
- jc l_write_error
- main_coder:
- cmp fsize,bsize
- jnb not_mix
- mov cx,bsize
- push si
- mov si,0
- dec cx
- mixing: ; если размер данных меньше блока заполним
- mov ah,0 ; сначала буфер псевдослучайными значениями таймера
- push cx
- int 1Ah
- add dl,50
- add temp1[si],dl
- pop cx
- inc si
- loop mixing
- pop si
- not_mix:
- mov ah,3Fh
- mov bx,input_handle ; дскриптор исходного файла
- mov cx,bsize ; считываем bsize байт в память
- lea dx,temp1
- int 21h ; считываем значения в память, начиная со смещения temp1
- jc l_read_error
- cmp ax,0 ; проверяем сколько байт считано
- je endwr ; если 0, то файл закончился
- mov cx, bloc
- lea bx,nbuf
- mov it,0 ; счетчик it: 0<=it<=(bsize-1)
- col_loop: ; цикл по столбцам
- mov jt,0 ; счетчик jt: 0<=jt<=(blocj-1)
- raw_loop: ; цикл по строкам
- mov al,jt
- mov bh,bloc
- mul bh
- mov bx,ax ; в bx заносим jt*bloc
- xor ax,ax ; в ax заносим 0
- mov al,bloc
- sub ax,cx
- mov di,ax ; в di - номер обрабатываемого столбца
- mov al,[bx+di+offset(temp1)]
- push ax ; заносим в стек текущий байт данных
- mov al,nkey[di]
- mov bh,blocj
- mul bh
- mov bx,ax ; bx = ключ_столбца*blocj
- xor ax,ax ; в ax заносим 0
- mov al,jt
- mov di,ax ; в di заносим jt
- pop ax ; извлекаем из стека байт данных
- mov [bx+di+offset(nbuf)],al ;помещаем байт в буфер
- inc it
- inc jt
- cmp jt,blocj
- jne raw_loop
- loop col_loop ; конец цикла по колонкам
- mov ah,40h
- mov bx,output_handle ; загружаем дескриптор нового файла
- mov cx,bsize ; bsize бай будет записано
- lea dx,nbuf
- int 21h ; переписываем в новый файл кодированный блок данных
- jc l_write_error
- sub fsize,bsize
- jmp main_coder
- error_empty:
- dispstr source_empty_err; сообщение об ошибке
- mov ERRID,01 ; запись факта ошибки
- ret
- l_read_error:
- dispstr read_file_error ; сообщение об ошибке
- mov ERRID,01 ; запись факта ошибки
- ret
- l_write_error:
- dispstr write_file_error ; сообщение об ошибке
- mov ERRID,01 ; запись факта ошибки
- endwr:
- ret
- EncodeFile endp
- ;##########################################################################
- ;######################## процедура ДЕкодирования #######################
- ;##########################################################################
- DecodeFile proc
- mov ah,3Fh
- mov bx,input_handle ; дескриптор файла
- mov cx,4 ; считываем 4 байта
- lea dx,fsize
- int 21h ; считываем реальный размер декодированного файла в fsize
- jc dl_read_error
- main_decoder:
- mov ah,3Fh
- mov bx,input_handle ; дескриптор файла
- mov cx,bsize ; считываем bsize байт в память
- lea dx,temp1
- int 21h ; считываем блок данных в память
- jnc d_go_krypt
- jmp dl_read_error
- d_go_krypt:
- cmp ax,0 ; проверяем сколько байт считано
- jne d_nf10 ; если 0, то файл закончился
- ret
- d_nf10:
- cmp ax,bsize
- jb error_2
- push ax
- mov cx, bloc
- lea bx,nbuf
- mov it,0 ; счетчик it: 0<=it<=(bsize-1)
- d_col_loop: ; счетчик по столбцам
- mov jt,0 ; счетчик jt: 0<=jt<=(blocj-1)
- d_raw_loop: ; счетчик по строкам
- xor ax,ax ; заносим в ax - 0
- mov al,bloc
- sub ax,cx
- mov di,ax
- mov al,nkey[di]
- mov bh,blocj
- mul bh
- mov bx,ax
- xor ax,ax ; заносим в ax - 0
- mov al,jt
- mov di,ax
- mov al,[bx+di+offset(temp1)]
- push ax ;помещаем байт данных в стек
- mov al,jt
- mov bh,bloc
- mul bh
- mov bx,ax ; в bx заносим ax
- xor ax,ax ; заносим в ax - 0
- mov al,bloc
- sub ax,cx
- mov di,ax
- pop ax ; восстановление байта данных из стека
- mov [bx+di+offset(nbuf)],al ; заносим в al текущийц байт данных
- inc it
- inc jt
- cmp jt,blocj
- jne d_raw_loop
- loop d_col_loop
- mov ah,40h
- mov bx,output_handle ; загружаем дескриптор нового файла
- pop cx ; записываем число обработанных байтов в счетчик
- cmp fsize,bsize
- jnb sub_b_size
- mov cx,word ptr fsize
- sub_b_size:
- lea dx,nbuf
- int 21h ; переписываем в новый файл
- jc dl_write_error
- sub fsize,bsize
- jmp main_decoder
- error_2:
- dispstr source_format_err ; сообщение об ошибке
- mov ERRID,01 ; запись факта ошибки
- ret
- dl_read_error:
- dispstr read_file_error ; сообщение об ошибке
- mov ERRID,01 ; запись факта ошибки
- ret
- dl_write_error:
- dispstr write_file_error ; сообщение об ошибке
- mov ERRID,01 ; запись факта ошибки
- d_endwr:
- ret
- DecodeFile endp
- end start
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement