Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Финогенов-основы_языка_ассемблера.doc
Скачиваний:
25
Добавлен:
17.09.2019
Размер:
3.35 Mб
Скачать

УДК 681.3.068 ББК 32.973

Автор: К-Г.Финогенов Ф59 Основы языка Ассемблера. — М.: Радио и связь, 1999. — 28S с.: ил.

ISBN 5-256-01451-Х.

Книга представляет собой учебное пособие по языку ассемблера персональ­ных компьютеров типа IBM PC. Описаны особенности архитектуры микропро­цессоров Intel и всего компьютера в целом, правила составления программ, основные конструкции языка и приемы программирования, принципы про­граммирования подключаемой к компьютеру аппаратуры. Рассмотрены возмож­ности использования в 16-разрядных приложениях реатьного режима средств современных 32-разрядных процессоров. Дано сжатое описание принципов за­щищенного режима с примером программирования. В приложении дан перечень Команд процессора Pentium с примерами и пояснениями.

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

ББК 32.973 ISBN 681.3.068

О Финогенов К.Г., 1999

Инженерно-техническое издание

Кирилл Григорьевич ФИНОГЕНОВ

ОСНОВЫ ЯЗЫКА АССЕМБЛЕРА

Оформление серии и обложка В.Г.Ситникова. Макет подготовлен ООО ИОЦ «Силуэт»

ИБ № 2876 ЛР № 061888 от 19.12.97

Сдано в набор 19.02.99 г. Подписано в печать 22.03.99 г.

Формат 60x881/i6 Бумага газетная Гарнитура Тайме

Печать офсетная Печ. л. 18,0 Уч.-изд. л. 15,0

Тираж 5000 экзЛзд. Hs 111 Заказ 1371

Отпечатано в Производственно-издательском комбинате ВИНИТИ,

140010, Г. Люберцы, Московской обл., Октябрьский пр-т, 403.

Тел. 554-21-86

Предисловие

Книга рассчитана на пользователей персональных компьютеров типа IBM PC, которые хотели бы поближе познакомиться с архитектурными особенностями семейства микропроцессоров корпорации Intel и научиться понимать и составлять программы на языке ассемблера для этих процес­соров.

Если существующие сегодня языки программирования (а их насчиты­вается не один десяток) условно разбить на две категории, то в одну из которых попадет язык ассемблера, а в другую — все остальные. В то время, как языки высокого уровня ориентируются на решение тех или иных при­кладных задач (математических, экономических и др.) и содержат в себе средства алгоритмического описания этих задач, язык ассемблера являет­ся отражением архитектуры процессора, т.е. его логического устройства, режимов и алгоритмов функционирования. Операторы языка ассемблера представляют собой фактически команды микропроцессора, только вы­раженные не в виде машинных кодов, а с помощью более или менее наглядных мнемонических обозначений. Эта особенность языка ассембле­ра определяет его возможности и сферы использования.

Как известно, программы, написанные на языке ассемблера (если, конечно, они написаны грамотно), отличаются высокой эффективнос­тью, т.е. минимальным объемом и максимальным быстродействием. Это обстоятельство обусловило широкое использование языка ассемблера в тех случаях, когда скорость работы программы или расходуемая ею память имеют решающее значение. Некоторые классы программ (например, про­граммы драйверов устройств, отличающиеся жесткой структурой) требу­ют для своего составления обязательного использования языка ассембле­ра. Язык ассемблера также удобен для написания программ управления нестандартной аппаратурой, подключаемой к компьютеру с целью пост­роения автоматизированных систем управления научными измерениями или технологическими процессами, тем более, что от таких программ часто требуется еще и максимальное быстродействие. В то же время для разработки программ математического или логического характера — по моделированию, обработке числовой или символьной информации, об­служиванию баз данных и др. лучше подходят языки высокого уровня.

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

Предисловие

Предисловие

