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

Ассемблер? Это просто! Учимся программировать Выпуск ╧ 005


Служба Рассылок Городского Кота

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


Выпуск N 005.

Сегодня у нас:

План рассылки:


Информация для вновь подписавшихся

Пожалуйста, возьмите предыдущие выпуски в одном из следующих мест:

www.subscribe.ru/archive/comp.prog.assembler

www.oleg77.newmail.ru/Assembler/For_assemblers.html

Написать мне с просьбой выслать: oleg77@online.ru

Постарайтесь прежде перекачать из указанных выше сайтов. Если ничего не получится, то пишите мне.

Ознакомьтесь с предыдущими рассылками. В них находится важная информация, которую необходимо знать!

Благодарю всех, кто подписался.


Ваши письма

Дорогие мои! На прошлой неделе я получил от Вас огромное количество писем. Ответил всем, кто мне присылал. Как я уже говорил, кто не получил ответ, напишите еще раз, т.к. мой ящик был частенько перегружен. Очень многие просили выслать предыдущие выпуски, которые занимают 100 Кб.

Также поступало много вопросов по поводу возникновения ошибок в программах, либо в ассемблере и компоновщике. Я старался отвечать как можно быстрее, понимая, что всем вам нетерпелось быстрее научится "топтать кнопки".

Пожалуйста, указывайте в письме, если вы хотите, чтобы Ваше полное имя с e-mail было опубликовано.

Возникло несколько заморочек с моим сайтом. Все исправил. Прошу прощения за причиненные неудобства.

Многие уже довольно-таки хорошо освоили Ассемблер из моих предыдущих выпусков, чем меня порадовали своими собственными программами (особенно АНДРЕЙ, Дмитрий).

Очень порадовал меня Дмитрий Лазебник, который предложил вариант оформления рассылок. Очень здорово у него все получилось. Думаю, что я помещу это вариант на сайт к себе (с разрешения Дмитрия).

Есть еще несколько вопросов по поводу отладчика CodeView. Дело в том, что для полноценной работы CV недостаточно одного файла cv.exe. Нужно иметь еще несколько дополнительных библиотек, которые в 2 раза больше cv.exe. Подписчик Eugene выслал мне по e-mail TASM 3.01 и AFD, о котором я писал в первом выпуске рассылки. AFD, конечно, не очень актуален в настоящий момент по следующим причинам:

  • не поддреживает 32-х разрядные регистры;
  • не распознает формат PE и NE (Windows).

Зато у него есть преимущества:

  • удобен и прост в использовании;
  • показывает в одном окне регистры, код, память и др.

Для изучения работы программ в DOS его больше чем достаточно. Спасибо, Eugene!

В прежние времена я работал только с AFD. Затем, к моему сожалению, его потерял. Теперь AFD можно взять на моем сайте (прибл. 64 Кб). Николай помог заархивировать этот файл, в результате чего его размер уменьшился почти в два раза!

Спасибо всем, кто помог мне справиться с текущими проблемами!

Пришло несколько пожеланий сменить фон рассылки, т.к. на ч/б принтере плохо видны символы. Я, как видите, сделал фон посветлее по вашим просьбам.

Андрей Литвиенко предложил алгоритм по переводу двоичных чисел в десятичные и наоборот:

Вот таблица в помощь:

128 64 32 16 8 4 2 1
0 0 0 1 0 1 0 0

В верхнем столбике вписываем разряды, а в нижнем - биты.

Теперь просто складываем:

128*0 + 64*0 + 32*0 + 16*1 + 8*0 + 4*1 + 2*0 + 1*0 = 20

или еще проще:

0+0+0+16+0+4+0+0 = 20

Спасибо Андрею!

Gregory спрашивал, каким ассемблером лучше пользоваться: Borland (TASM) или Microsoft (MASM). Под DOS я всегда писал программы используя MASM 5.10, которым был очень доволен. В принципе, большой разницы между MASM и TASM на данный момент нет. Но, на мой взгляд, под Win9x лучше использовать TASM32.

