assembler. Учебник для вузов_Юров В.И_2003 -637с (862834), страница 28
Текст из файла (страница 28)
Пример программы на ассемблере<1>;Prg_6_l.asm'•<2>;Программа преобразования двузначного шестнадцатеричного числа<3>;в символьном виде в двоичное представление.<4>;Вход: исходное шестнадцатеричное число из двух цифр,<5>;вводится с клавиатуры.<б>;Выход: результат преобразования помещается в регистр dl.<9><10><11><12><13><14><15><16><17><18>data segment para public "data";сегмент данныхmessage db "Введите две шестнадцатеричные цифры,$"data endsstk segment stackсегмент стекаdb 256 dup ("?")stk endsначало сегмента кодаcode segment para public "code"начало процедуры mainmain procassume cs:code,ds:data,ss:stkmov ax,data;адрес сегмента данных в регистр ахпродолжение *126Глава 6.
Первая программаЛистинг 6.1 (продолжение)mov ds.ax;ax в dsmov ah,9<20>raov dx,offset messageint 21h<22>xor ax ,axочистить регистр ах<23>mov ah, inIh в регистр ah<24>int 21hгенерация прерывания с номером 21h<25>mov dl.alсодержимое регистра al в регистр dl<2б>sub dl 30hвычитание: (dl)=(dl)-30h<27>cmp dl 9hсравнить (dl) с 9h<28>перейти на метку Ml, если dl<9h или dl=9h<29>jle Mlsub dl, 7hвычитание: (dl)=(dl)—7h<30>определение метки MlMl:mov cl,4hпересылка 4h в регистр cl<32>shl dl.clсдвиг содержимого dl.Ha 4 разряда влево<33>вызов прерывания с номером 21h<34>int 21hвычитание: (dl)=(dl)—30h<35>sub al,30hcmp al 9h<36>сравнить (al) с 9h<37>перейти на метку М2, если al<9h или al=9hjle M2<38>sub al ,7hвычитание: (al)=(al)-7hM2:определение метки М2<39><40>add dl.alсложение: (dl)=(dl)+(al)пересылка 4c00h в регистр ахmov ax,4c00h<42>int 21hвызов прерывания с номером 21пmain endpконец процедуры m a i n<43>конец сегмента кода<44>code endsend mainконец программы с-точкой входа main<45>В предыдущих главах говорилось, что процессор аппаратно поддерживает шестьадресно-независимых областей памяти: сегмент кода, сегмент данных, сегмент стекаи три дополнительных сегмента данных.
Наша программа использует только первые три из них.Строки 9-11 определяют сегмент данных. В строке 10 описана текстовая строка с сообщением «Введите две шестнадцатеричные цифры».Строки 12-14 описывают сегмент стека, который является просто областьюпамяти длиной 256 байт, инициализированной символами «"?"». Отличие сегмента стека от сегментов других типов состоит в использовании и адресации памяти.В отличие от сегмента данных (наличие которого необязательно, если программане работает с данными), сегмент стека желательно определять всегда.Строки 15-44 содержат сегмент кода. В этом сегменте в строках 16-43 определена одна процедура main.Строка 17 содержит директиву ассемблера, которая связывает сегментные регистры с именами сегментов.Строки 18-19 выполняют инициализацию сегментного регистра DS.Строки 20-22 выводят на экран сообщение message:Введите две шестнадцатеричные цифрыСтрока 23 подготавливает регистр АХ к работе, обнуляя его.
Содержимое АХ послеэтой операции следующее:ах = 0000 0000 0000 0000Строки 24-25 обращаются к средствам операционной системы для ввода символа с клавиатуры. Введенный символ операционная система помещает в регистрAL. К примеру, пусть в ответ на сообщение с клавиатуры были введены две шестнадцатеричные цифры:5СПример простой программы127В результате после отработки команды в строке 25 появится один символв ASCII-коде — 5, и состояние регистра АХ станет таким:ах = 0000 0001 0011 0101Строка 26 пересылает содержимое AL в регистр DL. Это делается для того, чтобыосвободить AL для ввода второй цифры.
Содержимое регистра DX после этой пересылки следующее:dx = 0000 0000 0011 0101Строка 27 преобразует символьную цифру 5 в ее двоичный эквивалент путем вычитания 30h, в результате чего в регистре DL будет двоичное значениечисла 5:dx = 0000 0000 0000 0101В строках 28-29 выясняется, нужно ли корректировать двоичное значение в DL.Если оно лежит в диапазоне 0...9, то в DL находится правильный двоичный эквивалент введенного символа шестнадцатеричной цифры.
Если значение в DL больше 9,то введенная цифра является одним из символов А, В, С, D, E, F (строчные буквыдля экономии места обрабатывать не будем). В первом случае строка 29 передаступравление на метку Ml. При обработке цифры 5 это условие как раз выполняется,поэтому происходит переход на метку Ml (строка 31).Каждая шестнадцатеричная цифра занимает одну тетраду.
У нас две таких цифры, поэтому нужно их разместить так, чтобы старшинство разрядов сохранялось.В строках 32-33 значение в DL сдвигается на 4 разряда влево, освобождая местов младшей тетраде под младшую шестнадцатеричную цифру.В строке 34 в регистр AL вводится вторая шестнадцатеричная цифра С (ее ASCIIкод — 63h):ах = 0000 0001 0100 0011В строках 35-37 выясняется, попадает ли двоичный эквивалент второго символа шестнадцатеричной цифры в диапазон 0...9.
Наша вторая цифра не попадаетв диапазон, поэтому для получения правильного двоичного эквивалента нужнопроизвести дополнительную корректировку. Это делается в строке 38. СостояниеAL после выполнения строки 35 следующее:ах = 0000 0001 0001 0011В AL записано число 13h, а нужно, чтобы было ОСЬ (помните о правилах записишестнадцатеричных чисел!). Так как ОСЬ не попадает в диапазон 0...9, то происходит переход на строку 38. В результате работы команды вычитания в регистре ALполучается правильное значение (al) = ОСЬ:ах = 0000 0001 0000 1100И наконец, в строке 40 сдвинутое значение в DL складывается с числом в AL:dx = 0000 0000 0101 0000ах+=0000 0001 0000 1100dx=0000 0000 0101 1100Таким образом, в регистре DL получен двоичный эквивалент двух введенныхсимволов, изображающих двузначное шестнадцатеричное число:(dl) = 05Ch128Глава 6.
Первая программаСтроки 41-42 предназначены для завершения программы и возврата управления операционной системе.Этот пример не случайно рассмотрен столь детально. Он отражает многие специфические особенности программирования на ассемблере. На его основе построен материал следующего раздела, посвященный тому, как из исходного модуляполучить правильно функционирующий исполняемый модуль.Процесс разработки программыНа рис.
6.1 приведена общая схема процесса разработки программы на ассемблере. Название программы соответствует рассмотренному ранее примеру программы (см. листинг 6.1). На схеме выделено четыре этапа этого процесса. На первомэтапе, когда вводится код программы, можно использовать любой текстовый редактор. В Windows таким редактором может быть Блокнот (Notepad). При выборередактора нужно учитывать, что он не должен вставлять «посторонних» символов(специальных символов форматирования).
С этой точки зрения Microsoft Wordв качестве основного редактора ассемблерных программ не годится. Очень интересный редактор — Asm Editor for Windows (http://www.avtlab.ru). Созданный с помощью текстового редактора файл должен иметь расширение .asm.1.ВВОД ИСХОДНОГО ТЕКСТА ПРОГРАММЫТекстовыйредакторprg_3_1 .
asm/2. СОЗДАНИЕ ОБЪЕКТНОГО МОДУЛЯТрансляцияпрограммыTasm exe•51. .>1^** ^.^1пгп Ч 1 kt^~^^^prg_3_1 .erf^*4. ОТЛАДКА ПРОГРАММЫРис. 6.1. Схема процесса разработки программы на ассемблереДля выполнения остальных этапов разработки требуются специализированныепрограммные средства из пакета MASM или TASM. В ходе настоящего обсуждения будут описываться средства обоих пакетов, но в основном на примере TASM,поскольку процесс разработки ассемблерных Программ с использованием этогоПроцесс разработки программы129пакета более нагляден.
В принципе, все пакеты ассемблера выполняют практически одну работу, но по-разному, например, маскируют ее с помощью интегрированный среды или объединяют некоторые этапы разработки. Поняв суть преобразований исходной программы, выполняемых пакетом TASM, освоить другие пакетыассемблера будет на порядок легче и.Трансляция программыСледующий шаг на пути создания исполняемого модуля — трансляция программы. Для трансляции нужен подготовленный и записанный на диск исходный текстпрограммы (см. листинг 6.1).На этапе трансляции решается несколько задач:Ш перевод команд ассемблера в соответствующие машинные команды;• построение таблицы символов;« расширение макросов;is формирование файла листинга и объектного модуля.Программа, которая реализует эти задачи, называется ассемблером. Итог работы ассемблера — два файла: файл объектного модуля и файл листинга.Объектный модуль включает в себя представление исходной программы в машинных кодах и некоторую другую информацию, необходимую для отладки и компоновки его с другими модулями.
При использовании пакета TASM получениеобъектного модуля исходного файла производится программой (ассемблером)tasm.exe. Формат командной строки для запуска tasm.exe следующий:TASM [ключи] имя_исходнрго_файла [,имя_объектного_файла][,имя_файла_листинга] [,имя_файла_перекрестных_ссылок]Помнить формат командной строки tasm.exe необязательно. Получить быструюсправку о нем на экране можно, если запустить tasm.exe без параметров. Обратитевнимание на то, что большинство параметров заключено в квадратные скобки.
Этообщепринятое соглашение по обозначению необязательных параметров. Из этогоследует, что обязательным аргументом командной строки является лишь имя исходного файла. Этот файл должен находиться на диске и обязательно иметь расширение .asm. За именем исходного файла через запятую могут следовать необязательные параметры, обозначающие имена объектного файла, файла листингаи файла перекрестных ссылок. Если не задать их, то соответствующие файлы попросту не будут созданы. Если же их нужно создать, то необходимо учитывать некоторые моменты.II Если имена объектного файла, файла листинга и файла перекрестных ссылокдолжны совпадать с именем исходного файла (наиболее типичный случай), тонужно просто поставить запятые вместо имен этих файлов:tasm.exe prg_6_l , , ,В результате будут созданы файлы с одинаковыми именами и разными расширениями, как показано на рис.
6.1 для второго этапа.^ Если имена объектного файла, файла листинга и/или файла перекрестных ссылок не должны совпадать с именем исходного файла, то нужно в команднойстроке указать имена нужных файлов в соответствующем порядке, к примеру:5 Зак. 256130Глава 6. Первая программаtasm.exe prg_6_l , , p r g _ l i s t ,В результате на диске будут созданы файлы prg_6_l.obj, prg_list.lst, prg_6_l.crf.• Если требуется выборочное создание файлов, то вместо ненужных файлов необходимо подставить параметр nul Например:t a s m .