При отладке программ, написанных на языках высокого уровня типа С или C++, приходится пользоваться встроенным в систему программи­рования интерактивным отладчиком, всегда содержащим в себе деассем-блер. В простых случаях удается отладить программу, наблюдая ход выпол­нения операторов языка высокого уровня; более тонкие ошибки обнару­живаются только на уровне машинных кодов путем анализа содержимого регистров процессора и конкретных ячеек памяти. Такой метод ценен еще и тем, что позволяет войти внутрь вызываемых из прикладной программы системных средств (функций DOS или Windows) и проаншжзировать вза­имодействие отлаживаемой программы с внутренними функциями опе­рационной системы.

Кроме потребительских качеств, язык ассемблера имеет еще значи­тельную методическую ценность. Отражая архитектурные особенности используемого в компьютере микропроцессора, а также средства взаимо­действия микропроцессора с аппаратурой компьютера и подключенными к компьютеру устройствами, язык ассемблера предоставляет уникальную возможность изучения процессора и компьютера в целом, освоения того, что и как умеет делать аппаратура компьютера и каковы ее возможности и ограничения. Знакомство с внутренними возможностями компьютера чрез­вычайно полезно, в частности, для программиста, работающего на язы­ках Паскаль или Си, так как позволяет увидеть за формализмом языка высокого уровня те реальные процессы, которые будут протекать в систе­ме при выполнении прикладной программы и, следовательно, более осоз­нанно подойти к разработке структуры программы и ее конкретных алго­ритмов.

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

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

В разделе, посвященном архитектуре реального режима, рассматрива­ются наиболее принципиальные элементы архитектуры процессора и ком­пьютера в целом: понятие сегментной адресации, способы адресации, предоставляемые микропроцессором, система программных и аппарат­ных прерываний, распределение адресного пространства и система вво­да-вывода.

Раздел основ программирования посвящен методике подготовки и от­ладки программ на языке ассемблера, типам данных и средствам их описа­ния, взаимодействию программ с операционной системой, а также исполь­зованию различных способов передачи управления внутри программы.

В следующем разделе описываются типы приложений DOS (програм­мы .ЕХЕ и .СОМ, резидентные программы, обработчики прерываний) и правила их составления, даются многочисленные примеры использова­ния наиболее важных команд, конструкций и алгоритмов языка. Отдель­ный параграф посвящен принципам программного управления аппарату­рой, подключаемой к компьютеру.

Последний раздел книги посвящен расширенным возможностям со­временных 32-разрядных микропроцессоров типа Pentium и др. Здесь рас­сматриваются архитектурные особенности этих процессоров, возможнос­ти использования 32-разрядных операндов в прикладных программах, ос­новные принципы и команды защищенного режима.

В приложении дается описание всех команд микропроцессоров 8086...Pentium с примерами и пояснениями.

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

К. Г.Финогенов

Введение

Введение

Микропроцессоры корпорации Intel и персональные компьютеры на их базе прошли не очень длинный во времени, но значительный по суще­ству путь развития, на протяжении которого кардинально изменялись их возможности и даже сами принципы их архитектуры. В то же время, внося в микропроцессор принципиальные изменения, разработчики были вы­нуждены постоянно иметь в виду необходимость обеспечения совмести­мости новых моделей со старыми, чтобы не отпугивать потенциального покупателя перспективой полной замены освоенного или разработанно­го им программного обеспечения. В результате современные микропро­цессоры типа Pentium, обеспечивая такие возможности, как 32-битную адресацию почти неограниченных объемов памяти, многозадачный ре­жим с одновременным выполнением нескольких программ, аппаратные средства защиты операционной системы и прикладных программ друг от друга, богатый набор дополнительных эффективных команд и способов адресации, в то же время могут работать (и часто работают) в режиме первых микропроцессоров типа 8086, используя всего лишь 1 мегабайт оперативной памяти, 16-разрядные операнды (т. е. числа в диапазоне до 216-1=65535) и ограниченный состав команд. Поскольку программирова­ние на языке ассемблера напрямую затрагивает аппаратные возможности микропроцессора, прежде всего следует выяснить, в какой степени про­граммист может использовать новые возможности микропроцессоров в своих программах и какие проблемы программной несовместимости мо­гут при этом возникнуть.