Igor Korot указал не неточность в программе из прошлого выпуска. 0B800h - сегмент видеобуфера цветного дисплея (CGA, EGA, VGA, sVGA), но не монохромного (у него 0A000h, кажется).

__________

Для тех, кто мало знаком с HTML. Для того, чтобы было легче рассортировать ваши письма, отправляйте, пожалуйста, письмо с того места, с которого я вас прошу отправить. Если вы, например, наведете курсор "мыши" на слово "от сюда" из следующего абзаца, то увидите внизу экрана надпись: mailto:oleg77@online.ru?Subject=Разместить мой e-mail

Когда мне придет письмо, то в поле "Тема:" уже будет указано то, что размещается после знака "=".

__________

Энергичный и веселый парень Сергей (sergey@email.orgus.ru), с которым у меня завязалась небольшая переписка, предложил такой вариант:

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

Есть еще вариант. Newmail.ru любезно предоставил мне возможность открыть собственный форум и чат. Форум в настоящий момент создается, и вы скоро (через 1-2 дня) сможете его посетить. Адрес форума будет на моем сайте. Можно также открыть чат по вашим просьбам. Я там также буду появляться.


Смена сайта

Уважаемые подписчики! 27 июля 2000 года у меня изменился адрес сайта. Дело в том, что Narod.ru отказал мне в предоставлении дальнейших услуг в связи с тем, что я разместил на своем сайте Turbo Assembler. Дорогие мои! Я хотел, чтобы у вас все было под рукой, чтобы вы не бегали на рынок и не искали там необходимые программы. С вашего разрешения я опубликовываю завязавшуюся между мной и г-ном Dilevsky переписку на прошлой неделе (стиль письма и орфография сохранены. Некоторые фразы вырезаны мной в целях экономии места, но суть от этого не меняется. E-mail г-на Dilevsky на всякий случай удален).

От: Alexander Dilevsky

Дата: 24 июля 2000 г. 18:45
Hello Oleg!

На вашем сайте наблюдаются некоторые ашипки: команда push imm работает только на процессорах 80286 и выше (ну, может еще на 186). Поэтому push 0B800h может и не сработать.

Компьютер обычно вешается комбинацией cli hlt. На один байт короче получается :) И под форточками это обычно не работает, ибо кто ж даст пользовательской программе запретить все прерывания..

И уберите, пожалуйста, со своего сайта tasm. Я что-то не слышал, чтобы его выпускали в бесплатное пользование.

Alexander Dilevsky
narod.ru system administrator

From: Калашников Олег [mailto:oleg77@online.ru]
Sent: Thursday, July 27, 2000 3:43 PM
Здравствуйте, Александр!

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

Далее. Комбинация cli hlt очень четко контролируется Win. В случае выполнения данных строк Win сообщает, что программа выполнила некорректную операцию, но сам Win не виснет!

В моем примере cli jmp $ вешается не только DOS, но и Win9x. Если Вы не в курсе, то хотя бы проверили, прежде чем писать...

Tasm я убирать не собираюсь. Кто Вам сказал, что у меня нет соответствующей лицензии (разрешения) на размещение его на сайте?

Счастливо!

От: Alexander Dilevsky

Дата: 27 июля 2000 г. 8:17
Будьте добры, пришлите мне хотя бы текст документа, разрешающего выкладывать tasm на сайт, позволяющий скачивать его всем желающим... Лучше, конечно, копию этого документа. Насколько мне известно, компания Borland... не позволяла его бесплатного распространения...

From: Калашников Олег [mailto:oleg77@online.ru]
Sent: Thursday, July 27, 2000 7:19 PM
Уважаемый Alexander Dilevsky!

Я не обязан высылать такую информацию всем подряд. Тем более, что у меня нет ни времени, ни желания возиться с данным документом..., чтобы удовлетворить Ваше любопытство. Я предъявлю его только уполномоченным на то лицам и по их официальному требованию...

От: Alexander Dilevsky
Дата: 27 июля 2000 г. 12:46
Как системный администратор сервера narod.ru я все-таки попрошу вас прислать мне этот документ либо удалить с вашего сайта Turbo Assembler. В противном случае мы будем считать, что вы нарушаете права компании Inprice Corporation и пункт 5.3.5 Пользовательского Соглашения, что приведет к удалению вашего сайта.

