Вот, предлагаю версию 1.0, никому не нужного перекодировщика из ASCII в WIN и наоборот написанного на асме с использованием самодифицирующегося кода, впрочем выигрыш от его использования минимальный...
Жду огромное кол-во комментариев, оваций или хоть чего-нибудь...
.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 ;
;;; Типа, экран помощи;;;
@PrintHelp:
mov ah,9
lea dx,HelpMes
int 21h
jmp @EndOfProg;;; Ошибка -> выводим код, завершаем работу;;;
@PrintError:
push cs
pop es
lea di,DOSErrorCode
call Bin2Hex
push es
pop ds
mov ah,9
lea dx,ErrorMes
int 21h;;;
@EndOfProg:
mov ax,4C01h
int 21h
WIN db 0
OutHandle dw ?
InHandle dw ?
ErrorMes db 13,10,' -> Ошибка DOS #: '
DOSErrorCode db ' ','$'
Question db 'Выходной файл уже существует, переписать? (Enter = Да):$'
HelpMes db 13,10,'Эта прога представляет собой лишь очередной ремейк конвертора из ASCII в WIN.',13,10
db 'Использование: convert.com <входной.файл> <выходной.файл> [#]',13,10
db 'При указании параметра # происходит перевод из WIN в ASCII без него - наоборот.'
db 13,10,13,10,13,10
db '>>> Copyright by GLuk <<<','$'
db 'complete!$'
Bin2Hex Proc;; На входе ES:DI - адрес приемника; AL - число;;; Сохраняем используемые регистры
push ax
push cx
push di
mov ah,al
shr al,4 ; Выделяем старший полубайт, сдвигом на 4 бита вправо;
@StartModify:
add al,30h ; Преобразуем до ASCII-цифры
cmp al,39h ;
jbe $+4 ; Если это буква
add al,7 ; добавляем еще 7
stosb ; Запоминаем
@Change:
mov al,ah ; Восстанавливаем исх. значение
and al,0Fh ; Выделяем младший полубайт;;;;;;;;;;;;;;;;;;;;;;;;;
mov word ptr @Change,00AEBh; jmp $+0Ah
jmp @StartModify ; Преобразуем ее
@Done:mov word ptr @Change,0C48Ah; Восстанавливаем исх. код
pop di
pop cx
pop ax
ret
Bin2Hex EndP;;; Собственно, сам перекодировщик WIN->WIN;;;
WIN2ASCII Proc
push ax
push ds
push si
push cx
pushf ; Сохр. регистр флагов
cld ; Очищаем флаг направления (6)
@NextByte: ;
lodsb ; Получаем байт в AL
cmp si,cx ; Может это конец?
je @Stop ;
@FirstModified:
cmp al,0C0h ; Проверяем первый диапазон
jb @NextByte ;
cmp al,0EFh
ja @NextRange
sub al,64 ; Инкремент/Декремент на этот случай
jmp @Store ;
@NextRange: ;
cmp al,0F0h ; Следующий диапазон 0F0h-0FFh
jb @NextByte ;
sub al,16 ;
@Store:
mov [si-1],al ;
jmp @NextByte ;
@Stop: ;
popf
pop cx
pop si
pop ds
pop ax
ret ; 39 байт
WIN2ASCII EndP
END Start ;
Ну не будем мусолить... поищу - есть некоторые люди... а больше паг не по сабжу не постить (личная просьба модера).
2Clane: Вишь ли в моем понятии МОДЕР - это человек, понимающий несколько больше, чем остальные в своем топике... но т.к. ты тех людей не знаешь - no comment's
Извиняюсь за офтопик. Помогите, пожалуйчта, новичку!!! Нужно на АСМе написать программу, которая при вводе любой буквы покажет первую цифру ее ASCII кода. Заранее огромное спасибо!!!
.model tiny ; модельВот. Компилить
.code ;тут начинается секция кода
org 100h ;грузим со смещения 100h, так как с 0 по 100h идут всякие структуры
start: ;метка начала кода
xor ah,ah
int 16h ;получаем в al код символа
cmp al,27 ;это esc?
je exit ;да - валим
pechat:
mov cl,4 ;shr al,4 на 8086 не проходит вроде
shr al,cl ;делаем через cl, что вроде как лучше и наглядней div
cmp al,0ah ;сравниваем
ja bol6e
add al,30h ;если меньше, то имеем дело с числом
jmp pechats
bol6e:
add al,37h ;если больше, то с буквой (разницу ищи в таблице ascii)
pechats:
mov digits,al ;полученный символ пихаем подальше
mov ah,9h ;функция вывода строки
mov dx, offset dannie ;ds:dx - указывают на строку
int 21h ;выводим
jmp start ;повторяем
exit:
ret ;в стеке лежит 0 (не веришь - в отладчик), то есть
;это всё равно, что jmp 0, а по смещению 0 лежит команда int 20h - выход
dannie db 'First digit is: '
digits db 0h,0ah,0dh,'$'
end start
На будущее, Freeman, просьба писать коментраии =), и немного пожалуйста по блокам дели, для удобства чтения
.model tiny
.code
org 100h
start:
xor ah,ah
int 16h; ah - SCAN code al - ASCII
cmp al,27; ESC?
je exit; аха
jmp pechat; идем печатать
dal6e:; ???
pechat:
mov cl,4;??? не проще было бы shr al,4? т.е. al=al div 16
shr al,cl;
cmp al,0ah
; тут я кое что переделал, на один jmp меньше.
add al,30h; цифра =)
jmp pechats
bol6e:
add al,7; цифра больше чем 10. Для букв от 0A до 0F
pechats:
mov digits,al
mov ah,9h
mov dx, offset dannie
int 21h
jmp start
exit:
ret
dannie db 'First digit is: '
digits db 0h,0ah,0dh,'$'
end start
Коментарии сделаем. Писалось на скорую руку, не очень оптимально. Перевод числа в символ, кстати, можно проще сделать
cmp al,0ahно ведь нормальный человек начнёт задавать вопрос: почему так?
sbb al,69h
das