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.rar Чтобы переписать к примеру на 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 Последнюю версию рассылки (с исправленными ошибками), а так-же приложение, со списком функций ДОС-а, списком регистров, описанием команд, и многого другого, вы найдете на http://ass3mbler.narod.ru Да сохранит вас F2.