Отправляет email-рассылки с помощью сервиса Sendsay

Ассемблер для начинающих.

  Все выпуски  

Ассемблер для начинающих. Выпуск 4-ый.


Информационный Канал Subscribe.Ru

Assembler for newbies in Low level Programming
Ассемблер для новичков в низкоуровневом программировании.

Все вокруг иллюзорно...

Пожалуй все-таки теории у нас слишком много было, давай-те ка поболее практики,
к примеру 
самое пожалуй насущьное, работа с файлами. MS-DOS не даром называется Дисковой
ОС, и 
работа с файлами в ней организована довольно просто и удобно. Метод работы с
файлами этой ос называется 
методом описателя. 

 ПРИМЕЧАНИЕ. В функциях ДОС признаком ошибки является флаг C, т.е. мы можемсделать
такое:
int 40h
jc error       ;jc т.е. jmp если C взведен.

Сначала файл должен быть открыт, при этом используется его полное или краткое
имя. В первом случае это 
значит, что должен использоваться полный путь к файлу (C:\temp\test.txt к примеру),
а во втором случае 
файл берется из того-же каталога из которого программа была запущена.
 После успешного открытия файла ему присваивается описатель, через который, собственно
и ведется 
вся работа с этим файлом. По умолчанию мы можем открыть только 20 файлов (почему
см. PSP) 
 В конце работы файл следует закрыть.

Почему необходимо закрывать файл по завершении работы программы? Ну, если не
закрыть к примеру после 
записи в файл, то скорее всего все что мы записали в файл будет потеряно. Но
почему потеряно: 
 описатель файла есть лишь некий указатель на область памяти, на буфер, куда
сначала пишутся все данные прежде 
чем попасть в файл. И только при переполнении этого буфера, или закрытии файла
все это физически записывается в 
файл. Тем самым скорость записи увеличивается во много раз. 

ПРИМЕЧАНИЕ: В дос имеется функция 68h, которая сбрасывает буферы записи на жесткий,
тем самым предохраняя 
вас от потери информации.

Далее примеры.
 Открытие файла:
на masm:

        mov DX,offset _file     ;в _file название файла (_file db 'test.txt',0)
        mov AL,2                         ;2 для чтения и записи, 1 запись, 0 только чтение
        mov AH,3Dh             ; открытие файла (функция)
        int 21h                       ; вызываем её     
        jc er                           ; и если ошибка (не существует такого файла
к примеру) то jmp на er
        mov handle,AX
fasm:
        mov DX,_file               ;все остальное так-же как и выше.
        mov [handle],AX
PS после вызова 21h/3Dh в ax содержится описатель(handle, хендл) файла.
ПРИМЕЧАНИЕ: про fasm я напишу в отдельном выпуске. Кстати, очень удобен, и синтаксис
лучше, "правильней". Да и компилить удобнее.

Закрытие файла:
        mov AH,3Eh
        mov BX,handle
        int 21h
        jc er
на fasm отличие: mov BX,[handle]

Чтение и запись:
        mov AH,40h        ; номер функции(запись)
        mov BX,handle    ; хэндл файла
        mov DX,offset _buff  ; адрес буфера (отсюда берем данные и пишем в файл)
        mov cx,1000           ; сколько байт из буфера записать в файл
        int 21h
        jc er

В AX передает код ошибки, или сколько байт записано.
Чтение - 3Fh все так-же, но возвращает сколько байт считано.

далее прога, на fasm, но её без труда  можно перевести на любой другой асм.

PS я перевел текст этой проги из OEM в ANSI для того, чтобы можно было прочитать

то что там написано, но если вы хотите её скомпилировать, пишите в кодировке
ДОС (terminal в блокноте к примеру), 
чтобы то что вы написали отображалось в виде букв а не кракозяблов.
PS последнюю версию берем на http://ass3mbler.narod.ru/efman.zip



Чтобы переписать к примеру на masm, достаточно запомнить несколько правил:
mov al,_file1 ; поместить в al адрес _file1
mov al,[_file1] ; поместить в al байт находящийся по адресу _file1
все остальное (пока) ничем не отличается.
Да, и не удивляйтесь тому что здесь делается call на метки, такое можно делать
и в других асмах. (ведь call, это только
push адреса следующей команды, и jmp на метку процедуры).
ПРИМЕЧАНИЕ , если убрать ядро, то получим прогу для копирования файлов.
; сие творение написано Skif_Q.


format MZ       ; это для того чтобы компилятор делал дос программу

entry codseg:Begin   ; указание что Begin есть начало кода.
stack 50h                 ; определяем что для стека нам хватит 50h байт

segment dat

ermes1  db 'ОШИБКА ОТКРЫТИЯ ЭТОГО ФАЙЛА, ПОПРОБУЙТЕ ЕЩЕ РАЗ$'
ermes2  db 'ОШИБКА ОТКРЫТИЯ ИЛИ СОЗДАНИЯ ФАЙЛА (может он только для чтения?)$'

enterr  db 13,10,'$'

ent1    db      13,10
        db      '   ______________________________________________',13,10
        db      '  ',13,10
        db      ' |',13,10        
        db      ' |     Extended File Security Manager. Cripter    ',13,10
        db      ' |        Версия : 0.01 beta 1 build 804          ',13,10
        db      ' |         Эта прога для шифрации файла           ',13,10
        db      ' |                                                |',13,10
        db      '  \______________________________________________/',13,10,13,10,13,10
        db      ' Для выхода из программы нажмите Ctrl-C',13,10,13,10  
        db      ' Пожалуйста введите имя файла, который надо зашифровать',13,10,' : $'