В письме, полученном из Inprise Corporation, утверждается, что Turbo Assembler не является свободно распространяемым продуктом и размещение его на вашем сайте нарушает лицензионное соглашение Inprise/Borland.

Alexander Dilevsky

From: Калашников Олег [mailto:oleg77@online.ru]
Sent: Thursday, July 27, 2000 7:39 PM
Уважаемый Alexander Dilevsky!

В таком случае, прошу Вас выслать мне письмо, полученное от компании Inprise Corporation, в котором говорится о том, что мне не дано право помещать на сайт Narod.ru TASM.

По данному письму я должен точно установить, что оно получено от указанной выше компании, а не напечатано каким-либо лицом, не имеющим отношения к Inprise Corporation.

Более того, мне необходимо удостовериться в том, что Вы действительно являетесь системным администратором сайта Narod.ru. Каким образом будет это доказано - меня не интересует.

В противном случае, никаких ответных писем Вам выслано не будет.

С уважением,

_____________________________
Калашников Олег Александрович
Контракт-менеджер
ФПС "БИН"

В ответ уважаемый г-н Dilevsky выслал мне письмо, в котором говориться о том, что Borland не разрешала размещать на сайтах свои продукты.

Вот так у нас всегда, друзья мои: борятся не с причиной, а со следствием. То, что можно купить любое программное обеспечение за полтинник на Митинском рынке или на Горбушке, это никого не интересует. TASM же, размещенный на моем сайте, очень сильно взволновал г-на Dilevsky, за что сайт был ликвидирован с сервера Narod.ru.

Да, моя вина в том, что я не выслал документ, разрешающий размещать на сайте TASM. Но, как говорится, не бывает худа без добра. Я перешел на новый сервер NEWMAIL.RU, что и предлагали мне сделать многие подписчики, т.к. связь с "Народом" не совсем качественная (по крайней мере, мне приходилось перекачивать для проверки со своего сайта TASM по 2-3 раза, т.к. он приходил "битый", о чем я предупреждал вас в прошлом выпуске. Многие из вас также жаловались на плохую связь, предлагая мне перейти на newmail). Теперь проблема решена. Более того, NEWMAIL не требует никах документальных подтверждений программных продуктов, размещенных на их сервере.

Новый адрес моего сайта: www.oleg77.newmail.ru


Ваши предложения по ведению рассылки

В прошлом выпуске я попросил вас прислать свои предложения по поводу того, какую программу вы бы хотели писать, параллельно изучая Ассемблер. Вот какие варианты были предложены (если Вы хотите проголосовать, то нажмите в соответствующей строке кнопку "мыши"; в теле письма желательно ничего не укаывать совсем, т.к. может не выдержать мой ящик):

Некоторые пояснения.

На Ассемблере очень сложно написать графическую игру. Для этого обычно используются специальные графические программы, в которых рисуются изображения людей, деревьев, дорог и пр. А на Ассемблере (и то не всегда) пишется только ядро, которое управляет графикой.

Дизассемблер тоже не так-то просто написать, хотя вполне реально. Для этого нужно будет изучить формирование машинного кода в компьютере, а это довольно большой курс.

Viewer для просмотра графики можно сделать, если кто-нибудь пришлет формат того или иного файла (jpg, bmp и т.п.). Я, к сожалению, этим никогда не занимался...

Голосуйте, друзья мои! Ваши письма принимаются до выхода следующего выпуска. Жду с нетерпением!


Немного теории

Я получил много писем с таким вопросом:

TASM выдает ошибку: Near jump or call to different CS.

Я предложил вставить строку assume cs:CSEG. Что же происходит?

Дело в том, что эта строка указывает Ассемблеру на привязку сегментного регистра CS к нашему сегменту (CSEG). MASM ассемблирует прекрасно и без этой строки. Если оператор assume отсутствует, то MASM как бы по умолчанию вставляет ее автоматически.

Другое дело TASM. Он, встретив в программе строки вида:

