Table Of ContentЯ3ЫКn
nрограммnрованnя
Использование
п
при разработке программ
Режимы MASM и /delJ/
• Архитектура и команды
nроцессоров 80х86
• Программирование
сопроцессоров 80х87
• Объектно-ориентированное
nрограммирование
• Разработка DLL
и Windоws-nриложений
A.aUA;1EКIiIUIa • Поддержка языков с++
иРаsса/
Использование
ТuгЬо
Assembler
при·
разработке npoгpaMM~
Киев
"Диалектика"
1995
ББК.32.973
И26
Книжная редакция фирмы ..Диалектика"
3ав.редакцией С.В.Тох:арь
Испольвование Turbo Аssешblегпри разработкепрограмм/ Сост.
И26 А.А. Чекатков. - Киев: "Диалектика" 1995.- 288 с.
I
ISBN S-7707-S04З-Х
В книге описывается одна из'наиболее распространенных систем про
граммирования на языке Ассемблер для персональных компьютеров - Turbo
Аssешblег 3.х (TASM). Приводится большое число примеров программ 11
обширная справочная информация по системе ТASM
вьк 32.973
Borland - зарегистрированная торговая марка Borland Тпгегпацопа].Inc.
Все остальные названия изделий и программных продуктов являются зарегнстри
рованными торговыми марками соответствующих фирм.
© Л.А.Чекатков, подбор материала,
перевод, авторский текст,
компоновка и компьютерная
верстка
© фирма "Диалектика", 1993,
TSBN5-7707-504З-Х обработка и оформление
Введение
Б жизни каждого программиста наступает момент, когда он решает заняться изу
чением ассемблера. И это, без сомнения, правильное решение! Настоящий профее
сионал должен уметь создавать программыI использующие ресурсы компьютера с
максимальной эффективностью, а все это невозможно без применения ассемблера.
"Максимальная скорость выполнения при минимальных размерах программы' - де
виз, под которым работают программисты. пишущие на ассемблере.
Однако ассемблер имеет одну особенность, которая отпугивает многих начинаю
щих программистов. - он является машинно-ориентированным языком. Это означа
ет, что пишущий на ассемблере работает непосредственно с ресурсами компьютера,
что требует хорошего знания его архитектуры, логики работы операционной систе
мы, а также большой аккуратности при написании программы.
Поэтому данная книга призвана помочь тем программистам, которые только при
ступили к изучению ассемблера и еще не освоились в мире процессоров фирмы Intel
и операционныхсистемфирмыМiсrоsоft.
Но профессионал, для которого все это является давно пройденным этапом,
также может найти здесь немало интересного, поскольку материал, изложенный в
книге, описываетне только язык ассемблера, но и такие возможности,реализован
ные в транслятореTurbo Assembler фирмы Borland, как:
• применение объектно-ориентированной техники программирования;
• поддержка 32-разрядной модели памяти и кадра стека;
• полная поддержка процессоров 386 и 486;
• директивы упрощенной сегментации;
• поддержка таблиц; .
.. полное сохранение информации об исходном тексте для отладчика Turbo
Debugger;
• возможность разработки программ для среды Мiсrоsоft Windows.
Подробномуописаниювсех этих и другихос~бенностейТшЬо Assembler позво
J
ляющих разрабатывать программы с максимальной эффективностью, посвящена зна
чительная часть книги.
Следующая группа которой может быть полезна эта книга - программисты, ис
I
пользующие компиляторы с языков высокого уровня, разработанные фирмой
Borland - С++ и Pascal. Основываясьна материале, изложенномв данной книге,
они могут писать на ассемблереподпрограммы,критичные по времени выполнения,
и подключатьих к своимпрограммам.
Даннаякнигаможетоказатьпомощь и тем, кто использовалраньшетрансляторс
языка ассемблера фирмы Мicrоsоft. Применяя описанныездесь возможностиТигЬо
Assembler, они могут с наименьшими затратами преобразовать свои программы на
MASM дЛЯ того, чтобы использовать ТигЬо Assembler с максимальной эффек
тивностью.
Краткое описание ~ИГИ
Данная книга состоит из 8 частей. Материал излагается в порядке возрастания
сложности, поэтому тем, кто только начинает изучать ассемблер, рекомендуется на
чать чтение с первой части. Более опытные программисты могут переходить сразу к
изучению нужных им тем. Заключительная часть носит справочный характер и мо
жет использоваться в практической работе по написанию программ на ассемблере.
Введение з
Часть 1 содержит первоначальные сведения об ассемблере, описание архитектуры
пропессора 8086, основы организации загрузки и выполнения программ в DOS, а
такжеподробноеописаниевсех командпроцессора8086.
.Часть 2 посвящена применению Turbo Assembler для разработки программ в ре
альном режиме.
Часть 3 рассматривает архитектуру процессора 80386, команды защищенного ре
жима и возможности Turbo Assemblerпо написанию программ, использующих защи
щенный режим.
Часть 4 излагает основные понятия технологии объектно-ориентированного прог
раммирования, содержит описание директив Turbo Assembler и пример программы.
реализующей эту технологию.
Часть .5 предназначена для программистов, работающих на языках высокого
уровня, и описывает интерфейсы между Turbo Assembler и компиляторами Borland
.С++ 11Borland Pascal.
Часть 6 выделяет основные концепции программирования на ассемблере для сре
ды Мicrоsоft Windows, содержитпримерыпрограммдляэтой среды.
Часть 7 представляет описание архитектуры и команд математических сопроцес
соров х87, содержит пример программы. использующей сопроцессор.
Прияожения, как уже говорилось, носят справочный характер 11содержат сведе
ния по практическому применению Turbo Assembler.
Что нужно знать для того, .чтобы начать работу
.Для эффективной работы скнигой необходимо владеть основными приемами ра
боты в DOS (а в некоторыхразделах - и в Windows) и уметь создавать текстовые
файлы с помощью какого-либотекстовогоредактора.
Крометого, необходимоиметь на компьютересам Turbo Assembler. Установка его
происходит автоматически при установке Borland Pascal ИЛИ Borland С++. При этом
выдается запрос на необходимостьустановкиTurbo Assembler и на указание катало
гов, в которых будут размещены файлы, относящиеся к Тцгоо Assembler. В книге
описан Turbo Assembler версии 3.2. В случае использования более ранних версий
нужно иметь в виду, что какие-то особенности, характерные для версии 3.2, будут
отсутствовать.
4 Испольэование Тщ-Ьо Asstlmbfer1lpUразработкепрограмм
Часть 1. Первоначальные сведения об ассемблере
и разработке программ для процессора 8086
Глава 1. Пример разработки простейшей программы на
~ссемБJIере
t.1. Создание,исходного текста программы
На рис.Гл приведен текст простейшей программы на ассемблере, выводящей на
экран строку "Здравствуйте!",
; Д.ННlolе nporpaMMlo1
ОАТА SEGMENT
HELLO ОВ 'Здра8СТ8уйте 1$'
ОАТА ENDS
; Код nporpaMMlo1
СООЕ SEGMENT
ASSUMECS: СООЕ. DS: ОАТА
START: ml:)v АХ,DАТА
mov OS. АХ
тоу АН .9 ; 8...80Д сообщения
тоу ОХ, OFFSETHELLO
int '21h
mov АН'. .4Ch ; 81olXOA из nporpaMMlo1
int 21h
СООЕ ENDS
ENO START
Рис.1.1. ПростенwаJl программ•.
Чтобы создать файл с исходнымтекстомданной программы.надо запуститька
кой-нибудьтекстовыйредактор,набратьприведенныйна рис.1.1 текст и сохранить
его в файлес любымименеми расширением.ASM (расширение может отличаться от
.ASM, но тогда при вызове Turbo Assemblerнужно будет указывать его вместе с име
нем файла, тогда как расширение .ASMтранслятор использует по умолчанию).
1.2. Трансляция, компоновка и запуск программы на выполнение
Подготовив текст программы и сохранив его в текстовом файле (например,
нвц.о.хзмт, можно переходить к созданию исполняемого файла, который будет
запускаться на выполнение, как любая программа DOS.
На рис.l.2 представлена схема разработки программ на Assembler. Как видно из
рисунка, процесс создания программы включает подготовку исходного текста прог
раммы, трансляцию,его в файл специального вида, называемого объектным файлом,
и компоновку полученного.объектного файла (или полученных объектных файлов,
если создаваемая программа состоит из нескольких модулей) в выполняемый файл.
После того как в результате компоновки получен выполняемый файл, его можно за
грузить и выполнить в DOS. Если в результате работы созданной программы возник
нет необходимость в изменениях ее алгоритма, весь процесс повторяется сначала.
Для трансляции HELLO.ASM необходимо в строке приглашения DOS ввести:
TASM h.11o
После этого произойдет вызов Turbo Assembler, которому в качестве параметра
будет передано имя файла, содержащего исходный текст программы (так как расши-
Часть f 5
рение не задано, Turbo Assembler будет считать, что используется расширение
.хвмэ. Если текст программы набран правильно, то в результате работы транслято
ра на экране появится следующий текст:
Turbo Ass.mbI.r V.rsion 3.2Copyright (с) 1992Ьу Вorlend Int.rn.tion.l, Inc
Ass.mbIingfde: h.llo.asm
Error m.SS8g8S: Нon.
W.ning m.sseges: Non.
Р8а•••: 1
R.m8ining m.mory: 331k
Это означает, что процесс трансляции завершился успешно. В этом случае Turbo
Assembler создает файл HELLO.OBJ, содержащий оттранслированную программу.
Если в процессетрансляции будут обнаружены ошибки, то объектный файл не со
здается, а сообщенияоб ошибках появляютсяв пункте Еггог messages.Тогда необхо
димо отредактировать исходный текст программы, устранив в нем указанные в сооб
щениях ошибки, и повторить трансляцию.
Соэдание ПDограммы
ИСХОДНItIЙ текст
HELLO.ASM
Тран!ляция
•
ое~еКТН"IЙ Ф.ЙJ1
HELLO.OBJ
,
I
Компоновка
В~lпоnн.еМ"IЙ фай,"
,
HELLO.EXE
I
Выполнение
I
Рис:.1.2.СО3Д8Нне nporp.MM~1 Н8 кс:ем6neре.
После получения объектнего файла выполняется его компоновка в выполняемый
файл. Для этого используется компоновщик Turbo Linker фирмы Богlапd. Для за
пуска компоновщика необходимо ввести строку:
TLINK h.1Io
После этого произойдет запуск на выполнение компоновщика с передачей ему в
качестве параметра имени объектного файла (по умолчанию используется расшире
ние .ОВ]). При работе компоновщика на экране должно появиться сообщение:
Turbo Link V.rsion 5.1 Copyright(с) 1992Ьу BorlandJntern8tion81, Inc
Warning: но iteck
Это означает, что процесс компоновки завершился успешно и на диске создан
файл программы HELLO.ЕХЕ, готовый к выполнению (на предупреждающее сооб- '
щениеWarning в данномслучаеможноне обращатьвнимания).
6 Использование Turbo Assemblerпри разработкепрограмм
Теперь созданную программу можно запустить на выполнение, введя в строке
приглашения DOS имя исполняемогофайла Ьейо. В результатеработы программы
на экранепоявитсястрока
Здравствуйте'
Таким образом, процесс создания программы успешно завершен! Из исходного
текстапрограммы.находящегосяв файле HELLO.ASM, трансляторомсоздан объек
тный файл HELLO.OB), из которого, в свою очередь, компоновщиксоздал выпол
няемыйфайл HELLO.EXE. Крометого, компоновщиксоздает карту испояьэования
памяти (файлс расширением.МАР), котораяможетпонадобитьсядля анализаком
поновкипрограммы.состоящейиз несколькихобъектных"файлов.
{.3. Объектный код программы
Если при трансляции программы вызов ТитЬо Assembler ввести в виде:
TASM hello /1,
то трансляторпомимообъектногофайла создасттекстовыйфайл HELLO.LST, в ко
тором, в частности, будет содержатьсяинформация, приведеннаяна рис.1.3. Этот
файлназываетсяфайломлистинга.Листингпредназначендля представленияобъект
ного кода программы в шестнадцатиричномвиде вместе с соответствующимему ис
ходнымтекстом.
1 0000 DAТАSEGMENT
2 0000 87 А4 ЕО АО HELLO DB'3дракт.уЙТе 1$'
А2 Е1 Е2 +
3 А2 Е3 А9 Е2
AS 2021 +
4 24
5 OOOF ')АТА ENDS
6 0000 СООЕ SEGMENT
7 ASSUME CS: CODE,DS: ОАТА
8 0000 880000, START: mov АХ, DATA
9 0003 8Е D8 movDS, АХ
100005 8409 mov АН, 9; ...I80AсообщеННR
110007 ВА OOOOr mov ОХ. OFFSETHELLO
12000А СО 21 int 21"
13000С 844С mov АН. 4Ch; ...IXOA1013nporpaMMIo.
14000е CD 21 int 21.,
150010 CODE ENOS
16 ENDSTART
Рнс.1.3. Фрагмент листинга HELLO.LST.
Объектный код находится слева от исходного текста программы. Заметим, что
некоторые строки программы не порождают объектного кода. Это объясняется тем,
что в данных строках находятся не команды процессора и не данные, с которыми
они работают, а директивы ассемблера, предназначенные.для управления пропессом
трансляции.
Второй вывод, который можно сделать, анализируя этот листинг, - каждой ас
семблерной команде соответствует свой код, причем одинаковые команды могут
иметь разные коды. Причиной такого разнообразия кодирования одних и тех же ко
манд служит вид операндов, с которыми работают эти команды. Например, команды
mov АН,9 н mov AH,4Ch
имеютодинаковыекоды (В4) и отличаютсятолькозначениемоперандов(09 и 4С со
ответственно), так как форма операндов (значение, заданное непосредственно в ас
семблернойкоманде) у них одинакова. В то же время 8 других операторах, исполь
зующих команду пюу, коды различны, так как все они работают с различными типа
ми операндов.
Таким образом, объектный код - это представление программы. написанной на
языке ассемблер, в том виде, который может воспринимать процессор, При этом
~~1 7
каждый оператор программы кодируется числом или группой чисел, значение кото
рых определяется командой, примененной в этом операторе, и данными, которыми
оперирует эта команда. Всю работу по такому кодированию выполняет транслятор.
После успешного завершения трансляции полученный объектный код помещается в
специальном формате в файл, называемый объектным файлом. Компоновщик, объе
диняя все объектные файлы, из которых состоит программа, в один выполняемый
файл, завершает работу по подготовке программы для запуска.
Глава 2. Архитектура процессора 8086
2.1. Устройство персонаяьвого компьютера
Традиционный настольный персоналъный компьютер (ПК) состоит из системного
блока, монитора, клавиатуры и мыши. Системный блок содержит: блок питания,
системную (материнскую) плату, адаптеры внешних устройств, накопители на жест
ких магнитных (НЖМД) и гибких (НГМД) дисках. а также ряд других устройств.
Для нас вначале наибольший интерес представляет системная плата, на которой
размещаются оперативная память, процессор и логика управления, связанные между
собой наборами проводников, которые называются шинами.
Овератнвяая память физически выполнена в виде микросхем и предназначена
ДЛЯ временного хранения программ и данных, которыми они манипулируют. Логи
чески оперативную память можно представить в виде последовательности ячеек. каж
дая из которых имеет свой номер, называемый адресом. Использование оперативной
памяти определяется тем, что считывание или запись в ее ячейку занимает доли мик
росекунды, а для других устройств это время в 1О, а для медленных периферийных
устройств даже в 1000 раз больше.
Центральный процессор (ЦП). в современных персональных компьютерах вы
полнен в виде одной сверх60ЛЬШОЙ интегральной микросхемы (СБИС), содержащей
свыше миллиона транзисторов. ЦП выполняет машинные команды, выбирая их в
заданной последовательности из оперативной памяти.
Работа всех электронных устройств компьютера координируется сигналами уп
равления, вырабатываемыми ЦП и некоторыми другими СБИС, сигналами тактового
.генератора (тактовой частоты), с помощью которых синхронизируются действия всех
сигналов.
Возможности компьютера в наибольшей степени зависят от типа установленного
процессора и его тактовой частоты. Семейство процессоров 80х86 корпорации Intel
включает в себя следующие микросхемы (в новых обозначениях 80 заменено на
iAPX - Intel Advanced Processor Агсшгесшге):
• 16-разрядные: 8086, 8088, 80186, 80188, 80286 (процессоры х88 имеют 8-:раз-
рядную шину данных);
• 32-разрядные: i386SX, i386DX (80386), i486SX, i486DX, i486DX2, i486SL;
• 64-разрядные: Pentium.
,Совместимые с процесссрами 80х86 микросхемы выпускают также фирмы AMD,
IBM и Cyrix.
2.2. Основныесведенияо процессоре8086. Системысчисления,принятыеддя
преаставаевияданныхв прог~аммахна ассемблере
С точки зрения программиста. процессор8086.состоит из 8 регистров общего на
значения, 4 сегментных регистров, регистра адреса команды и регистра флагов. Про
цессор выставляет на шину адреса адрес выбираемых из памяти команд (или дан
ных), которые-поступают в шесгибайтный буфер (очередь команд). Это определяет
также невозможностъ модификации в программе команды, следующей за вьшолняе
мой в текущий момент.
Адресную шину можно представить в виде 20 проводников, в каждом из кото
рых может либо протекать напряжение заданного уровня (сигнал 1), либо отсутство-
8 Использование ТиrЬоAssemblerприразработкепрограмм
вать (сигнал О). Система счисления, построенная на цифрах О и 1 называется Д80И
чной. цифра 2 в двоичной системе записывается как .10, 3 - как 11, 4 - как
100, 5 - как 101, 6 - как 11О и т. д.
Минимальная единица информации, соответствующая двоичному разряду, назы
вается бит. Группаиз8 битовназываетсябайтом (байт - наименьшая адресуемая, еди
ница основной памяти), 2 байта (16 бит) образуют слово, а 16байтов - параграф.
Таким образом, с помощью тб-раэрядной шины данных можно передавать числа
от О (во всех проводниках сигнал О) до 65535 (во всех проводниках сигнал 1). Нес
мотря на то, что двоичная система обладает высокой наглядностью, она имеет суще
ственный недостаток - числа, записанные в двоичной системе, слишком громоздки.
С другой стороны, привычная для нас десятичная система слишком сложна для пе
ревода чисел в двоичную и обратно. Поэтому наибольшее распространение в практи
ке программирования получила"шестнадцатеричная система счисления.'
На рис.2.2 приведены представления чисел от О до 16 в двоичной, десятичной и
шестнадцатеричной системах. Используя эту таблицу, можно легко переводить числа
из шестнадцатеричной системы в двоичную и обратно. Например, шестнадцатеричное
значение 6F запишется в двоичной системе как 01101111 (6=0110 + F=1111), а двои
чное 001111011100 - как шестнадцатеричное 3DC (0011=3 + 1101=D + 1100=С).
ДЛЯ указания основания системы счисления после числа пишется буква, например:
11 - десятичное 11, 11Ь - двоичное 3, 11h - шестнадцатеричное17.
Двоичное Десятичное UUестнадцатеричное
0000 00 00
0001 01 01
0010 02 02
0011 03 03
0100 04 04
0101 OS OS
0110 06 06
0111 07 07
1000 08 08
1001 09 09
1010 10 ОА
1011 11 ов
1100 12 ОС
1101 13 00
1110 14 ое
1111 1S OF
10000 16 10
Рис.2.2. Форм...предст••neННАчисел.
2.3. Адресация памяти в процессоре 8086
Числа, устанавливаемые процессором на адресной шине, являются адресами, Т.е.
номерами ячеек оперативной памяти, из которых необходимо считывать очередную
команду или данные. Размер ячейки оперативной памяти составляет 8 разрядов, т.е.
1 байт. Поскольку процессор использует тб-раэрядные адресные регистры, то это
обеспечивает ему доступ к 65536 (FFFFh) байт или 64К (1К=1024 байт) основной
памяти. Такой блок непосредственноадресуемойпамяти называетсясегментом. Лю
бой адресформируется"ИЗ адресасегмента(всегдакратен16) и адреса ячейки внутри
.сегмента (этот адрес называют смещением), На компьютерах, оснащенных процессо
ром 8086, оперативная память обычно имеет размер, равный 640К. ДЛЯ того чтобы
работать с памятью такого размера, процессор осуществляет пересчет адресов с по
мощью процедуры, называемой вычислением эффективного адреса (рис.З.З).
Физический 20-разрядный адрес вычисляется сложением сдвинутого влево на 4
разряда 16-разрядного адреса сегмента оперативной памяти со значением 16-разряд
ного смещения относительно начала этого сегмента. Используя 20-разрядные адреса,
можно адресовать 1М оперативной памяти ( 1М=1024К= 1048576 байт). В программе
на ассемблере полный адрес записывается в виде
5555:0000,
где SSSS значение адреса сегмента;
0000 значение смещения в этом сегменте. Например, физический адрес
Часть f 9