Ассемблер?
Это просто! Учимся
программировать Выпуск N 026 (Оболочка) |
Доброе время суток, дорогие подписчики!
Сегодня в номере:
!!! Сюрприз !!!
Информация для новых подписчиков |
Благодарю Вас, что подписались на рассылку "Ассемблер? Это просто! Учимся программировать". Надеюсь, что Вы не останетесь равнодушны к ней и почерпнете море полезной информации, а также повысите свой уровень в "общении" с IBM-совместимыми компьютерами.
Прежде, чем приступать к изучению материала в данном выпуске, Вам необходимо внимательно ознакомиться с предыдущими. Я уверен, что Вы очень быстро и без труда догоните остальных подписчиков, не смотря на то, что у нас уже 26 выпуск.
Все, что нужно для изучения Ассемблера (предыдущие выпуски, адреса экспертов, необходимые программы, документацию, а также многое другое), можно найти на сайте http://www.Kalashnikoff.ru. Рекомендую Вам сперва ознакомиться с разделом "Информация для новых подписчиков".
Если у Вас нет выхода в Сеть, то предыдущие выпуски рассылки, информацию для новеньких и адреса экспертов можно получить по почте, направив пустое письмо по адресу AssmIssues@Kalashnikoff.ru. Информация (350 Кб) будет выслана Вам в течение двух рабочих дней с момента получения Вашего письма. Однако, пожалуйста, не злоупотребляйте этим, т. к. высылка писем подобного объема несет существенную нагрузку на почтовые сервера.
В предыдущих выпусках рассылки я писал про язык С и, видимо, допустил ошибку. Заострю на этом внимание, т.к. мне кажется, что многим подписчикам данная информация будет полезна (учитывая то, что вскоре приступим к Windows + С). Ко мне пришло письмо от Алексея следующего содержания (привожу выдержки):
Здравствуйте,
уважаемый Олег!
Вы действительно ошиблись по
поводу языка C. Файл stdio.h (и другие *.h)
не содержит самих функций, они
находятся в различных (в
зависимости от модели памяти)
библиотечных файлах. А файлы *.h (они
называются заголовочными) содержат
прототипы (заголовки) функций и
представляют собой обычные
текстовые файлы.
Прототип
показывает компилятору, какого
типа, в каком порядке и каким
образом (через стек или регистры)
функции передаются аргументы, а так
же какого типа функция возвращает
значения. Можно в библиотеку
включить свои функции, написанные
на C или ассемблере, и пользоваться
этими функциями как стандартными,
создав свой заголовочный файл.
Практически каждый стандартный
заголовочный файл содержит
несколько десятков прототипов, но в
код программы включаются ТОЛЬКО
ИСПОЛЬЗУЕМЫЕ В ДАННОЙ ПРОГРАММЕ
ФУНКЦИИ.
Причины большего
объёма программы, написанной на C в
другом.
Во-первых, в каждую C-программу
включается так называемый
загрузчик C (находящийся в файлах
c0?.obj, различных в зависимости от
модели памяти). С него начинается
работа программы, затем вызывается
функция main С-программы, завершает
программу опять же загрузчик C. А в
нём содержатся обработчики
некоторых прерываний, переменные,
определение версии операционной
системы и много ещё чего (в комплект
поставки C/C++ входит файл c0.asm, так
что его можно посмотреть).
Во-вторых, ... Впрочем, я начинаю
увлекаться. Ведь это не рассылка по
C/C++, а я не автор. Хочется только
добавить, что С-компилятор
генерирует довольно эффективный
код, в этом можно убедиться, задав
при компиляции ключ -S и посмотрев
листинг на ассемблере.
____________
Некотрые уточнения по поводу 386/486 SX/DX машин. В принципе, пришло несколько подобных писем (от: Serge I.Driantsov, Дмитрий Сердюк). Однако, письмо Максима Белова более-менее точно описывало ситуацию с SX/DX машинами:
...С процессорами ситуация несколько иная была.
1. 486 начались с 16 или с 20 или с 25 МГц (у меня на рабочем ящике стоял такой уродец - 486SX-25).
2. 486 DX-33 (домашний первый ящик) - сопроцессор был уже там.
3. 386 серия - совершенно отдельная песня. Если в 486 сопроцессор был встроен и отключен (процент выхода годных чипов), то в 386 индекс DX/SX говорит о ширине внешней шины данных процессора - 32/16 бит. (как 8086/8088 - 16 разрядный внутри, а вот снаружи 16/8).
4. Что-то я еще слышал про 486SX/387DX связку, но плохо себе это представляю, как это возможно.
5. Говоря о выпайке, может быть, имелось в виду выпаивание распаянного на материнской плате процессора?
___________
Мой комментарий.
1. Читайте следующий раздел: "История развития IBM-совместимых компьютеров".
3. Полностью согласен, что индекс SX в 386 машинах свидетельствовал о разрядности шины.
4. Дело в том, что 487 сопроцессор ничем не отличается от 387. Поэтому структура и принцип работы, а также команды 387 сопроцессора аналогичны 487. Иначе говоря, в "четверках" стоял обычный "трешный" сопроцессор, только располагался он на одном кристалле с основным процессором.
5. Лично я купил в свое время 386DX-40, рассчитывая, что в нем присутствует сопроцессор (теперь понятно, что я ошибался). При вскрытии системного блока, оказалось, что сопроцессор действительно присутствовал когда-то, но его выпаяли. Это было явно видно на разъеме...
____________
Granit прислал алгоритм вывода десятичных чисел на экран. Спасибо!
Но! Дело в том, что максимальное число, которое может вывести данная процедура, гораздо меньше, чем то, которое выводим мы в нашем примере. Тем не менее, я опубликовываю данный алгоритм (без проверки с моей стороны):
DEC.ASM
ВНИМАНИЕ! Это - типичный формат *.exe-файла. Ассемблировать его нужно следующим образом:
ML.EXE DEC.ASM
Или:
TASM DEC.ASM
TLINK DEC.OBJ
И все! Никаких параметров! В результате должен получиться DEC.EXE. Судя по структуре файла, видно, что Granit использует TASM...
___________
Добрый день или другое какое время суток!
Я решил узнать, что же такое Ассемблер и подписался на рассылку, не забыв и заказать предыдущие выпуски. Но вот одно немного смущает еще до начала всех проб и ошибок. Как-то кто-то говорил мне, что для программирования на Ассемблере надо знать архитектуру именного того процессора, для которого пишется код на Ассемблере: Pentium ли это, Pentium Pro, Pentium-II или Pentium-III. А у меня дома машина на AMD-K6 бегает. Действительно ли этот процессор имеет свою систему команд, и правда ли то, что книги или рассылки по программированию на Ассеблере для Пентиума или 486 ничем не помогут мне, так как я хочу работать на AMD-K6? Спасибо заранее за разъяснения.
С уважением, Michael.
___________
Мой комментарий.
Уважаемый Михаил!
Дело в том, что в 1981 году появились первые компьютеры на базе процессора Intel. Назывались они IBM PC. Со временем появились IBM PC/XT, IBM PC/Jr, IBM PC/AT, IBM PS/2 и т.д. Главное не это. Главное то, что программа, написанная для процессора Intel 8086 должна работать и на Pentium-III, т.к. Pentium - это процессор, совместимый с 8086. Иначе говоря, совместимость программ идет снизу вверх. Например, многие любят старые XT-шные игры: Pirates, Civilization, King's Bounty, Arcanoid и пр. Естественно, они были написаны для 8086 процессора, но работают также на 386-Pentium. AMD - это IBM-совместимый компьютер. Это означает, что программы, написанные для IBM PC/XT, будут работать на Pentium, на AMD и на других IBM-совместимых компьютерах. Отсюда правило - если Вы пишите программу, используя инструкции 8086 процессора, то я даю гарантию (точнее не я, а фирма-производитель процессоров), что они будут корректно работать на последующих процессорах (80286, 80386, AMD, Compaq и пр.).
___________
Хочу выразить благодарность Сергею Юрьевичу за проделанную работу по переводу *.txt-файлов в формат DOC. Спасибо!
Если я не ошибаюсь, то ситуация такая:
Процессор | Тип (SX/DX) | ОЗУ | Винчестер (Мб) | Мегагерцы (Mhz) | Монитор | Отечественный вариант |
8086/8088 | --- | 256-640 Кб | 10-20 | 4,77 - 8 | Mono, CGA | ЕС-1840, 1841, 1851 и пр. |
80286 | --- | до 4 Мб | 20-60 | 6 - 16 | CGA - VGA | EC-1849 |
80386 | SX/DX | 4-8 Мб | 40-120 | 16-40 | EGA - VGA | EC-1863 |
80486 | SX/DX | 4-12 Мб | 80-370 | 25-120 | EGA - VGA | Не помню |
Pentium | --- | 16 Мб | 300-800 | 60 | VGA - sVGA | --- |
Некоторые комментарии. Приведенную в таблице информацию не следует считать обязательной для того или иного компьютера. Например, при желании можно было укомплектовать такую машину: IBM 486 SX-25, 10Мб - винчестер, 32Мб - ОЗУ, MDA - монитор...
Что же касается отечественных вариантов, то могу сказать, что лучшим конструкторским решением (не беру во внимание форму системного блока и шум вентилятора) можно считать ЕC-1849 (12Mhz, 640 Кб основной + 384 КБ расширенной (XMS) памяти, 40Мб винчестер, EGA - изначальная конфигурация завода МЗВТ). Самыми неудачными оказались: ЕС-1840 (не имел возможности подключать винчестер вообще, содержал ошибки в ПЗУ, а также (как и в ЕС-1841 - 1843) два здоровых ящика (системный блок), которые нужно было включать (дисководы и сам компьютер)), ЕС-1863 ("мутант" 386SX - 2 Мб памяти, EGA-монитор, 16 Mhz, высокая цена).
Чем же отличались эти компьютеры друг от друга? Я считаю, что каждый ассемблерщик должен знать историю развития ПК. Ну, хотя бы вкратце. Иначе можете попасть впросак...
С чего все начиналось (речь идет о IBM'ках!).
В 1981 году на свет появляется первый персональный компьютер IBM PC. Затем, как уже писалось, XT, AT и т.д.
286 процессор мало чем отличался от своих старших "братьев". Имел несколько новых команд (например, PUSH число), а также позволял переводить компьютер в т.н. "защищенный режим" (protected mode). Сомневаюсь, что многие программы им пользовались, т.к. этот режим сильно отличался от "трешного". Немного увеличилась скорость работы, да памяти чуть-чуть нарастили. Вот, собственно, и все.
"Тройки" (т.е. 386 процессоры) существенно отличались от всех предшествующих поколений компьютеров. Прежде всего - полноценный защищенный режим, много дополнительных команд для работы с ним, возможность управлять до 4 Гб ОЗУ и многое другое. По сути дела, современный Пентиум - это не что иное, как обычная "тройка", только работающая в несколько раз быстрее, да имеющая несколько дополнительных операторов (MMX, SSE).
"Четверки" далеко не ушли от 386. Единственное, что их отличало от "трешек", так это расположение сопроцессора на одном кристалле с основным процессором. Существенно увеличилась скорость работы, добавилось несколько новых команд и др. по мелочам. Все остальное было также, как у "тройки".
Ну, а "Пентиум" - он, как говорится, и в Африке "Пентиум"...
Вот это вкратце. Надеюсь, о компьютерах мы еще поговорим подробней позже...
Sshell26.asm
(головной файл) |
|
Display.asm |
Files.asm |
Keyboard.asm |
Main.asm |
|
Data.asm |
ВНИМАНИЕ! Прилагаемый алгоритм перехода по файлам при нажатии на "стрелку вниз" и "стрелку вверх" очень сложный и не доделанный (т.е. содержит море ошибок)! Читайте ниже...
_____________
Что нового у нас? Теперь оболочка сразу после загрузки переходит в корневой каталог текущего диска, читает файлы, выводит их длинные имена на экран, размеры, текущий каталог вверху, а также...
...А также теперь мы можем самостоятельно менять каталоги, т.е. лазить по диску! И еще перечитывать его (Ctrl+F3)!
Обратите внимание, что теперь "бегает" (как это?) "курсорчик" (что ли?). В общем, почти как в "настоящем "Нортоне"! Только это все далеко не доделано (например, программа пытается перейти в каталог, которые на самом деле является файлом! Или не делает прокрутку на экране. Если файлов много, и они не вмещаются на экран, то курсор просто исчезает из поля видения, когда мы переходим нижнюю границу. Проще всего самим посмотреть, что делает оболочка и прямо сейчас). Почему мы не доделали ее?
Дело в том, что все не так просто, как кажется. Я вообще, когда увидел "Нортон" первый раз, то подумал, что курсорчик должен бегать по файлам обязательно. Т.е. это как бы не забота программы, а так, само собой. Потом, со временем, я понял, что все, что происходит на экране, должен делать программист. Даже этот злосчастный курсорчик...
Интересно, как вообще можно сделать выбор файла (т.е. найти отмеченный или текущий файл в памяти, куда мы прочитали каталог)? Насколько это сложно - судить вам...
Рассмотрим алгоритм считывания файлов в память и перемещение по ним "стрелками".
Чтение файлов из каталога и размещение их в отведенной памяти.
Есть несколько способов размещения файлов в отведенной памяти программы.
1. Самый примитивный и простой. Предположим, что работаем мы ТОЛЬКО с короткими именами файлов (как в предыдущих версиях DOS, когда никто и "слыхом не слыхивал" об имени файла длиной более 200 символов). Раньше все файлы имели длину не больше чем 12 байт (8 символов имя файла + "точка" + 3 символа расширение). Тогда отводим 13 байт памяти для каждого файла. Почему 13? Первый байт будет сигнализировать о статусе файла (т.е. либо отмеченный, либо текущий (на который будет указывать курсорчик), либо текущий + отмеченный). Статус файла будем получать при проведении некоторых операций с файлами (копирование, удаление, запуск и пр.). Т.о. в 64Кб отведенной памяти можно поместить более 5.000 файлов!
Чем хорош данный способ?
По файлам просто "бегать" и искать отмеченный или текущий. Просто перемещаем указатель на 13 и... получаем смещение следующего файл. Вы улавливаете мысль? Если нет, то попробуйте "проработать" наш файл-приложение под отладчиком. Будет о-о-очень сложно, но нужно!
2. Второй способ гораздо сложнее, зато экономит память. Файлы с длинными именами могут содержать чуть более 255 символов. Теперь посчитаем, сколько файлов мы сможем поместить в 64Кб: 65536/255=256. Но некоторые каталоги содержат 400 и более файлов... Тогда нужно отводить еще один, два, три сегмента или использовать расширенную память (но этим будем заниматься позже), что усложнит задачу.
Как мы поступаем в оболочке?
Допустим, в некотором каталоге существуют следующие файлы/каталоги:
1. assm.txtТеперь внимательно следите за тем, как размещаем их в памяти. Для этого нужно будет вооружиться листком и ручкой (что я и делал при составлении данной таблицы). Допустим, мы размещаем файлы в сегменте 1234h, начиная со смещения 0000h (обратите внимание, что в оболочке файлы размещаются со смещения 500!):
Адрес | Статус файла (один байт) | Адрес следующего файла (два байта) | Адрес предыдущего файла (два байта) | Имя файла + ASCII 0 |
1234:0000h | 0000h | 0001h | 0003h | 0005h (assm.txt (8 + ASCCI 0 = 9 байт) |
1234:000Dh | 000Dh | 000Eh | 0010h | 0012h (Мои документы = 13 + ASCII 0 = 14 байт) |
1234:001Fh | 001Fh | 0020h | 0022h | 0024h (Супер новый файл!.asm = 21 + ASCII 0 = 22 байта) |
Примечание. ВНИМАТЕЛЬНО изучите таблицу. Посмотрите, насколько поля, приведенные в данной таблице отличаются от нашей оболочки.
Теперь два слова.
Перед первым файлом мы заносим в поле "Адрес предыдущего файла" 0000h. Когда пользователь нажмет "стрелку вверх" на верхнем файле, то наша программа, прочитав смещение предыдущего файла, "поймет", что "выше" уже файлов нет и ничего не сделает.
Перед последним файлом занесем в поле "Адрес следующего файла" также 0000h. Когда пользователь нажмет "стрелку вниз", то наша программа "поймет", что "ниже" уже файлов нет и ничего не произойдет.
Если вы до сих пор не поняли, о чем идет речь, то нужно посидеть еще над файлом-приложением и поковыряться в нем до утра. Уверяю вас: то, что делает наша оболочка, когда заносит файлы в буфер, - почти "ювелирная" работа. Занесенный по ошибке один байт ("плюс-минус") разрушит всю базу данных по файлам. Надеюсь, что принцип будет понятен, когда вы проведете несколько часов перед монитором...
"Зачем мне нужно сидеть перед монитором и ковыряться"?
Отвечу вопросом на вопрос: "Вы хотите научиться "разбирать по полочкам" чужие программы?" Поверьте, простая программа, написанная на Паскале, гораздо сложнее "понимается" под отладчиком, чем аналогичная на Ассемблере. Сегодня-завтра вы захотите разобрать чужую программу (ну, или уже захотели!), да мало что получится, если вы не разберете наш файл-приложение. Опыт приходит со временем, и знания увеличиваются пропорционально часам, проведенным за отладчиком! Помните это!
На сегодня все!
Уважаемые подписчики!
Я благодарен всем вам за то, что читаете рассылку, что присылаете вопросы, программы, стараетесь всеми силами помочь мне, поддерживаете морально. Поверьте: я внимательно знакомлюсь со всеми письмами, приходящими ко мне на ящик. А писем, уверяю вас, немало... Если есть возможность - отвечаю. Кто все-таки не получил ответ - извините... Времени у меня не так и много, вы знаете...
В общем, отвлекаюсь я. Дело в том, что я приготовил вам небольшой сюрприз, ма-а-аленький подарок... К сожалению, не все вы сможете им воспользоваться (если можно так сказать), но все же... Итак, дорогие мои, жду вас всех прямо сейчас здесь. Очень надеюсь, что... В общем, обсудим позже...
С уважением,
Калашников Олег: Assembler@Kalashnikoff.ru
ICQ No.: 68951340
URL сайта подписчиков: http://www.Kalashnikoff.ru
______________
По вопросам сотрудничества, рекламы и спонсорства обращайтесь:
(C) Москва, 2001. Авторское право принадлежит Калашникову О.А. Публичное размещение материала из рассылки, а также его использование полностью или частично в коммерческих или иных подобных целях без письменного согласия автора влечет ответственность за нарушение авторских прав. |