loop Label_1

jmp Label_2

call Procedure

не может "понять" к какому сегменту следует обратиться (CS, DS, ES) и выдает сообщение об ошибке.

Как уже говорилось, мы пишем com-файлы в которых всего один сегмент (мы обзываем его CSEG). Если вы создадите еще один (например, DSEG), то компоновщик (link.exe), при попытке создать com-файл, выдаст ошибку.

Чтобы полностью закрыть данную тему, привожу полный вид разбираемой нами строки:

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

Этим мы указываем Ассемблеру на то, что сегментные регистры CS, DS, ES, SS будут указывать на наш единственный сегмент.


Новые операторы

Сегодня рассмотрим всего один оператор, но зато какой!

Команда

Перевод (с англ.)

Назначение

Процессор

CALL метка call - вызов Вызов подпрограммы 8086

Итак, вы уже немного знакомы из предыдущих выпусков с подпрограммами.

Допустим, нам необходимо написать программу, которая выводит на экран сообщение

Нажмите любую клавишу...

ждет нажатия клавиши, а затем выводит еще одно сообщение:

Вы успешно нажали клавишу!

ждет от пользователя клавишу и завершается.

Что нужно для этого? Вызвать два раза функцию 09h прерывания 21h и столько же функцию 10h прерывания 16h (вы это уже прекрасно знаете).

Вот так:

...

(1) mov ah,9

(2) mov dx,offset Mess1

(3) int 21h

(4) mov ah,10h

(5) int 16h

(6) mov ah,9

(7) mov dx,offset Mess2

(8) int 21h

(9) mov ah,10h

(10) int 16h

(11) int 20h

...

(12) Mess1 db 'Нажмите любую клавишу...$'

(13) Mess2 db 'Вы успешно нажали клавишу!$'

...

Там, где стоит многоточие, опущен код программы. Я буду часто так делать для того, чтобы постоянно не печатать операторы, тем самым занимая место в рассылке. Я думаю, вы без труда разберете, какие команды необходимо вставить...

Смотрим дальше. Строки (1) - (3) и (6) - (8) выводят строку. Они очень похожи, за исключением загрузки в DX разных строк.

Строки же (4) - (5) и (9) - (10) полностью идентичны. Получается, что мы теряем байты...

Чтобы упростить программу и, тем самым, уменьшить ее размер, воспользуемся оператором CALL (создадим подпрограммы). Вот что у нас получится:

...

(1) mov dx,offset Mess1

(2) call Out_string

(3) call Wait_key

(4) mov dx,offset Mess2

(5) call Out_string

(6) call Wait_key

(7) int 20h

(8) Out_string proc

(9) mov ah,9

(10) int 21h

(11) ret

(12) Out_string endp

(13) Wait_key proc

(14) mov ah,10h

(15) int 16h

(16) ret

(17) Wait_key endp

(18) Mess1 db 'Нажмите любую клавишу...$'

(19) Mess2 db 'Вы успешно нажали клавишу!$'

...

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

Итак, что здесь происходит? Думаю, что многие уже догадались. Однако, нужны нектороые пояснения.

Минутка внимания! В строке (1) загружаем в DX адрес строки Mess1. В строке (2) вызываем подпрограмму, которую мы назвали Out_string. Что делает компьютер? Он запоминает адрес (смещение) следующей команды (строка (3)) и переходит на метку Out_string (строка (8)). DX при этом не меняется (т.е. в нем сохраняется адрес строки Mess1)! В строках (9) - (10) используем функцию 09h прерывания 21h для вывода строки на экран. В строке (11) компьютер берет запомненный адрес и переходит на него (в данном случае на строку (3)) (ret - return - возврат). ВСЕ! Процедура отработала!

У вас, вероятно, появился вопрос: А где это, интересно, компьютер запоминает куда нужно возвращаться???

Отвечу вкратце, т.к. эта тема достойна отдельного выпуска. Есть такая область памяти. Назвается стек (stack). Вот именно туда и "ложится" адрес для возврата из подпрограммы. В следующем выпуске мы подробно рассмотрим стек, сегмент стека, а также регистры SS и SP, которые отвечают за стек.

Надеюсь, что разобраться в дальнейшей работе программы (начиная со строки (3)) не составит труда. Все ведь очень просто!

Обратите внимание на оформление процедуры:

______________

Out_string proc

Out_string endp

______________

Out_string - название процедуры

Proc - procedure - процедура

endp - end procedure - конец процедуры

Стоит еще отметить, что из одной подпрограммы можно вызывать другие. Из других - третьи. Главное правило - не запутаться в возвратах, иначе компьютер просто виснет! Внимательно следить за работой подпрограмм позволяет отладчик.


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

Хотите увидеть всю мощь Ассемблера?

Давайте усовершенствуем программу с предыдущего выпуска.

(1) CSEG segment

(2) assume CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG

(3) org 100h

(4) Start:

(5) mov ax,0B800h

(6) mov es,ax

(7) mov al,1

(8) mov ah,31

(9) mov cx,254

(10) Next_screen:

(11) mov di,0

(12) call Out_chars

(13) inc al

(14) loop Next_screen

(15) mov ah,10h

(16) int 16h

(17) int 20h

(18) Out_chars proc

(19) mov dx,cx

(20) mov cx,2000

(21) Next_face:

(22) mov es:[di],ax

(23) add di,2

(24) loop Next_face

(25) mov cx,dx

(26) ret

(27) Out_chars endp

(28) CSEG ends

(29) end Start

Не устали?

Будем разбираться... Хотя, собственно, ничего сложного нет.

Итак, строки (1) - (8), (15) - (17) и (28) - (29) опускаем. Вопросов по ним быть не должно.

В строке (9) заносим в CX число 254, указывающее на то, сколько раз будет выполняться основной цикл. Строки (10) и (14) - "голова" и "хвост" нашего основного цикла соответственно. DI будет меняться в процедуре, поэтому нам необходимо будет его постоянно аннулировать (11). В строке (12) вызываем процедуру, которая заполнит экран кодом символа, который находится в AL (в первом случае - это 01 "рожица"). Все! Теперь экран заполнен кодом 01. При этом DI будет равно 2001 (поэтому нам и нужно его обнулять). Далее увеличим на единицу код, который находится в AL (теперь AL содержит 02 - тоже "рожица", но немного другого вида) (строка (13)), уменьшим счетчик на 1 и перейдем к заполнению экрана кодом 02 (строка 14). И так 254 раза.

Теперь процедура.

В строке (19) сохраним CX (просто перенесем его в DX), т.к. он будет изменен во вложенном цикле ниже. Строки (21) и (24) - "голова" и "хвост" вложенного цикла, который будет выполняться 2000 раз (надо же заполнить экран полностью) (см. строку (20), в которой загружаем счетчик в CX). Все! Осталось только восстановить CX (строка (25)) и выйти из подпрограммы (26).

Итак, у нас здесь два цикла: основной и вложенный (так мы их назвали). Основной выполняется 254 раза, а вложенный - 2000 раз.

Если у Вас Pentium, то, боюсь, что вы не успеете заметить вывод всех символов. Очень быстро работает, хотя это далеко и не оптимальный алгоритм (кто знаком с языком - подтвердят мои слова).

Для исследования данного примера я рекомендую вам воспользоваться отладчиком. Т.к. у многих есть CV и AFD, то вкратце еще раз объясню, какие кнопки давить.

CodeView:

F8 - пошаговое выполнение команд (с заходом в подпрограммы);

F10 - выполнение команды за один шаг (без захода в подпрограммы).

AFD:

F1 - пошаговое выполнение команд (с заходом в подпрограммы и прерывания);

F2 - выполнение команды за один шаг (без захода в подпрограммы и прерывания).

Что-то я тут намудрил... Ну, поэксперементируйте с клавишами. Принцип прост.

На сегодня все!

Удачного программирования!

С уважением,

Калашников Олег (oleg77@online.ru).


FAQ на сайте для любопытных

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



http://subscribe.ru/
E-mail: ask@subscribe.ru

В избранное