Первые персональные компьютеры корпорации IBM, появившиеся в 1981 г. и получившие название IBM PC, использовали в качестве цент­рального вычислительного узла 16-разрядный микропроцессор с 8-раз­рядной внешней шиной Intel 8088. В дальнейшем в персональных компью­терах стал использоваться и другой вариант микропроцессора, 8086, ко­торый отличался от 8088 тем, что являлся полностью 16-разрядным. С тех пор его имя стало нарицательным, и в программах, использующих только возможности процессоров 8088 или 8086, говорят, что они работают в режиме 86-го процессора.

В 1983 г. корпорацией Intel был предложен микропроцессор 80286, в котором был реализован принципиально новый режим работы, получив­ший название защищенного. Однако процессор 80286 мог работать и в режиме 86-го процессора, который стали называть реальным.

В дальнейшем на смену процессору 80286 пришли модели 80386, i486 и, наконец, различные варианты процессора Pentium. Все они могут ра­ботать и в реальном, и в защищенном режимах. Хотя каждая следующая

Введение \ 7

модель была значительно совершеннее предыдущей (в частности, почти на два порядка возросла скорость работы процессора, начиная с модели 80386 процессор стал 32-разрядным, а в процессорах Pentium реализован даже 64-разрядный обмен данными с системной шиной), однако с точки зрения программиста все эти процессоры весьма схожи. Основным их ка­чеством является наличие двух режимов работы — реального и защищен­ного. Строго говоря, в современных процессорах реализован еще и третий режим — виртуального 86-го процессора, или V86, однако в плане ис­пользования языка ассемблера этот режим не отличается от обычного режима 86-го процессора, и в этой книге мы его касаться не будем.

Реальный и защищенный режимы прежде всего принципиально раз­личаются способом обращения к оперативной памяти компьютера. Метод адресации памяти, используемый в реальном режиме, позволяет адресо­вать память лишь в пределах 1 Мбайт; в защищенном режиме использует­ся другой механизм (из-за чего, в частности, эти режимы и оказались полностью несовместимыми), позволяющий обращаться к памяти объе­мом до 4 Гбайт. Другое важное отличие защищенного режима заключается в аппаратной поддержке многозадачности с аппаратной же (т.е. реализо­ванной в самом микропроцессоре) защитой задач друг от друга.

Реальный и защищенный режимы имеют прямое отношение к работе операционной системы, установленной на компьютере.

В настоящее время на персональных компьютерах типа IBM PC ис­пользуются в основном два класса операционных систем (оба — разработ­ки корпорации Microsoft): однозадачная текстовая система MS-DOS и многозадачная графическая система Windows. Операционная система MS-DOS является системой реального режима; другими словами, она исполь­зует только средства процессора 8086, даже если она установлена на ком­пьютере с процессором Pentium. Система Windows — это система защи­щенного режима; она значительно более полно использует возможности современных процессоров, в частности, многозадачность и расширенное адресное пространство. Разумеется, система Windows не могла бы рабо­тать с процессором 8086, так как в нем не был реализован защищенный режим.

Соответственно двум типам операционных систем, и все программ­ное обеспечение персональных компьютеров подразделяется на два клас­са: программы, предназначенные для работы под управлением MS-DOS (их часто называют приложениями DOS) и программы, предназначен­ные для системы Windows (приложения Windows). Естественно, приложе­ния DOS могут работать только в реальном режиме, а приложения Windows — только в защищенном.

Таким образом, выражения «программирование в системе MS-DOS», «программирование в реальном режиме» и «программирование 86-го про-цесвора» фактически являются синонимами. При этом следует подчерк­нуть, что хотя процессор 8086, как микросхема, уже давно не использует­ся, его архитектура и система команд целиком вошли в современные про­цессоры. Лишь относительно небольшое число команд современных

