Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- .model small ;один сегмент кода, данных и стека
- .stack 100h
- .386
- .data ;сегмент данных
- ;Объявление переменных
- file1 db 0fh dup (0) ; Имена файлов
- file2 db 0fh dup (0) ;
- file3 db 0fh dup (0) ;
- ident1 dw 0 ; Идентификаторы файлов
- ident2 dw 0 ;
- ident3 dw 0 ;
- headline1 db 2ch dup (?) ; Буферы для заголовков
- headline2 db 2ch dup (?) ;
- bufblock db 0efffh dup (00h) ; буфер чтения блока
- format db 'RIFFWAVEdata' ; формат RIFF для проверки файлов на соответствие RIFF структуре
- ; Сообщения выводимые пользователю
- noparammsg db 'Enter the parameters',0dh,0ah,'$' ; если программа запущена без параметров
- nofile2msg db 'No second file',0dh,0ah,'$' ; если в параметрах не указано имя 2-го файла
- m_par_nofn3 db 'No third file',0dh,0ah,'$' ; если в параметрах не указано имя 3-го файла
- file1msg db ' First wav-file:',0dh, 0ah, '$' ; начало работы с 1-м файлом
- file2msg db ' Second wav-file:',0dh, 0ah, '$' ; начало работы со 2-м файлом
- combfiles db ' Combining files:',0dh, 0ah, '$' ; начало склейки файлов
- openfilemsg db 'Opening: $' ; попытка открыть файл
- createfile db 'Creating new file: $' ; попытка создать файл
- okmsg db 'Done',0dh,0ah,'$' ; успешно
- errmsg db 'Error',0dh,0ah,'$' ; ошибка
- readerrmsg db 'Read: Error',0dh,0ah,'$' ; ошибка при чтении файла
- writtingerrmsg db 'Writing: Error',,0dh,0ah,'$' ; ошибка при записи
- writtingnoerr db 'Writing: Done',0dh,0ah,'$' ; успешная запись
- formaterrormsg db 'Format: Error',0dh,0ah,'$' ; формат фалйа не верный
- formsuccmsg db 'Format: Correct',0dh,0ah,'$' ; формат фалйа верный
- comperrormsg db 'Compatibility: Error',0dh,0ah,'$' ; при несовместимости
- compsucc db 'Compatibility: Ok',0dh,0ah,'$' ; файлы совместимы
- overflorerrmsg db 'The file is too large',0dh,0ah,'$' ; при переполнении
- succcomb db ' Files successfully combined',0dh,0ah,'$' ; успешная склейка
- .code
- ; начало программы
- start:
- mov ax, @data ; инициализация сегмента es
- mov es, ax ;
- push es ; сохранение es для последующего восстановления в ds
- mov cl, ds:[80h] ; в CL заносится длина параметров командной строки
- cmp cl, 0 ; если она равна 0
- jz er_empty ; вывод сообщения об ошибке
- ; считывание названий
- lea di, file1 ; адреса строк заносятся в регистры
- lea dx, file2 ;
- lea bx, file3 ;
- call parread ; вызов процедуры для чтения названий файлов
- pop ds ; восстановить ds
- cmp file2,0 ; если нет имени второго файла
- je nofile2 ; вывести сообщение об ошибке
- cmp file3,0 ; если нет имени третьего файла
- je nofile3 ; вывести сообщение об ошибке
- mov ah, 9h ; вывод информации о первом файле
- lea dx, file1msg ;
- int 21h ;
- mov ah, 9h ; Информация об открытии файла
- lea dx, openfilemsg ;
- int 21h ;
- ; считывание идентификатора
- mov ah, 3dh ; вызов функции открытия файлов
- lea dx, file1 ; адрес имени файла
- lea bx, ident1 ; адрес идентификатора файла
- call openfileproc ; вызов процедуры открытия файла
- jc exit_prog ; в случае ошибки - выход
- ; проверка на соответствие формату RIFF
- mov bx, ident1 ; идентификатор файла в BX
- lea dx, headline1 ; адрес буфер для первого заголовка
- call wavcheck ; вызов процедуры проверки формата заголовка
- jc exit_prog ; в случае ошибки - выход
- jne exit_prog ;
- mov ah, 9h ; вывод информации о втором файле
- lea dx, file2msg ;
- int 21h ;
- mov ah, 9h ; Информация об открытии файла
- lea dx, openfilemsg ;
- int 21h ;
- ; считывание идентификатора
- mov ah, 3dh ; вызов функции открытия файлов
- lea dx, file2 ; адрес имени файла
- lea bx, ident2 ; адрес идентификатора файла
- call openfileproc ; вызов процедуры открытия файла
- jc exit_prog ; если была ошибка - выход
- ; проверка на соответствие формату RIFF
- mov bx, ident2 ; идентификатор файла в BX
- lea dx, headline2 ; адрес буфера заголовка
- call wavcheck ; вызов процедуры проверки формата заголовка
- jc exit_prog ; если была ошибка - выход
- jne exit_prog ;
- mov ah, 9h ; вывод информации о совместимости файлов
- lea dx, combfiles ;
- int 21h ;
- ; сравнение совместимости файлов
- lea si, headline1 + 0ch ; заголовки файлов со смещением +12 (до начала секции 'fmt ')
- lea di, headline2 + 0ch ;
- call filescompcheck ; вызов процедуры проверки cовместимости файлов
- jne exit_prog ; если была ошибка - выход
- mov ah, 9h ; вывод информации о склейке
- lea dx, createfile ;
- int 21h ;
- ; создание нового файла
- mov ah, 3ch ; вызов функции создания
- mov cx, 0 ; обычного файла
- lea dx, file3 ; имя создаваемого файла
- lea bx, ident3 ; его идентификатор
- call openfileproc ; вызов процедуры создания файла
- jc exit_prog ; если была ошибка - выход
- ; вычисление длины нового файла
- lea si, headline1 ; в si заголовок 1-го файла
- add si, 28h ; смещение до длины данных (40 байт)
- lodsw ; младшие 2 байта из SI в AX
- mov cx, ax ; младшие 2 байта в cx
- lodsw ; старшие 2 байта из SI в AX
- mov dx, ax ; старшие 2 байта в dx
- lea si, headline2 ; в si заголовок 2-го файла
- add si, 28h ; смещение до длины данных (40 байт)
- lodsw ; младшие 2 байта из SI в AX
- mov bx, ax ; младшие 2 байта в bx
- lodsw ; старшие 2 байта из SI в AX
- xchg bx,ax ; младшие в ax, старшие в bx(меняем местами содердимое ВХ и АХ)
- push ax ; сохранить
- push bx ; длины
- push cx ; данных
- push dx ; файлов
- ; проверка длины нового файла
- add ax, cx ; вычислить 2 младших байта
- adc dx, bx ; с учетом переноса вычислить 2 старших байта (+ Флаг переноса)
- jc overflorerr ; если переполнение - вывод ошибки
- cmp dx, 7735h ; сравнение на предмет переполнения
- ja overflorerr ; если больше - ошибка переполнения
- jb overflowchecked ; меньше - пропустить проверку младших
- cmp ax, 9590h ; проверка младших разрядов размера
- ja overflorerr ; если больше - ошибка переполнения
- ; создание заголовка для нового файла
- overflowchecked:
- lea si, headline2 ; заголовок нового файла будет создан на основе заголовка первого файла
- lea di, headline1 ;
- push dx ; сохранить размер файла
- push ax ;
- add ax, 28h ; размер всего файла это размер данных + 40 символов
- adc dx, 0 ; добавить в ДХ флаг переполенения
- mov cx, 4 ; копирование первых 4 символов 'RIFF'
- rep movsb ;
- stosw ; добавление размера нового файла
- mov ax, dx ;
- stosw ;
- add si, 4 ; смещение на размер файла
- mov cx, 20h ; копирование оставшегося заголовка
- rep movsb ; до длины данных
- pop ax ; восстановление в ax длины данных
- stosw ; добавление длины данных
- pop ax ;
- stosw ;
- ; Формирование заголовка нового файла
- mov bx, ident3 ; идентификатор нового файла сохраняется в BX
- lea dx, headline1 ; сохранение заголовка в файла
- mov ah, 40h ; запись заголовка в файл по идентификатору БХ
- mov cx, 2ch ; длина заголовка 44 байта
- int 21h ; выполнить
- jc writtingerr ; если была ошибка - выход
- mov ah, 9h ; иначе сообщение
- lea dx, writtingnoerr ; об успешной записи
- int 21h ;
- ; Запись содержимого 1-го файла
- pop dx ; восстановление старших байтов
- pop ax ; восстановление младших байтов
- mov bx, ident1 ; идентификатор 1-го файла для процедуры
- call copydata ; вызов процедуры копирования
- jc writtingerr ; если была ошибка - выход
- ; Запись содержимого 2-го файла
- pop dx ; восстановление старших байтов
- pop ax ; восстановление младших байтов
- mov bx, ident2 ; идентификатор 2-го файла для процедуры
- call copydata ; вызов процедуры копирования
- jc writtingerr ; если была ошибка - выход
- mov ah, 9h ; сообщение об успешной склейке файлов
- lea dx, succcomb ;
- int 21h ;
- exit_prog: ; выход из программы
- mov ax, 4C00h
- int 21h
- nofile2: ; вывод сообщения об отсутствии имени второго файла
- mov ah, 9h
- lea dx, nofile2msg
- int 21h
- jmp exit_prog
- nofile3: ; сообщение об отсутствии в имени второго файла в аргументах
- mov ah, 9h
- lea dx, m_par_nofn3
- int 21h
- jmp exit_prog
- er_empty: ; вывод сообщения о пустой строке с аргументами
- pop ds ; восстановление ds
- mov ah, 9h
- lea dx, noparammsg
- int 21h
- jmp exit_prog
- overflorerr: ; вывод сообщения о ошибке переполнения
- mov ah, 9h
- lea dx, overflorerrmsg
- int 21h
- jmp exit_prog
- writtingerr:
- mov ah, 9h
- lea dx, writtingerrmsg
- int 21h
- jmp exit_prog
- ;Объявление процедур
- ; Процедура чтения параметров
- ; на входе адреса строк, где будут храниться имена файлов
- ; на выходе - имена файлов
- ;==================================================================
- parread proc
- mov si, 81h ; в si заносится первый символ
- mov cx, 2 ; нужно считать 3 параметра
- skipspace: ; пропуск пробелов
- lodsb ; символ заносится в АЛ
- cmp al, 20h ; сравнивается с пробелом
- je skipspace ; если пробел, проверяется след. символ
- charread: ; иначе
- jb readstrend ; если символ меньше 20h, то это символ конца строки ODh
- stosb ; иначе, символ заносится в di
- lodsb ; а следующий символ в AL
- cmp al, 20h ; сравнивается с пробелом
- jne charread ; если не пробел, повторить
- readstrend: ; если попался символ конца строки
- mov al, 0 ; в al заносится 0
- stosb ; и записывается в di
- pushf ; содержимое регистра FLAGS сохраняется в стек
- cmp cx, 0 ; если третий файл уже введен
- je readrep ; пропуск следующей команды
- mov di, bx ; адрес строки с названием третьего файла
- cmp cx, 1 ; если второй файл уже введен
- je readrep ; пропуск следующей команды
- mov di, dx ; адрес строки с названием второго файла
- readrep:
- popf ; восстанавливаем регистр флагов из стека
- loope skipspace ; если последний попашвийся символ - пробел, повторить
- ret ; выход из процедуры
- parread endp
- ;==================================================================
- ; Процедура открытия/создания файла
- ; при открытии
- ; на входе адрес идентификатора, номер функции
- ; на выходе - идентификатор
- ; при создании
- ; на входе номер функции, адрес строки с именем ,атрибут файла
- ; на выходе - описатель нового файла
- ;==================================================================
- openfileproc proc
- mov al, 0 ; режим доступа - чтение
- int 21h ; выполнить
- jc openfileer ; если ошибка чтения - выход с ошибкой
- mov [bx],ax ; иначе запись идентификатора файла
- mov ah, 9h ; функция вывода строки
- lea dx, okmsg ; адрес строки
- int 21h ; выполнить
- ret ; выход из процедуры
- openfileer: ; сообщение об ошибке чтения
- mov ah, 9h ;
- lea dx,readerrmsg ;
- int 21h ;
- ret ;
- openfileproc endp
- ;==================================================================
- ; Процедура чтения заголовка файла и проверки его соответствия формату RIFF т.е. сравнение со строкой 'RIFFxxxxWAVEx...xdata'
- ; на входе адрес буфера для заголовка
- ; на выходе заголовок
- ;==================================================================
- wavcheck proc
- mov cx, 2ch ; считать первые 44 байта (длину заголовка)
- mov ah, 3fh ; вызов функции чтения из файла в DX
- int 21h ; выполнить
- jc readingerr ; вывод сообщения об ошибке, если неудачно
- lea si, format ; загрузка эталонной строки для сравнения
- mov di, dx ; сравнение строки-примера со строкой из файла(находящейся в буфере)
- mov cx, 4 ; сравнить первые 4 символа ('RIFF')
- repe cmpsb ; сравнение байта в SI с байтом в DI
- jne formaterror ; если есть несовпадение - выход
- add di, 4 ; сместить на 4 символа
- mov cx, 4 ; сравнить 4 символова ('WAVE')
- repe cmpsb ; сравнение байта в SI с байтом в DI
- jne formaterror ; если есть несовпадение - выход
- add di, 18h ; сместить на 18 символов
- mov cx, 4 ; сравнение 4 символова ('data')
- repe cmpsb ; сравнение байта в SI с байтом в DI
- jne formaterror ; если есть несовпадение - выход
- mov ah, 9h ; сообщение об успешном чтении файлов
- lea dx, formsuccmsg ;
- int 21h ;
- ret ;
- readingerr:
- mov ah, 9h ; Если возникает ошибка при чтении файла
- lea dx, readerrmsg ;
- int 21h ;
- ret
- formaterror:
- mov ah, 9h ; Если формат файла не соответствует формату RIFF
- lea dx, formaterrormsg ;
- int 21h ;
- ret
- wavcheck endp
- ;==================================================================
- ; Процедура проверки совместимости параметров файлов
- ; здесь проверяется формат, кол-во каналов, частота дискретизации, кол-во байт за секунду воср., кол-во байт для 1го сэмла, кол-во бит в сэмпле)
- ;==================================================================
- filescompcheck proc
- mov cx, 1ch ; проверка 28 символов
- repe cmpsb ; на совпадение
- jne comperror ; если есть несовпадение - выход с ошибкой
- mov ah, 9h ; иначе, сообщение об успешном сравнении форматов
- lea dx, compsucc ; сообщение об успешном сравнении форматов
- int 21h
- ret
- comperror:
- mov ah, 9h ; сообщение об ошибке сравнения форматов
- lea dx, comperrormsg
- int 21h
- ret
- filescompcheck endp
- ;==================================================================
- ; Процедура копирования в из указанного в bx файла в новый файл
- ;==================================================================
- copydata proc
- mov cx, 0efffh ; заносим кол-во птовторений
- div cx ; при записи блоками по EFFFh байт
- push dx ; сохранение размера последнего блока
- cmp ax, 0 ; если файл меньше EFFFh
- je copy_dt ; запись единственного блока длиной dx
- mov cx, ax ; иначе копирование блоков данных по EFFFh
- copyloop:
- jc errext ; если была ошибка записи - выход
- push cx ; сохранение числа оставшихся повторений
- mov ah, 3fh ; вызов функции чтения из файла
- mov cx, 0efffh ; блока из EFFFh байтов
- lea dx, bufblock ; в буфер
- int 21h ;
- push bx ; сохраненить идентификатор
- mov ah, 40h ; вызов функции записи
- mov bx, ident3 ; в 3новый файл
- mov cx, 0efffh ; блок из EFFFh байтов
- int 21h ;
- pop bx ; восстановить индетиф. первого файла
- pop cx ; и оставшееся число повторов
- loop copyloop ; повторить
- copy_dt:
- mov ah, 3fh ; чтение из 1-го файла (идентификатор в bx)
- pop cx ; последнего блока
- lea dx, bufblock ; в буфер
- int 21h ;
- mov ah, 40h ; запись этого блока
- mov bx, ident3 ; в 3-й файл
- int 21h ;
- errext:
- ret
- copydata endp
- ;==================================================================
- end start
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement