Калашников.ru - Ассемблер? Это просто!.. (Выпуск № 009)

InterReklama Advertising

Здравствуйте, уважаемые любители Ассемблера!

Выпуск N 009

Сегодня в нашей рассылке:

Ваши письма;

Программа из прошлого выпуска;

Программка для практики;

Моя проблема...

Ваши письма

Дорогие мои! Я был очень рад получить от вас столько много писем по поводу клуба программистов. Почти все поддержали эту идею. Не забывайте, что сам клуб будете делать вы! Моя задача - объединить вас всех.

Кстати, на нашем сайте ( http://www.Kalashnikoff.ru/ ) уже есть возможность посетить форум (наконец-то я сделал его!). Добро пожаловать!

Там также есть возможность ознакомиться с каждой отдельной рассылкой. Если раньше все выпуски я помещал в архив, то теперь любой желающий может взять отдельный выпуск и прочитать его (вдруг кто-то не получит выпуск по почте?). Тоже самое я сделал и для второй своей рассылки по правам потребителей.

________________

Мне очень нравится, как вы уже разбираете программы для практики. Поверьте, мне это доставляет море удовольствия! Некоторые варианты и решения я разместил на сайте.

_________________

Спасибо всем, кто голосует на сайте. Пока лидирует "Быстро DOS, а затем Win". Быстро вовсе не означает "галопом по европам". Мы не перейдем к Win до тех пор, пока досконально не изучим DOS.

В этом выпуске мы еще рассмотрим несколько новых операторов, а с 10 уже начнем писать программы (оболочка а-ля "Нортон Коммандер", вирус, резидент). Акцент будем делать на оболочку. На мой взгляд нам понадобится месяцев 5-6 для изучения DOS. Но я могу ошибаться..

Программа из прошлого выпуска.

Надо мне научиться оформлять программы по другому, т.к. настоящее оформление очень корявое. Пока времени не хватает на все...

Давайте разберем программу из прошлого выпуска.

Вот она:

_________________

...

;опустим код CSEG и пр.

(1) Begin: mov ax,3D00h ;будем открывать файл для чтения

;обратите внимание, как мы записываем операторы (сразу за меткой). Так тоже можно

(2) mov dx,offset File_name ;DS:DX указывают на путь к файлу

(3) int 21h ;открываем

(4) jc Error_file ;если произошла ошибка (нет такого файла, слишком много открытых файлов, ошибка чтения) - то на метку Error_file

(5) mov Handle,ax ;запомним номер файла в переменной Handle

(6) mov bx,ax ;для того, чтобы прочитать файл нужно в BX указать его номер, полученный после открытия. Он у нас в AX. Загрузка числа в регистр с другого регистра (а, тем более, если используется AX) происходит быстрее, чем с памяти (переменной). Поэтому загружаем с AX, а не с переменной. Хотя запись mov bx,Handle не будет ошибочной.

(7) mov ah,3Fh ;функция 3Fh - чтение файла

(8) mov cx,0FF00h ;будем читать 0FF00h

(9) mov dx,offset Buffer ;DS:DX указывает на буфер в памяти для чтения

(10)int 21h ;все готово. Читаем

(11)mov ah,3Eh ;закрываем файл

(12)mov bx,Handle ;номер файла должен быть в BX. Но т.к. он менялся, то загрузим его с нашей переменной (Handle)

(13)int 21h ;закрываем файл

(14)mov dx,offset Mess_ok ;загрузим в DX строку с сообщением о том, что все в порядке

(15)Out_prog: mov ah,9 ;функция 09h - вывод строки на экран (можно было и не писать!)

(16)int 21h ;выводим строку

int 20h ;выходим из программы

(17)Error_file: mov dx,offset Mess_error ;загрузим в DX строку с сообщением о том, что не смогли открыть файл

(18)jmp Out_prog ;и пойдем на метку Out_prog (зачем нам дублировать код, если он уже есть?)

;Данные

(19)Handle dw 0 ;резерв 2 байта для нашей переменной

(20)Mess_ok db 'Файл загружен в память! Смотрите в отладчике!$' ;понятно

(21)Mess_error db 'Не удалось открыть (найти) файл ' ;эти строки...

(22)File_name db 'c:\msdos.sys',0,'!$' ;... рассмотрим ниже...

(23)Buffer equ $ ;...

_________________

Для многих (я бы сказал, почти для всех) остались непонятными строки (21) - (23). Кто полазил в отладчике - много чего понял и узнал нового. Давайте подробней рассмотрим указанные команды.

Запомните оператор: $. При ассемблировании нашей программы Ассемблер заменит этот знак на адрес, по которому он расположен. Вот пример:

(1) CSEG segment

(2) assume cs:CSEG

(3) org 100h

(4) Begin:

(5) My_lab equ $

(6) My_lab2 equ $+2

(7) mov bx,offset My_lab

(8) mov bx,offset My_lab2

(9) int 20h

(10) CSEG ends

(11) end Begin

Строки (5) и (6) места в памяти не занимают (как и метки). Ассемблер (при ассемблировании) запомнит, что метка My_lab находится по адресу 100h (помните: org 100h?), а метка My_lab2 - 102h. Рекомендую Вам посмотреть в отладчике эту программу.

В программе из прошлого выпуска (как вы уже поняли) мы размещаем Buffer в конце кода. Т.о. оператор:

mov dx,offset Buffer

занесет в DX адрес (смещение) на первый свободный байт, расположенный за телом программы, в нашем сегменте (CSEG). По этому адресу мы и будем загружать в память данные из файла. В отладчике это хорошо видно.

Что касается строк (21) - (22). На сколько вы помните из прошлых выпусков, функция 09h прерывания 21h выводит на экран строку. Сама строка должна заканчиваться символом $. Я уже говорил, что если этот знак убрать, то функция, выведя строку на экран, продолжит выводить остальные символы до тех пор, пока в памяти не встретится тот самый "бакс" - $.

Теперь внимательно смотрите на строки (21) - (22):

(21)Mess_error db 'Не удалось открыть (найти) файл '

(22)File_name db 'c:\msdos.sys',0,'!$'

Что мы видим? Мы видим то, что не видим в конце строки (21) символ $ (да простят меня за каламбур!). Функция 09h (если файл не был найден) выведет на экран следующее:

Не удалось открыть (найти) файл c:\msdos.sys !

Символ '0' будет отображен как пробел. А для чего нужен '0' в строке (22)? При открытии файла в DS:DX должен быть указан сам файл. Строка должна завершаться символом '0'. Если этот символ убрать, то функция скорее всего вернет ошибку. Ведь файла c:\msdos.sys!$ не существует!

Можем сделать и так, конечно. Только мы потеряем байты:

Mess_error db 'Не удалось открыть (найти) файл c:\msdos.sys!$'

File_name db 'c:\msdos.sys',0

Какой смысл?

Вот и разобрались... Мы будем очень часто на практике использовать данный метод. Поэтому, если у вас и остались "темные моменты", мы их постепенно "просветлим".

Программка для практики.

Давайте поподробнее рассмотрим работу с файлами. Вот пример:

___________________

CSEG segment

assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG

org 100h

; -------------- Начало -------------

Begin:

mov dx,offset File_name

call Open_file

jc Error_file

; -------------- Открыли файл -----------

mov bx,ax

mov ah,3Fh

mov cx,offset Finish-100h

mov dx,offset Begin

int 21h

; ------------- Прочитали файл ----------------

call Close_file

; ------------ Выводим сообщение --------------

mov ah,9

mov dx,offset Mess_ok

int 21h

ret

; ---------- Не смогли найти файл -----------------

Error_file:

mov ah,2

mov dl,7

int 21h

ret

; ======= Процедуры пошли... ==========

; --- Открытие файла ---

Open_file proc

cmp Handle,0FFFFh

jne Quit_open

mov ax,3D00h

int 21h

mov Handle,ax

ret

Quit_open:

stc

ret

Handle dw 0FFFFh

Open_file endp

; --- Закрытие файла ---

Close_file proc

cmp Handle,0FFFFh

je No_close

mov ah,3Eh

mov bx,Handle

int 21h

mov Handle,0FFFFh

No_close:

ret

Close_file endp

; ===== Данные ======

File_name db 'less009.com',0

Mess_ok db 'Все нормально!', 0Ah, 0Dh, '$'

Finish equ $

CSEG ends

end Begin

______________________

ВНИМАНИЕ: этот файл нужно сохранить как less009.asm!

Вот работы вам на целую неделю!!!

Сложно. Очень сложно... Да и отладчик работать не будет... Что же делать-то? Ищите, экспериментируйте, пробуйте все варианты... Здесь много чего интересного!

Моя проблема.

Друзья мои! Случилось непредвиденное. У меня появились проблемы с работой.

Мне очень горько об этом сообщать, но придется. Весь наш отдел попадает под сокращение (правда, предлагают очень хорошие условия (деньги платят)). Тем не менее, доступа к Сети у меня не будет какое-то время. Дома я не могу пользоваться, т.к. очень плохая АТС (шаговая). Я даже не могу получить почту. Не шлите, пожалуйста, пока письма...

В связи с этим рассылка уходит на вынужденный отпуск. На какой период - не знаю. Но очень надеюсь, что ненадолго. При первой же возможности я выйду на связь.

Естественно, у вас будут возникать вопросы по поводу Ассемблера. В связи с чем рискну оставить свой домашний телефон в Москве (огромная просьба: не злоупотребляйте этим!): 492-23-53. Если возникнут вопросы, на которые вы не сможете найти ответ ни на форуме, ни где-либо еще, то звоните мне. Я, конечно, понимаю, что многим будет сложно мне позвонить (межгород все-таки), но все-таки хоть что-то...

Я также буду благодарен вам за любые советы и предложения относительно работы (хотя варианты у меня пока есть).

Вот и все. Друзья мои! Не скучайте! Мы скоро увидимся!

 

Удачи Вам!

С уважением,

Калашников Олег ( oleg77@online.ru?Subject=Ассемблер: )

Сайт: www.Kalashnikoff.ru

[Следующий выпуск] [На главную страницу]

u="u496.71.spylog.com";d=document;nv=navigator;na=nv.appName;p=1; bv=Math.round(parseFloat(nv.appVersion)*100); n=(na.substring(0,2)=="Mi")?0:1;rn=Math.random();z="p="+p+"&rn="+rn;y=""; y+=""; y+=""; y+=""; d.write(y);if(!n) { d.write("

Соседние файлы в папке Выпуски