IPB
ЛогинПароль:

> ПРАВИЛА РАЗДЕЛА!!!

1. Заголовок или название темы должно быть информативным
2. Все тексты программ должны помещаться в теги [CODE=asm] [/CODE]
3. Прежде чем задавать вопрос, см. "FAQ",если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно, такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Ассемблера. Исключение только с согласия модератора.
5. НЕ используйте форум для личного общения! Все, что не относиться к обсуждению темы - на PM!
6. Проверяйте программы перед тем, как выложить их на форум!!

> Конвертор Ascii->win
сообщение
Сообщение #1


Профи
****

Группа: Пользователи
Сообщений: 775
Пол: Мужской

Репутация: -  0  +


Вот, предлагаю версию 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                ;
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов(1 - 6)
сообщение
Сообщение #2


Профи
****

Группа: Пользователи
Сообщений: 775
Пол: Мужской

Репутация: -  0  +


Part II


;;; Типа, экран помощи;;;
@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                          ;
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Профи
****

Группа: Пользователи
Сообщений: 775
Пол: Мужской

Репутация: -  0  +


Ну не будем мусолить... поищу - есть некоторые люди... а больше паг не по сабжу не постить (личная просьба модера).

2Clane: Вишь ли в моем понятии МОДЕР - это человек, понимающий несколько больше, чем остальные в своем топике... но т.к. ты тех людей не знаешь - no comment's
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гость






Извиняюсь за офтопик. Помогите, пожалуйчта, новичку!!! Нужно на АСМе написать программу, которая при вводе любой буквы покажет первую цифру ее ASCII кода. Заранее огромное спасибо!!!
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


-
****

Группа: Пользователи
Сообщений: 480
Пол: Мужской

Репутация: -  4  +


.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
Вот. Компилить
ml asd.asm /AT

Сообщение отредактировано: volvo -


--------------------
бб
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Знаток
****

Группа: Пользователи
Сообщений: 408
Пол: Мужской

Репутация: -  3  +


На будущее, 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


Сообщение отредактировано: volvo -


--------------------
- Где я?
- Во тьме.
- В какой тьме?
- Во тьме твоего мозга.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


-
****

Группа: Пользователи
Сообщений: 480
Пол: Мужской

Репутация: -  4  +


Коментарии сделаем. Писалось на скорую руку, не очень оптимально. Перевод числа в символ, кстати, можно проще сделать
cmp al,0ah
sbb al,69h
das
но ведь нормальный человек начнёт задавать вопрос: почему так?

Сообщение отредактировано: volvo -


--------------------
бб
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 23.04.2024 14:40
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name