8

Введение

процессоров специально предназначены для организации защищенного режима и распознаются процессором, только когда он работает в защи­щенном режиме. Поэтому изучение языка ассемблера целесообразно на­чинать с изучения архитектуры процессора 8086 или, точнее, того гипо­тетического процессора, который как бы объединяет часть архитектурных средств современных процессоров, предназначенных для использования в реальном режиме, и соответствующих архитектуре процессора 8086. Мы будем называть этот гипотетический процессор МП 86. В настоящей книге изучению архитектуры и программирования МП 86 посвящены первые три главы.

Деление программ на приложения DOS и приложения Windows не исчерпывают вопроса о возможньгх типах программ. Дело в том, что ряд дополнительных средств, имеющихся в современных процессорах, впол­не можно использовать и в реальном режиме (хотя сама операционная система MS-DOS, разработанная еще в эпоху процессора 8088, ими не пользуется). К этим средствам относится расширенный состав команд процессоров и, главное, их 32-разрядная архитектура.

Современные процессоры (начиная с 80386), в отличие от своего пред­шественника 8086, являются 32-разрядными. Это дает возможность про­граммисту использовать в программе 32-разядные операнды (т. е. числа в диапазоне до 23:-1=4 294 967 295), что во многих случаях позволяет упрос­тить алгоритм программы и повысить ее быстродействие. Программа, пред­полагающая работать с 32-разрядными операндами, должна иметь в своем составе одну из директив .386, .486 или .586, которые разрешают трансля­тору использовать дополнительные средства соответствующего процессора. Включение в программу этой директивы одновременно открывает доступ и к дополнительным командам и способам обращения к памяти, отсутству­ющим в процессоре 8086, что также расширяет возможности программи­рования. В настоящей книге эти средства описаны в главе, посвященном расширенным возможностям современных процессоров.

Особая ситуация возникает, если программист хочет использовать не только 32-битовые данные, но и 32-разрядные адреса ячеек памяти. Про­граммы такого рода называются 32-разрядными приложениями (в отли­чие от 16-разрядных, в которых все адреса 16-разрядные, хотя данные могут иметь размер 32 бит). Для создания 32-разрядного приложения в состав программы необходимо включить (в соответствующем месте) опи­сатель use32. Однако следует иметь в виду, что MS-DOS не позволяет за­пускать 32-разрядные приложения, которые, таким образом, должны быть приложениями Windows. В то же время приложения Windows обычно со­ставляются не на языке ассемблера, а на одном из языков высокого уров­ня — Паскаль, С или C++, где тип создаваемой программы (16-разрядная или 32-разрядная) определяется настройками компилятора. Поэтому воп­росы разработки 32-разрядных приложений на языке ассемблера не вош­ли в настоящую книгу.

Как известно, система Windows допускает запуск приложений DOS (программ реального режима), организуя для этого так называемый сеанс

Введение :

DOS, в котором программы фактически выполняются в режиме 86-го процессора. Кроме этого, в Windows предусмотрена возможность загрузки компьютера в режиме эмуляции DOS, когда компьютер работает под уп­равлением варианта DOS, встроенного в систему Windows. Наконец, ком­пьютер можно сконфигурировать так, чтобы он позволял загружать как Windows, так и «чистую» DOS (например, MS-DOS 6.22), без всякой Windows.' Каким вариантом загрузки компьютера пользоваться при прора­ботке настоящей книги - дело вкуса и привычек читателя. Приводимые в книге примеры в своем большинстве просты, не затрагивают каких-то специальных системных средств и будут работать в любом режиме. После­днее замечание не относится только к примеру программы защищенного режима, приводимому в гл. 4, а также к обработчику прерываний от мыши, рассматриваемому в гл. 3. Эти программы следует запускать на «чистой* DOS.

Архитектура реального режима

11

Бант