ent2    db      ' Теперь введите имя файла, куда поместить зашифрованную ',13,10
        db      ' информацию (если он не существует, то будет создан)',13,10
        db      ' имя файла: $'
entpass db      ' Пожалуйста введите ключ для шифрации, он-же пароль',13,10
        db      ' :$'

passpe1 dw      0
passpe2 dw      0
passlen dw      ?

max     db      25
        db      0
_pass   rb      25                      
        db      0
        
pall    dw      ?

max1    db      22
        db      0       
_file1  rb      22
        db      0
        
max2    db      22
        db      0
_file2  rb      22
        db      0
        
handle1 dw      ?       ; хендл первого файла
handle2 dw      ?       ; и хендл второго файла
EOF     db      0
_buff   rb      1001    ; буфер

segment codseg
Begin:

        mov ax,dat
        mov ds,ax

                        ;  просим ввести назван. пер. файла.
        mov ah,09h
        mov dx,ent1
        int 21h
         
        
        mov ah,0Ah      ; ловим его (название)
        mov dx,max1
        int 21h
                        

        mov bx,0
        mov cx,22               ; проверка названия и добавление 0 после него
lono:
        mov al,byte [_file1 + bx]
        cmp al,0Dh
        jnz no1
        mov byte [_file1+bx],0
        jmp strt
no1:
        inc bx
        loop lono
        
strt:
        
        call ent                ; перевод строки
                        ; открываем первый фил
        mov ah,3Dh
        mov al,0
        mov dx,_file1
        int 21h
         
        jc error1
        mov [handle1],ax


        mov ah,09h      ; просим ввести назван. второго файла.
        mov dx,ent2
        int 21h 
        
        mov ah,0Ah      ; ловим его
        mov dx,max2
        int 21h
         
        call ent
        
        mov bx,0
        mov cx,22                       ; add zero after _file
lono1:
        mov al,byte [_file2+bx]
        cmp al,0Dh
        jnz no2
        mov byte [_file2+bx],0
        jmp strt1
no2:
        inc bx
        loop lono1
        
strt1:
        mov ah,3Dh                      ;открываем 2-й фил.
        mov al,1
        mov dx,_file2
        int 21h
        jc error2               
unerr:  mov [handle2],ax
        
        
        mov ah,09h      ; просим пароль
        mov dx,entpass
        int 21h
        
        call input_pass 
        call ent
        
        
                                        ; чтение  из первого фила
        mov dx,_buff
        mov cx,1000
loo:
        mov dx,_buff
        mov bx,[handle1]
        mov ah,3fh
        int 21h                 ; само чтение
        cmp ax,cx
        jz norm
        mov cx,ax
        mov [EOF],1
        
        
        
        ;/////////////////////////////////пошло ядро\\\\\\\\\\\\\\\\\\\\\\\\\\\\
norm:
        push ax
        push dx
        push bx
        push cx
        mov bx,0
        mov cx,1000
        mov ah,4                
        mov dh,ah
        mov [passpe1],0
        mov [passpe2],0
        
looo:
        
        mov ax,[passlen]
        cmp [passpe2],ax
        jnz ok
        mov [passpe2],0
ok:

        mov bx,[passpe1]
        mov dl,byte [_buff+bx]
        add dl,ah
        add ah,dh
        cmp ah,252
        
        jnz hie
        mov ah,4
hie:    
        mov bx,[passpe2]
        mov al,byte [_pass+bx]
        inc bx
        mov [passpe2],bx
        
        xor dl,al
        
        mov bx,[passpe1]
        mov byte [_buff+bx],dl
        inc bx
        mov [passpe1],bx
        loop looo
eno:    
        pop cx
        pop bx
        pop dx
        pop ax
        
                ;\\\\\\\\\\\\\\\\\\\\\\\\конец ядра//////////////////////////////////
enn:    

        mov bx,[handle2]
        mov ah,40h
        int 21h
        cmp [EOF],0
        jz loo
        
        
        
close2:
        mov ah,3Eh
        mov bx,[handle2]
        int 21h
        
        
        
close1:
        mov ah,3Eh
        mov bx,[handle1]
        int 21h
        
        

en:
        mov ah,4Ch
        int 21h
error1:


        mov ah,09h
        mov dx,ermes1
        int 21h
        call ent
        jmp Begin


error2:
        mov ah,3Ch
        mov cx,0
        mov dx,_file2
        int 21h
        jc error3
        jmp unerr

error3: mov ah,09h
        mov dx,ermes2
        int 21h
        call ent
jmp Begin


input_pass:             ; ввод и проверка пароля, а так-же определение его длины

        mov ah,0Ah
        mov dx,max
        int 21h
        
        mov bx,1
        
        mov cx,24
lomo:
        mov al,byte [_pass+bx]
        cmp al,0
        jz rav
        inc bx
        loop lomo
rav:
        mov [passlen],bx

        mov cx,bx
        mov bx,0
        mov dl,byte [_pass+2]
        xor dl,3
lok:
        mov al,byte [_pass+bx]
        xor al,dl
        mov byte[_pass+bx],al
        add dl,7
        inc bx
        loop lok
        ret
        


ent:
        push ax
        push dx
        mov ah,09h
        mov dx,enterr
        int 21h
         
        pop dx
        pop ax
        ret

По всем возникающим вопросам обращайтесь, всегда помогу.
Skif_Q ведущий рассылки.
skif_q@mail.ru 

Да сохранит вас F2.

Subscribe.Ru
Поддержка подписчиков
Другие рассылки этой тематики
Другие рассылки этого автора
Подписан адрес:
Код этой рассылки: comp.soft.prog.asmnewbies
Архив рассылки
Отписаться
Вспомнить пароль

В избранное