Жду огромное кол-во комментариев, оваций или хоть чего-нибудь...
.MODEL TINY
.386
.CODE
ORG 100h
Start:
cld
mov di,80h ; DS:DI - количество символов, введенных
; в командной строке после имени проги.
; DS - сегмент PSP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Минимум : a. b. - т.е. 10 символов включая 0Dh & возм. пробелы ;;;;;
; Максимум: maximum1.max maximum2.max = 27 + возм. пробелы -> 35.;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + параметр -> 4 space's
mov cl,[di] ;
;cmp cl,10 ;
;jb @PrintHelp ;
;cmp cl,80 ; Сверим пределы, если что - выводим
;ja @PrintHelp ; справку
mov ch,0 ; Инициализируем счетчик символов
inc di ;
inc di ; DS:DI, собственно, сами символы...
push di ; Сохр. смещение к началу первого имени
mov al,' ' ; Ищем первый пробел
repne scasb ; ищем, ищем...
je @SpaceFound ; ...нашли!
jmp @PrintHelp ; ...не нашли выводим справку об исп-ии : (
@SpaceFound:
mov byte ptr [di-1],0 ; Ставим ноль (формат имени -> ASCIIZ)
push di ; Сохр. смещение начала второго имени
mov al,0Dh ;
repne scasb ; Ищем конец строки, т.е. символ с кодом 13
je @EndFound ;
jmp @PrintHelp ;
@EndFound: ;
dec di ;
cmp word ptr [di-2],'# ' ; Смотрим нет ли параметра
jne @NoParam ;
dec di ; В случае присутствия -> меняем код
dec di ; процедуры перекодировщика
;;; Чиста выиграл 39-22= целых 17 байт; Было 3 варианта:;;; I;;;;
;push di ; 1
;lea di,@FirstModified+1 ; 3
;mov al,80h ; 2
;stosb ; 1
;add di,3 ; 3
;mov al,0AFh ; 2
;stosb ; 1
;mov al,4 ; 2
;add di,4 ; 3
;stosb ; 1
;lea di,@@@@@ ; 3
;stosb ; 1
;sub di,4 ; 3
;mov al,0E0h ; 2
;stosb ; 1
;pop di ; 1;;; Как итог - 30 байт, не пойдет : ( ;;;; II;;;
;mov byte ptr [@FirstModified+1],80h
;mov byte ptr [@FirstModified+5],0AFh
;mov byte ptr [@FirstModified+8],4
;mov byte ptr [@NextRange+1],0E0h
;mov byte ptr [@NextRange+4],4;;; Как итог - 25 байт, тож говно ; );;;; III
;;;;;;; Вот он - лучший и неповторимый!!! 8-);;;
lea si,@FirstModified+1 ; Смещение к первому байту изменяемого кода
mov byte ptr [si],80h ; Пределы первого диапазона
mov byte ptr [si+4],0AFh ;
mov byte ptr [si+7],4 ; Код сложения
mov byte ptr [si+12],0E0h ; Второй диапазон
mov byte ptr [si+15],4 ; !!!ONLY 22 bytes!!!
@NoParam:
mov byte ptr [di],0 ; Ставим ноль в конце второго имени
mov ax,3D02h ; Пробуем открыть файл для записи...
pop dx ; DS:DX - имя выходного файла
int 21h
jnc @AlreadyExist ; Если такого нету...
mov ah,3Ch ; ...пробуем создать
mov cx,20h ; Атрибут - архивный (включен бит 5)
int 21h ;
jc @PrintError ;
mov OutHandle,ax ; Сохраняем дескриптор созданного файла
jmp @TryOpenAnother ; Открываем следующий файл
@AlreadyExist: ;
mov OutHandle,ax
lea dx,Question ; Спрашиваем о возможности перезаписи
mov ah,9 ; файла, т.к. он уже существует
int 21h
mov ah,0 ; Ждем ввода
int 16h
cmp ax,1C0Dh ; Нажата клавиша Enter?
je @TryOpenAnother
jmp @PrintHelp ; При нажатии любой другой клавиши...
@TryOpenAnother:
pop dx ; Смещение к первому параметру
mov ax,3D02h ; Открыть для чтения...
int 21h
jc @PrintError
mov InHandle,ax ; Сохраняем дескриптор;;;; Основной цикл чтения/записи;;;
lea bp,InHandle ; Адресуем дескрипторы через сегмент стека
push ds ; Сохр. DS, хотя надо-ли??
mov ax,ds
add ax,1001h
mov ds,ax
@ReadNext:
mov bx,word ptr [bp] ; Дескриптор
xor dx,dx ; DS:DX - буфер для чтения
mov cx,dx ;
dec cx ; CX -> 0FFFFh ~64Kb
mov al,'.'
int 29h ; Контроль кол-ва 64Кб блоков
mov ah,3Fh ; Читать...
int 21h ; ...пока не уср1мся
jc @PrintError ; Контролируем...
cmp ax,0 ;
je @ConvertComplete ; Проверяем на EoF
mov si,dx ; или xor si,si по совести
mov cx,ax ; Кол-во реально прочитанных байт;;;
call WIN2ASCII
mov bx,word ptr [bp-2] ; Дескриптор
mov ah,40h ; Записываем
int 21h
jc @PrintError
jmp @ReadNext
@ConvertComplete:
pop ds ; Восстанавливаем сегмент данных
mov ah,40h ;
mov bx,OutHandle ;
xor cx,cx ; Записать 0 байт
int 21h ; Обрезаем файл - на всякий случай
jc @PrintError ;
mov ah,3Eh ; Закрываем оба файла
int 21h ;
jc @PrintError
mov bx,InHandle ;
int 21h ;
jc @PrintError
jmp @EndOfProg ;