Advertisement
Guest User

Untitled

a guest
May 28th, 2017
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. .model  small               ;один сегмент кода, данных и стека
  2. .stack  100h  
  3. .386
  4. .data                       ;сегмент данных
  5.  
  6. ;Объявление переменных
  7.     file1       db 0fh dup (0)          ; Имена файлов
  8.     file2       db 0fh dup (0)          ;
  9.     file3       db 0fh dup (0)          ;
  10.     ident1      dw 0                    ; Идентификаторы файлов
  11.     ident2      dw 0                    ;
  12.     ident3      dw 0                    ;
  13.     headline1   db 2ch dup (?)          ; Буферы для заголовков
  14.     headline2   db 2ch dup (?)          ;
  15.     bufblock    db 0efffh dup (00h)     ; буфер чтения блока
  16.     format      db 'RIFFWAVEdata'       ; формат RIFF для проверки файлов на соответствие RIFF структуре
  17.  
  18. ; Сообщения выводимые пользователю
  19.     noparammsg      db  'Enter the parameters',0dh,0ah,'$'              ; если программа запущена без параметров
  20.     nofile2msg      db  'No second file',0dh,0ah,'$'                    ; если в параметрах не указано имя 2-го файла
  21.     m_par_nofn3     db  'No third file',0dh,0ah,'$'                     ; если в параметрах не указано имя 3-го файла
  22.     file1msg        db  '   First wav-file:',0dh, 0ah, '$'              ; начало работы с 1-м файлом
  23.     file2msg        db  '   Second wav-file:',0dh, 0ah, '$'             ; начало работы со 2-м файлом
  24.     combfiles       db  '   Combining files:',0dh, 0ah, '$'             ; начало склейки файлов
  25.     openfilemsg     db  'Opening: $'                                    ; попытка открыть файл
  26.     createfile      db  'Creating new file: $'                          ; попытка создать файл
  27.     okmsg           db  'Done',0dh,0ah,'$'                              ; успешно
  28.     errmsg          db  'Error',0dh,0ah,'$'                             ; ошибка
  29.     readerrmsg      db  'Read: Error',0dh,0ah,'$'                       ; ошибка при чтении файла
  30.     writtingerrmsg  db  'Writing: Error',,0dh,0ah,'$'                   ; ошибка при записи
  31.     writtingnoerr   db  'Writing: Done',0dh,0ah,'$'                     ; успешная запись
  32.     formaterrormsg  db  'Format: Error',0dh,0ah,'$'                     ; формат фалйа не верный
  33.     formsuccmsg     db  'Format: Correct',0dh,0ah,'$'                   ; формат фалйа верный
  34.     comperrormsg    db  'Compatibility: Error',0dh,0ah,'$'              ; при несовместимости
  35.     compsucc        db  'Compatibility: Ok',0dh,0ah,'$'                 ; файлы совместимы
  36.     overflorerrmsg  db  'The file is too large',0dh,0ah,'$'             ; при переполнении
  37.     succcomb        db  '   Files successfully combined',0dh,0ah,'$'    ; успешная склейка
  38.    
  39. .code
  40. ; начало программы
  41. start:            
  42.     mov ax, @data       ; инициализация сегмента es
  43.     mov es, ax          ;
  44.     push es             ; сохранение es для последующего восстановления в ds
  45.  
  46.     mov cl, ds:[80h]    ; в CL заносится длина параметров командной строки
  47.     cmp cl, 0           ; если она равна 0
  48.     jz er_empty         ; вывод сообщения об ошибке
  49.    
  50. ; считывание названий
  51.     lea di, file1       ; адреса строк заносятся в регистры
  52.     lea dx, file2       ;
  53.     lea bx, file3       ;
  54.     call parread        ; вызов процедуры для чтения названий файлов
  55.    
  56.     pop ds              ; восстановить ds
  57.     cmp file2,0         ; если нет имени второго файла
  58.     je  nofile2         ; вывести сообщение об ошибке
  59.    
  60.     cmp file3,0         ; если нет имени третьего файла
  61.     je nofile3          ; вывести сообщение об ошибке
  62.    
  63.     mov ah, 9h          ; вывод информации о первом файле
  64.     lea dx, file1msg    ;
  65.     int 21h             ;
  66.  
  67.     mov ah, 9h          ; Информация об открытии файла
  68.     lea dx, openfilemsg ;
  69.     int 21h             ;
  70.    
  71. ; считывание идентификатора
  72.     mov ah, 3dh         ; вызов функции открытия файлов
  73.     lea dx, file1       ; адрес имени файла
  74.     lea bx, ident1      ; адрес идентификатора файла
  75.     call openfileproc   ; вызов процедуры открытия файла
  76.     jc exit_prog        ; в случае ошибки - выход
  77.    
  78. ; проверка на соответствие формату RIFF
  79.     mov bx, ident1      ; идентификатор файла в BX
  80.     lea dx, headline1   ; адрес буфер для первого заголовка
  81.     call wavcheck       ; вызов процедуры проверки формата заголовка
  82.     jc exit_prog        ; в случае ошибки - выход
  83.     jne exit_prog       ;
  84.  
  85.     mov ah, 9h          ; вывод информации о втором файле
  86.     lea dx, file2msg    ;
  87.     int 21h             ;
  88.  
  89.     mov ah, 9h          ; Информация об открытии файла
  90.     lea dx, openfilemsg ;
  91.     int 21h             ;
  92.    
  93. ; считывание идентификатора
  94.     mov ah, 3dh         ; вызов функции открытия файлов
  95.     lea dx, file2       ; адрес имени файла
  96.     lea bx, ident2      ; адрес идентификатора файла
  97.     call openfileproc   ; вызов процедуры открытия файла
  98.     jc exit_prog        ; если была ошибка - выход
  99.    
  100. ; проверка на соответствие формату RIFF
  101.     mov bx, ident2      ; идентификатор файла в BX
  102.     lea dx, headline2   ; адрес буфера заголовка
  103.     call wavcheck       ; вызов процедуры проверки формата заголовка
  104.     jc exit_prog        ; если была ошибка - выход
  105.     jne exit_prog       ;
  106.    
  107.     mov ah, 9h          ; вывод информации о совместимости файлов
  108.     lea dx, combfiles   ;
  109.     int 21h             ;
  110.    
  111. ; сравнение совместимости файлов
  112.     lea si, headline1 + 0ch     ; заголовки файлов со смещением +12 (до начала секции 'fmt ')
  113.     lea di, headline2 + 0ch     ;
  114.     call filescompcheck         ; вызов процедуры проверки cовместимости файлов
  115.     jne exit_prog               ; если была ошибка - выход
  116.    
  117.     mov ah, 9h          ; вывод информации о склейке
  118.     lea dx, createfile  ;
  119.     int 21h             ;
  120. ; создание нового файла
  121.     mov ah, 3ch         ; вызов функции создания
  122.     mov cx, 0           ; обычного файла
  123.     lea dx, file3       ; имя создаваемого файла
  124.     lea bx, ident3      ; его идентификатор
  125.     call openfileproc   ; вызов процедуры создания файла
  126.     jc exit_prog        ; если была ошибка - выход  
  127.    
  128. ; вычисление длины нового файла
  129.     lea si, headline1   ; в si заголовок 1-го файла
  130.     add si, 28h         ; смещение до длины данных (40 байт)
  131.     lodsw               ; младшие 2 байта из SI в AX
  132.     mov cx, ax          ; младшие 2 байта в cx
  133.     lodsw               ; старшие 2 байта из SI в AX
  134.     mov dx, ax          ; старшие 2 байта в dx
  135.     lea si, headline2   ; в si заголовок 2-го файла
  136.     add si, 28h         ; смещение до длины данных (40 байт)
  137.     lodsw               ; младшие 2 байта из SI в AX
  138.     mov bx, ax          ; младшие 2 байта в bx
  139.     lodsw               ; старшие 2 байта из SI в AX
  140.     xchg bx,ax          ; младшие в ax, старшие в bx(меняем местами содердимое ВХ и АХ)
  141.    
  142.     push    ax          ; сохранить
  143.     push    bx          ; длины
  144.     push    cx          ; данных
  145.     push    dx          ; файлов
  146.    
  147. ; проверка длины нового файла
  148.     add ax, cx          ; вычислить 2 младших байта
  149.     adc dx, bx          ; с учетом переноса вычислить 2 старших байта (+ Флаг переноса)
  150.     jc overflorerr      ; если переполнение - вывод ошибки
  151.     cmp dx, 7735h       ; сравнение на предмет переполнения
  152.     ja overflorerr      ; если больше - ошибка переполнения
  153.     jb overflowchecked  ; меньше - пропустить проверку младших
  154.     cmp ax, 9590h       ; проверка младших разрядов размера
  155.     ja overflorerr      ; если больше - ошибка переполнения
  156.    
  157. ; создание заголовка для нового файла
  158. overflowchecked:
  159.     lea si, headline2   ; заголовок нового файла будет создан на основе заголовка первого файла
  160.     lea di, headline1   ;  
  161.     push dx             ; сохранить размер файла
  162.     push ax             ;
  163.     add ax, 28h         ; размер всего файла это размер данных + 40 символов
  164.     adc dx, 0           ; добавить в ДХ флаг переполенения
  165.     mov cx, 4           ; копирование первых 4 символов 'RIFF'
  166.     rep movsb           ;
  167.     stosw               ; добавление размера нового файла
  168.     mov ax, dx          ;
  169.     stosw               ;
  170.     add si, 4           ; смещение на размер файла
  171.     mov cx, 20h         ; копирование оставшегося заголовка
  172.     rep movsb           ; до длины данных
  173.     pop ax              ; восстановление в ax длины данных
  174.     stosw               ; добавление длины данных
  175.     pop ax              ;
  176.     stosw               ;
  177.  
  178. ; Формирование заголовка нового файла
  179.     mov bx, ident3      ; идентификатор нового файла сохраняется в BX
  180.     lea dx, headline1   ; сохранение заголовка в файла
  181.  
  182.     mov ah, 40h         ; запись заголовка в файл по идентификатору БХ
  183.     mov cx, 2ch         ; длина заголовка 44 байта
  184.     int 21h             ; выполнить
  185.     jc writtingerr      ; если была ошибка - выход
  186.  
  187.     mov ah, 9h              ; иначе сообщение
  188.     lea dx, writtingnoerr   ; об успешной записи
  189.     int 21h                 ;
  190.  
  191. ; Запись содержимого 1-го файла
  192.     pop dx              ; восстановление старших байтов
  193.     pop ax              ; восстановление младших байтов
  194.     mov bx, ident1      ; идентификатор 1-го файла для процедуры
  195.     call copydata       ; вызов процедуры копирования
  196.     jc writtingerr      ; если была ошибка - выход
  197.    
  198. ; Запись содержимого 2-го файла
  199.     pop dx              ; восстановление старших байтов
  200.     pop ax              ; восстановление младших байтов
  201.     mov bx, ident2      ; идентификатор 2-го файла для процедуры
  202.     call copydata       ; вызов процедуры копирования
  203.     jc writtingerr      ; если была ошибка - выход
  204.    
  205.     mov ah, 9h          ; сообщение об успешной склейке файлов
  206.     lea dx, succcomb    ;
  207.     int 21h             ;
  208.    
  209. exit_prog:              ; выход из программы
  210.     mov ax, 4C00h
  211.     int 21h
  212.  
  213. nofile2:                ; вывод сообщения об отсутствии имени второго файла
  214.     mov ah, 9h
  215.     lea dx, nofile2msg
  216.     int 21h
  217.     jmp exit_prog
  218.    
  219. nofile3:                ; сообщение об отсутствии в имени второго файла в аргументах
  220.     mov ah, 9h
  221.     lea dx, m_par_nofn3
  222.     int 21h
  223.     jmp exit_prog
  224.  
  225. er_empty:               ; вывод сообщения о пустой строке с аргументами
  226.     pop ds              ; восстановление ds
  227.     mov ah, 9h
  228.     lea dx, noparammsg
  229.     int 21h
  230.     jmp exit_prog
  231.  
  232.    
  233. overflorerr:            ; вывод сообщения о ошибке переполнения
  234.     mov ah, 9h
  235.     lea dx, overflorerrmsg
  236.     int 21h
  237.     jmp exit_prog
  238.  
  239. writtingerr:
  240.     mov ah, 9h
  241.     lea dx, writtingerrmsg
  242.     int 21h
  243.     jmp exit_prog
  244.  
  245.    
  246. ;Объявление процедур
  247.  
  248. ; Процедура чтения параметров
  249. ; на входе адреса строк, где будут храниться имена файлов
  250. ; на выходе - имена файлов
  251. ;==================================================================
  252. parread proc
  253.     mov si, 81h             ; в si заносится первый символ
  254.     mov cx, 2               ; нужно считать 3 параметра
  255.  
  256. skipspace:                  ; пропуск пробелов
  257.     lodsb                   ; символ заносится в АЛ
  258.     cmp al, 20h             ; сравнивается с пробелом
  259.     je skipspace            ; если пробел, проверяется след. символ
  260.    
  261. charread:                   ; иначе
  262.     jb readstrend           ; если символ меньше 20h, то это символ конца строки ODh
  263.     stosb                   ; иначе, символ заносится в di
  264.     lodsb                   ; а следующий символ в AL
  265.     cmp al, 20h             ; сравнивается с пробелом
  266.     jne charread            ; если не пробел, повторить
  267.    
  268. readstrend:                 ; если попался символ конца строки
  269.     mov al, 0               ; в al заносится 0
  270.     stosb                   ; и записывается в di
  271.     pushf                   ; содержимое регистра FLAGS сохраняется в стек
  272.  
  273.     cmp cx, 0               ; если третий файл уже введен
  274.     je  readrep             ; пропуск следующей команды
  275.    
  276.     mov di, bx              ; адрес строки с названием третьего файла
  277.     cmp cx, 1               ; если второй файл уже введен
  278.     je  readrep             ; пропуск следующей команды
  279.    
  280.     mov di, dx              ; адрес строки с названием второго файла
  281.    
  282. readrep:
  283.     popf                    ; восстанавливаем регистр флагов из стека
  284.     loope skipspace         ; если последний попашвийся символ - пробел, повторить
  285.     ret                     ; выход из процедуры
  286.    
  287. parread endp  
  288. ;==================================================================
  289.  
  290. ; Процедура открытия/создания файла
  291. ; при открытии
  292. ; на входе адрес идентификатора, номер функции
  293. ; на выходе - идентификатор
  294. ; при создании
  295. ; на входе номер функции, адрес строки с именем ,атрибут файла
  296. ; на выходе - описатель нового файла
  297. ;==================================================================
  298. openfileproc proc
  299.     mov al, 0               ; режим доступа - чтение
  300.     int 21h                 ; выполнить
  301.     jc openfileer           ; если ошибка чтения - выход с ошибкой
  302.    
  303.     mov [bx],ax             ; иначе запись идентификатора файла
  304.     mov ah, 9h              ; функция вывода строки
  305.     lea dx, okmsg           ; адрес строки
  306.     int 21h                 ; выполнить
  307.     ret                     ; выход из процедуры
  308.    
  309. openfileer:                 ; сообщение об ошибке чтения
  310.     mov ah, 9h              ;
  311.     lea dx,readerrmsg               ;
  312.     int 21h                 ;
  313.     ret                     ;
  314.    
  315. openfileproc endp
  316. ;==================================================================
  317.  
  318. ; Процедура чтения заголовка файла и проверки его соответствия формату RIFF т.е. сравнение со строкой 'RIFFxxxxWAVEx...xdata'
  319. ; на входе адрес буфера для заголовка
  320. ; на выходе заголовок
  321. ;==================================================================
  322. wavcheck proc
  323.     mov cx, 2ch             ; считать первые 44 байта (длину заголовка)
  324.     mov ah, 3fh             ; вызов функции чтения из файла в DX
  325.     int 21h                 ; выполнить
  326.     jc  readingerr          ; вывод сообщения об ошибке, если неудачно
  327.    
  328.     lea si, format          ; загрузка эталонной строки для сравнения
  329.     mov di, dx              ; сравнение строки-примера со строкой из файла(находящейся в буфере)
  330.     mov cx, 4               ; сравнить первые 4 символа ('RIFF')
  331.     repe cmpsb              ; сравнение байта в SI с байтом в DI
  332.     jne formaterror         ; если есть несовпадение - выход
  333.    
  334.     add di, 4               ; сместить на 4 символа
  335.     mov cx, 4               ; сравнить 4 символова ('WAVE')
  336.     repe cmpsb              ; сравнение байта в SI с байтом в DI
  337.     jne formaterror         ; если есть несовпадение - выход
  338.    
  339.     add di, 18h             ; сместить на 18 символов
  340.     mov cx, 4               ; сравнение 4 символова ('data')
  341.     repe cmpsb              ; сравнение байта в SI с байтом в DI
  342.     jne formaterror         ; если есть несовпадение - выход
  343.    
  344.     mov ah, 9h              ; сообщение об успешном чтении файлов
  345.     lea dx, formsuccmsg     ;
  346.     int 21h                 ;
  347.     ret                     ;
  348.    
  349. readingerr:            
  350.     mov ah, 9h              ; Если возникает ошибка при чтении файла
  351.     lea dx, readerrmsg      ;
  352.     int 21h                 ;
  353.     ret
  354.    
  355. formaterror:
  356.     mov ah, 9h              ; Если формат файла не соответствует формату RIFF
  357.     lea dx, formaterrormsg  ;
  358.     int 21h                 ;
  359.     ret
  360.    
  361. wavcheck    endp
  362. ;==================================================================
  363.  
  364. ; Процедура проверки совместимости параметров файлов
  365. ; здесь проверяется формат, кол-во каналов, частота дискретизации, кол-во байт за секунду воср., кол-во байт для 1го сэмла, кол-во бит в сэмпле)
  366. ;==================================================================
  367. filescompcheck  proc
  368.     mov cx, 1ch             ; проверка 28 символов
  369.     repe cmpsb              ; на совпадение
  370.     jne comperror           ; если есть несовпадение - выход с ошибкой
  371.     mov ah, 9h              ; иначе, сообщение об успешном сравнении форматов
  372.     lea dx, compsucc        ; сообщение об успешном сравнении форматов
  373.     int 21h
  374.     ret
  375. comperror:
  376.     mov ah, 9h              ; сообщение об ошибке сравнения форматов
  377.     lea dx, comperrormsg
  378.     int 21h
  379.     ret
  380. filescompcheck  endp
  381. ;==================================================================
  382.  
  383. ; Процедура копирования в из указанного в bx файла в новый файл
  384. ;==================================================================
  385. copydata    proc
  386.     mov cx, 0efffh          ; заносим кол-во птовторений
  387.     div cx                  ; при записи блоками по EFFFh байт
  388.     push dx                 ; сохранение размера последнего блока
  389.     cmp ax, 0               ; если файл меньше EFFFh
  390.     je  copy_dt             ; запись единственного блока длиной dx
  391.     mov cx, ax              ; иначе копирование блоков данных по EFFFh
  392.    
  393. copyloop:
  394.     jc  errext              ; если была ошибка записи - выход
  395.    
  396.     push cx                 ; сохранение числа оставшихся повторений
  397.     mov ah, 3fh             ; вызов функции чтения из файла
  398.     mov cx, 0efffh          ; блока из EFFFh байтов
  399.     lea dx, bufblock        ; в буфер
  400.     int 21h                 ;
  401.    
  402.     push bx                 ; сохраненить идентификатор
  403.     mov ah, 40h             ; вызов функции записи
  404.     mov bx, ident3          ; в 3новый файл
  405.     mov cx, 0efffh          ; блок из EFFFh байтов
  406.     int 21h                 ;
  407.    
  408.     pop bx                  ; восстановить индетиф. первого файла
  409.     pop cx                  ; и оставшееся число повторов
  410.     loop copyloop           ; повторить
  411.    
  412. copy_dt:  
  413.     mov ah, 3fh             ; чтение из 1-го файла (идентификатор в bx)
  414.     pop cx                  ; последнего блока
  415.     lea dx, bufblock        ; в буфер
  416.     int 21h                 ;
  417.    
  418.     mov ah, 40h             ; запись этого блока
  419.     mov bx, ident3          ; в 3-й файл
  420.     int 21h                 ;
  421. errext:
  422.     ret
  423. copydata    endp
  424. ;==================================================================
  425.  
  426. end start
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement