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

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


Служба Рассылок Subscribe.Ru проекта Citycat.Ru

Ассемблер? Это просто! Учимся программировать
______________________________________

Выпуск N 21 (Оболочка)

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

  • Информация для новеньких

  • Организационные вопросы

  • Ваши письма

  • Оболочка



  • Прежде чем приступать к изучению материала в данном выпуске, Вам необходимо ознакомиться с предыдущими.

    Всю необходимую информацию (предыдущие выпуски, адреса экспертов, необходимые программы, документацию, а также многое другое) можно найти на сайте http://www.Kalashnikoff.ru. Рекомендую Вам прежде ознакомиться с разделом "Информация для новых подписчиков".

    Если у Вас нет выхода в Сеть, то предыдущие выпуски рассылки, информацию для новеньких и адреса экспертов можно получить по почте, направив пустое письмо по адресу AssmNew@Kalashnikoff.ru. Информация (300 Кб) будет выслана Вам в течение двух рабочих дней с момента получения Вашего письма-запроса. Однако, пожалуйста, не злоупотребляйте этим, так как высылка писем подобного объема несет дополнительную нагрузку на почтовые сервера.



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

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

    Итак, начнем по-порядку.

    ___________

    1. Приглашаются помощники:

    • для перевода текста с формата HTML в формат MS Word;
    • для перевода с формата *.txt (Windows) в формат MS Word (вопросы и ответы экспертов).

    Если у вас есть время и возможность, то, пожалуйста, напишите мне. Буду рад рассмотреть ваши предложения. Более бодробную информацию можно получить в письме, которое следует направить по адресу Assembler@Kalashnikoff.ru. В теле письма, пожалуйста, укажите, чем вы можете помочь. Буду очень признателен...

    ___________

    2. Требуются ведущие рубрики "Ваши письма".

    Необходимо качественно перевести письма подписчиков в формат HTML из текстового формата и оформить это соответствующим образом (как во всех наших выпусках оформлялась данная рубрика). Что я могу предложить? Предоставить вам полное ведение рубрики "Ваши письма" (с моими поправками, если понадобится). Ваше имя, e-mail, URL будут указаны в рассылке. Письма подписчиков будут высылаться вам по почте от моего имени, но без указания электронного адреса подписчика. Ваша задача: отобрать наиболее интересные для подписчиков письма, исправить по мере необходимости орфографические ошибки, оформить письма в формате HTML и выслать мне готовый вариант до выхода следующего номера рассылки (примерно за 2-5 дней). Вот, собственно, и все!

    ___________

    3. Экспертные группы (следует внимательно прочесть экспертам и подписчикам, задающим вопросы!).

    К сожалению, мне пришлось закрыть три экспертные группы в связи с тем, что данным экспертам практически не приходит вопросов. Закрыты следующие группы:

    1. Эксперты по работе с Turbo Debugger;
    2. Эксперты по работе с AFD;
    3. Эксперты по работе с CodeView.

    Как показало время, большинство вопросов задается группе "Эксперты по общим вопросам программирования на Ассемблере под DOS". Безусловно, лидирует по количеству отвеченных вопросов эксперт Slava V. Четкие ответы, лаконичное содержание, простой стиль изложения, оперативность ответов - все это делает Slav'у незаменимым помощником для меня и для всех подписчиков. Те из вас, кто получил ответ от Slav'ы, подтвердят мои слова. Как ему это удается - ума не приложу! В связи с этим хочу повторно выразить благодарность Slav'е за оказанную помощь как мне, так и всем вам, дорогие подписчики.

    Однако, кто-то из экспертов старается отвечать на ваши вопросы, а кто-то зарегистрировался и за все существование экспертных групп не ответил ни на один вопрос! Это особенно относится к указанной выше группе. Экспертов в данный момент довольно-таки много. Отбирать вручную и искать "сачков" нет времени. Поэтому мне придется поступить не очень хорошо, попросив вас, уважаемые эксперты, пройти т.н. перерегистрацию всех без исключения экспертов. Для этого необходимо направить мне пустое письмо до 31 января 2001 года включительно по адресу: Registration@Kalashnikoff.ru, указав в теле письма ваш электронный адрес по которому вы зарегистрированы в экспертной группе. В ответ на ваше письмо придут новые правила работы экспертных групп. Эксперты, от которых я НЕ получу писем до указанной даты, исключаются из числа экспертов. Сурово? Зато на мой взгляд справедливо по отношению к тем подписчикам, которые хотели бы стать экспертами, да группы уже укомплектованы, и мне с горечью в сердце приходится отказывать всем желающим. В последующих выпусках я напишу о том, сколько мест освободилось в той или иной группе. Надеюсь, что со временем мы соберем отличную экспертную группу в помощь вам, дорогие мои читатели.

    Подписчики, желающие задать вопросы экспертам, должны ознакомиться с новыми правилами (установленными 15 января 2001 года), которые можно найти на нашем сайте. Если у вас проблемы с Интернетом, то напишите мне письмо по адресу AssmExperts@Kalashnikoff.ru. Данная информация будет выслана вам в течение двух рабочих дней. Подписчикам, получившим или ознакомившимся на сайте с новыми правилами и адресами экспертов после 15.01.2001, волноваться не стоит! Данные правила упорядочивают работу экспертных групп, а также вносят определенные требования для подписчиков задающих вопросы, с тем, чтобы у нас не возник хаос, беспорядок и пр. Я также постарался оградить экспертов от вопросов, которые задают "ленивые" подписчики, т.е. те, кто столкнувшись с "малюпасенькой" проблемкой, сразу же задает вопрос экспертам. Дорогие мои! Так ведь не интересно! Уверяю вас, что пасуя перед сложностями (или обращаясь с мелкой проблемой к помощникам), вы мало чего добьетесь как в изучении Ассемблера, так и во всем остальном. Постарайтесь приложить максимум услилий для решения возникшей проблемы. Если же ничего не выходит, то - пожалуйста. Эксперты с огромным удовольствием ответят на ваш вопрос(ы). По содержимому вопроса ведь сразу видно, думали вы или нет, прежде, чем написали экспертам...

    Все вопросы, поступившие в адрес экспертов, но противоречащие новым правилам, игнорируются экспертами!

    ___________

    4. Обсуждение книги.

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

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

    ___________

    5. Новые поступления на сайте.

    На нашем сайте (http://www.Kalashnikoff.ru) теперь можно найти пособие по напсанию вирусов на русском языке, причем, в довольно-таки понятном и простом для начинающего программиста изложении. В данном пособии описаны несколько вариантов вирусов (включая резидентные вирусы и вирусы, заражающие *.exe-файлы). Надеюсь, что вы почерпнете из этого файла много действительно полезной и нужной информации, которая поможет вам освоить все тонкости программирования на Ассемблере.

    Более того, те, кто используют отладчик SoftIce при изучении Ассемблера, могут найти на указанном выше сайте документацию на русском языке по работе с SoftIce. Берите и качайте на здоровье!

    ___________

    6. Смена внешнего вида сайта.

    Ничто не стоит на месте. Все находится в движении, меняется. Вот и сайт наш уже третий раз поменял свой облик (условно - Версия 3.0). Сидел я, мучал свою несчастную, убитую горем "четверку" все выходные. Зато теперь плод моих трудов вы можете оценить лично. Был бы безмерно счастлив, если бы вы оставили запись (ваше мнение) в Гостевой книге.

    Конечно, пока что еще не все подразделы сведены к одному дизайну, стилю (например, Гостевая и форум). Но, тем не менее уже можно сделать однозначные выводы.

    Очень надеюсь, что мне скоро удастся сделать собственную Гостевую книгу и форум. Пока что ручки все не дотягиваются до этого.

    Я же, в свою очередь, хотел бы выразить глубокую благодарность за качественный хостинг компании AGAVA и лично Бобу Марлину (BoB MaRLiN) за помощь в создании настоящей Гостевой книги и выделенного места под нее.

    Если у вас есть время и желание написать форум и (или) гостевую на сайте http://www.Kalashnikoff.ru, то буду вам безмерно благодарен. Естественно, все ваши права будут соблюдены. Мой провайдер (www.100mb.ru) позволяет создавать свои CGI-скрипты в каталоге cgi-bin. Если вы надумали написать что-либо, то не нужно мне слать письмо с предложениями. Просто сделайте и пришлите (если не сложно). Я все выложу на сайт. Главное условие - чтобы форум и гостевая были одного стиля с сайтом. Очень на вас надеюсь...

    Да! Чуть не забыл! Теперь статистику посещений нашего сайта можно найти сдесь: http://www.Kalashnikoff.ru/usage. Она обновляется ежедневно. Статистика включает в себя трафик, страны и регионы, жители которых заходят на сайт, посещаемость по часам и многое другое. Зачем это? Да так, вдруг кому интересно будет...

    И вот еще: установил на сайте кнопку, которая сигнализирует всем посетителям о том, в Сети ли я сейчас или нет. Мне понравилось это дело...



    Дорогие мои подписчики! Ваши письма мы рассмотрим в следующем спецвыпуске, который выйдет до 26 января 2001 года. Дело в том, что писем ваших очень много, и большинство из них будут интересны всем подписчикам рассылки. Только вот байты сейчас не позволяют сделать это... Так что подождите, пожалуйста, спецвыпуск 022.



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

    Тем не менее, если вам лень копировать каждый файл в DOS-формат, то вы можете перекачать все целиком отсюда: http://www.Kalashnikoff.ru/Assembler/Issues/Enclosures/Sshell21.rar.

    Sshell21.asm
    Data.asm

    Display.asm

    Files.asm

    Keyboard.asm

    Main.asm


    Messages.asm


    Итак, поехали...

    Если вы уже запустили нашу "оболочку", то ничего особенно интересного вы, скорее всего, не нашли. Мы просто читаем содержимое текущего каталога в память, и выводим первые двадцать найденных файлов на экран.

    Однако, присмотревшись, вы поймете, что наша оболочка проделывает уйму работы. А именно:

    _______

    1. Ищет первый файл;

    2. Если это '.', то см. пункт 4; *

    3. Заносит в память имя найденного файла;

    4. Ищет следующий файл;

    5. Заносит имя найденного файла в память;

    6. Файлы закончились?

    7. Нет - см. пункт 4.

    8. Да - начинает выводить файлы на экран.

    9. Выведено уже 20 файлов? Нет - см. пункт 8. Да - см. пункт 10.

    10. Ждет нажатия на клавишу.

    11. Пользователь нажал ESC? Да - см. пункт 12. Нет - см. пункт 10.

    12. Запрашивает пользователя: уверен ли он, что хочет выйти в DOS.

    13. Не уверен (т.е. нажал все, что угодно, кроме 'Y' или 'y') - см. пункт 10.

    14. Уверен (т.е. нажал 'Y' или 'y') - выходит в DOS.

    Вот, собственно, и алгоритм работы нашей оболочки.

    * Примечание. В любом подкаталоге первый файл всегда '.' . Точнее, это не файл, а каталог. Если в командной строке набрать 'CD .' , то директория не изменится. Т.е. данный каталог - это просто текущий каталог. Нам его не нужно выводить в оболочке. Команда DIR выводить эту директорию на экран, в отличие от оболочек.

    Теперь подробнее...

    _______

    Новшество первое.

    Обратите внимание, как мы вызываем процедуру Draw_frame (MAIN.ASM, Main_proc). На первый взгляд ничего особенного. Но это только кажется... Раньше мы заносили в стек адреса строк, которые будут выводится вверху и внизу нашей рамки, а также атрибуты этих строк. Теперь же мы атрибуты в стек не заносим. Но как же тогда строки выводятся в нужном цвете? Обратите внимание, что находится перед строками Mess_head и Mess_down:

    Mess_head db 1Eh, ' Super Shell, Версия 1.0 ',0
    Mess_down db 1Dh, ' Россия, Москва, 2001 ',0

    Вот это и есть как раз нужные нам атрибуты соответствующих строк. Поступая таким образом, мы экономим байты нашей оболочки, более того не нагружаем стек. Отпадает необходимость заносить в стек два слова атрибутов для верхней строки и два слова нижней. Процедура вывода строк на экран (DISPLAY.ASM, Draw_messfr) перед тем, как выводить строку, занесет в AH первый символ, который и будет являться атрибутом! Это проще!

    mov ah,[si] ;Первый символ строки - атрибут (см. DATA.ASM)
    inc si ;Следующий байт - начало строки
    call Count_strmid ;Вычисляем середину строки

    call Print_string ;Выводим строку на экран

    _______

    Новшество второе.

    Теперь процедура рисования рамки (DISPLAY.ASM, Draw_frame) выводит еще и линию вверху окошка по нашему требованию. А что мы добавили перед вызовом даной процедуры. Да ничего почти! Просто изменили один бит:

    push 10b ;Экран не копировать, но вывести верхнюю линию.
    call Draw_frame ;Рисуем рамку на весь экран

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

    Видите, как наша процедура совершенствуется на глазах. А это далеко не предел! Еще дальше пойдем - еще больше будет!

    Внимание! А как же нам проверить, включен ли нулевой бит или нет? Скорее всего, оператором CMP здесь не обойтись. Да, действительно, не обойтись. И вот почему.

    Представьте, что первый раз мы выводим окошко, предварительно скопировав экран, но не выводим линию вверху. Тогда нулевой бит будет равен 1:

    push 1

    Следовательно, можно проверить так (в процедуре draw_frame данное слово будет называться Other (иное)):

    cmp Other,1

    Если флаг нуля устанавливается, т.е. Other = 1, то нужно предварительно скопировать экран в память.

    Хорошо. Теперь представим, что нужно вывести окошко с линией вверху, но не копировать экран (т.е. первый бит будет равен единице, а нулевой - 0):

    push 10b ;или push 2

    ...

    cmp Other,2

    И, наконец, представим, что нужно вывести и линию вверху, и сохранить экран:

    push 11b ;или push 3

    ...

    cmp Other,3

    Вроде все нормально... Однако, тем не менее, существует проблема. Нулевой бит (т.е. следует ли копировать экран или нет) мы проверяем в начале процедуры Draw_frame (т.е. до того, как вывели окошко), а вывод верхней линии - после того, как экран скопирован (если нужно), и выведено окошко. Теперь подумайте: можно ли с помощью CMP проверить установлен ли бит нулевой, игнорируя (умышленно не замечая) все оставшиеся биты проверяемого слова (Other)? Вдумайтесь в вопрос. Не спешите читать дальше. Правда, подумайте! Возьмите листок бумаги и поэкспериментируйте! Если сами поймете что да как, то будет гораздо проще понять новый оператор...

    ...

    Не сомневаюсь, что вы нашли выход из положения. Например, так:

    mov ax,Other ;Перенесем временно в AX значение переменной Other
    push ax
    and ax,1 ;Аннулируем все биты, кроме нулевого (вспомним логические команды)
    cmp ax,1 ;Проверим, равен ли теперь AX 1?
    pop ax
    mov Other,ax ;Восстановим переменную Other
    je Ravno ;Перейдем, если равен

    Следует отметить, что операторы mov и pop флаги (в частности, флаг нуля) не меняют!

    Хорошо получилось! Или не очень? Вероятно, есть другие способы? Безусловно есть! Ассемблер такой гибкий язык, что может делать невероятные, нет - поистине невероятное вещи!

    Чтобы временно не сохранять регистр или переменную перед проверкой одного-двух-трех... битов, используется оператор TEST:

    Название Перевод Применение Процессор
    TEST приемник, источник Test - тест, проверка Проверка одного и более битов 8086

    Примеры:

    mov ax,10100001b
    test ax,1 ;Проверим на то, равен ли нулевой бит единице.
    jnz Ravno ;Переход, если равен

    Обратите внимание, что после CMP мы ставим JE (JZ), если хотим перейти на определенную метку в случае, если приемник и источник равны. В команде TEST все идет "шиворот-на-выворот". Т.е. JE (JZ) перейдут на метку, если приемник и источник НЕ равны и наоборот: JNE (JNZ) перейдут на метку, если приемник и источник равны. Не надо путать!

    Еще пример:

    mov cl,100101b
    test cl,1000b ;Проверим на то, равен ли третий бит идинице
    jz Ne_ravno ;Переход, если НЕ равен

    В принципе, пока достаточного про TEST. TESTировать будем позже, а пока поехали дальше...

    Мы остановились на том, что переменная Other будет содержать более одного параметра. Причем эти параметры должны отвечать на вопрос ДА или НЕТ, т.е. РАВНО или НЕ РАВНО. Как, например, в нашей процедуре Draw_frame. Повторю: первый бит отвечает за рисование линии вверху окошка, а нулевой - за копирование участка экрана перед выводом окошка. Вспомните окно подтверждения выхода из оболочки. Экран-то прежде копируется в память. А вдруг пользователь передумает выходить? Нам что тогда, заново рисовать основное окно и перечитывать каталоги? Или проще сохранить часть затираемого экрана, а затем моментально восстановить его? Да что я говорю?! Прошли мы уже это...

    Использование битов переменной для подобных целей подходит как никогда лучше. Мы экономим байты. Вместо, скажем, восьми или 16 переменных мы используем всего одну! Красота...

    Вот кусок из нашего файла-приложения (этим мы подведем черту с TESTом):

    mov ax,Other ;Получим дополнительную информацию
    test al,1 ;Нулевой бит равен 0?
    jz No_copyscr ;Если так, то копировать экран не нужно.

    ___________

    Основы работы с памятью в DOS.

    Сразу отмечу, что пока мы рассмотрим основную память, т.е. 640 Кб.

    Поробно рассматривать управление памятью в DOS мы сегодня не будем. Затронем лишь ключевые, основополагающие моменты.

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

    Зачем это нужно?

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

    Совершенно верно! Для того, чтобы урезать память, используется функция 4Ah прерывания 21h:

    Вход: AH=4Ah
    ES=сегмент распределенного блока
    BX=размер блока в 16-и байтовых параграфах
    Выход: JC - ошибка, при этом:
    AX-код ошибки

    Распределенный блок в нашем случае - вся память, отведенная программе, начиная от 0 сегмента CS и заканчивая последним свободным байтом. Поэтому перед вызовом функции 4Ah следует убедиться в том, что ES указывает на сегмент, куда мы загрузились!

    Вот какая ситуация после загрузки нашей программы в память не будем брать адреса; какая разница?):

    1. Системные файлы; --- память занята от 0 до текущего байта

    2. Резидентные программы; --- память занята от 0 до текущего байта

    3. Наша программа; --- память занята от 0 до текущего байта

    4. Метка Finish; --- память занята от 0 до текущего байта

    5. Отведенная память нашей программе. --- память занята от 0 до конца.

    Получается, что ВСЯ память (640 Кб) занята после того, как наша программа загрузилась. Наша задача - урезать занятую память до метки Finish (см. п. 3). Для чего это нужно - рассмотрим позже.

    Обратите внимание, как мы ужимаем существующий блок памяти (MAIN.ASM, Prepare_memory):

    mov bx,offset Finish ;BX=последний байт нашей программы
    shr bx,4 ;Т.к. BX должен содержать не количество байт, а количество блоков по 16 байт, то мы должны сдвинуть биты вправо на 4
    inc bx ;Увеличим BX на один (на всякий случай!)
    mov ah,4Ah ;Функция урезания/расширения существующего блока памяти
    int 21h ;В данном случае урезаем, т.к. наша программа, естественно, меньше отведенного блока памяти после загрузки.

    Теперь картина такая:

    1. Системные файлы; --- память занята от 0 до текущего байта

    2. Резидентные программы; --- память занята от 0 до текущего байта

    3. Наша программа; --- память занята от 0 до текущего байта

    4. Метка Finish; --- память занята от 0 до текущего байта

    5. Память за меткой Finish. --- память свободна до конца 640 Килобайта, начиная с первого байта, следующего за меткой Finish!

    Размер памяти примерно такой: 640Кб минус смещение метки Finish.

    Теперь отведем кусок памяти размером 1000h 16-и байтовых блоков (параграфов) или 65536 байт:

    mov ah,48h
    mov bx,1000h
    int 21h

    mov Seg_files,ax

    Функция 48h прерывания 21h - выделить блок памяти:

    Вход: AH=48h
    BX=размер блока в 16-и байтовых параграфах
    Выход: JC - ошибка, при этом:
    AX-код ошибки;
    Иначе: AX=сегмент выделенного блока.

    Думаю, что объяснять приведенный перед таблицей пример не нужно. Все и так понятно. Рассмотрим только, что получилось:

    1. Системные файлы; --- память занята от 0 до текущего байта

    2. Резидентные программы; --- память занята от 0 до текущего байта

    3. Наша программа; --- память занята от 0 до текущего байта

    4. Метка Finish; --- память занята от 0 до текущего байта

    5. Память за меткой Finish + 65536 байт; --- память занята

    6. Память, начиная с адреса Finish + 65537 байт --- свободна

    Зачем мы выделили блок памяти размером 64Кб?

    В эту память мы будем загружать информацию о найденных файлах в текущем каталоге. А как вы думаете, NC показывает вам файлы в окошечке? Элементарно! Просто считывает к себе в память файлы, а затем с ними работает (точнее, вы работаете). Команда DIR, например, не загружает в память файлы. А зачем? Она нашла файл, вывела информацию на экран и - следующий... Вот так вот!

    Подписчик (задумчиво): Я тут сейчас вот как бы нечайно подумал... Мне кажется, это так сложно все... Нет, наверное, это не для меня... Пусть другие пишут на Ассемблере, а я лучше на Бейсике... Сдался мне Асм... Калашников этот вечно лишние проблемы накручивает... Спал раньше так хорошо по ночам...

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

    Как записываем в память найденные файлы?

    Алгоритм простейший:

    1. Ищем первый файл. Нет файлов - см. п. 5;

    2. Заносим имя файла в отведенный блок памяти. Дописываем после имени файла нуль;

    3. Ищем следующий файл. Нет больше файлов - см. п. 5;

    4. Заносим следующий файл в память сразу же за найденным предыдущим. На пункт 3;

    5. Заносим еще один нуль после последнего найденного файла для того, чтобы дать понять процедурам нашей оболочки, что это был последний найденный файл.

    6. Выводим указанное количество файлов на экран (сколько находится в переменной Number_files) (FILES.ASM, Out_files).

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

    Удачного вам изучения!

    До скорой встречи!


    С уважением,

    Автор рассылки: Калашников Олег
    URL сайта подписчиков:
    http://www.Kalashnikoff.ru
    E-mail автора:
    Assembler@Kalashnikoff.ru
    ICQ: 68951340

    Москва, 2001.


    (C) Авторское право принадлежит автору рассылки. Использование материала из рассылки в коммерческих и иных подобных целях, а также публичное публикование без письменного согласия автора влечет ответственность за нарушение авторских прав.


    http://subscribe.ru/
    E-mail: ask@subscribe.ru
    Поиск

    В избранное