КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
Листинг 3.1. Пример программы на ассемблере
<1>;---- Prg_3_1. asm------------- <2>;Программа преобразования двузначного шестнадцатеричного числа <3>;в символьном виде в двоичное представление <4>;Вход: исходное шестнадцатеричное число из двух цифр <5>;вводится с клавиатуры <6>;Выход: результат преобразования должен <7>;быть в регистре dl <8>;-------------------------------------- <9> data segment para public “data”; сегмент данных <10> message db “Введите две шестнадцатеричные цифры, $” <11> data ends <12> stk segment stack <13> db 256 dup ("?"); сегмент стека <14> stk ends <15> code segment para public "code»; начало сегмента кода <18> mov ax,data; адрес сегмента данных в регистр ах <19> mov ds,ax; ах в ds <20> mov ah, 9 <21> mov dx,offset message <22> int 21h <23> xor ax,ax; очистить регистр ах <24> mov ah, 1h;1h в регистр ah <25> int 21 h; генерация прерывания с номером 21h <2б> mov dl,al; содержимое регистра al в регистр dl <27> sub dl,3Oh; вычитание; (dl)=(dl)-30h <28> cmp dl,9h; сравнить (dl) с 9h <29> jle M1; перейти на метку М1 если dl<9h или dl=9h <30> sub dl,7h; вычитание: (dl)=(dl)-7h < 31 > М1:; определение метки М1 <32> mov cl,4h;пересылка 4h в регистр cl <33> shl dl.cl; сдвиг содержимого dl на 4 разряда влево <34> int 21h; вызов прерывания с номером 21 h <35> sub al,30h;вычитание: (dl)=(dl)-30h <36> cmp al.9h;сравнить (al) с 9h 28 <37> jle M2; перейти на метку М2 если al<9h или al=9h <38> sub al,7h; вычитание; (al)=(al)-7h <39> М2:;определение метки М2 <40> add dl.al;сложение; (dl)=(dl)+(al) <41> mov ax,4c00h; пересылка 4c00h в регистр ах <42> int 21h; вызов прерывания с номером 21h <43> main endp; конец процедуры main <44> code ends; конец сегмента кода <45> end main; конец программы с точкой входа main
Посмотрите внимательно на программу. В ней есть три участка, заключенные между директивами segment и ends (строки 9 и 11, 12 и 14, 15 и 44). Микропроцессор аппаратно поддерживает четыре адресно-независимых областей памяти: сегмент кода, сегмент данных, сегмент стека и дополнительный сегмент данных. Строки 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С В результате после отработки команды в строке 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 это условие как раз выполняется, поэтому происходит переход на метку М1 (строка 31). Каждая шестнадцатеричная цифра занимает одну тетраду. У нас — две таких цифры, поэтому нужно их разместить так, чтобы старшинство разрядов сохранялось. Строки 32-33 сдвигают значение в dl на 4 разряда влево, тем самым, освобождая место в младшей тетраде под младшую шестнадцатеричную цифру. Строка 34 вводит вторую шестнадцатеричную цифру С (ее ASCII-код 63h) в регистр al: ах = 0000 0001 0100 0011 Строки 35-37 выясняют, попадает ли двоичный эквивалент второго символа шестнадцатеричной цифры в диапазон 0...9. Наша вторая цифра не попадает в диапазон, поэтому для получения правильного двоичного эквивалента нужно произвести дополнительную корректировку. Это делает строка 38. Состояние al после выполнения строки 35 следующее: ах = 0000 0001 0001 0011 В al записано 13h, а нужно, чтобы было 0Ch (помните о правилах записи шестнадцатеричных чисел!). Так как 0Ch не попадает в диапазон 0...9, то происходит переход на строку 38. В результате работы команды вычитания в регистре al получается правильное значение (al) = 0Ch: ах = 0000 0001 0000 1100
И, наконец, строка 40 производит сложение сдвинутого значения в dl с числом в al: dx = 0000 0000 0101 0000 + ах = 0000 0001 0000 1100 = dx = 0000 0000 0101 1100 Таким образом, в регистре dl мы получили двоичный эквивалент двух введенных символов, изображающих двузначное шестнадцатеричное число: (dl) = 05Ch Строки 41-42 предназначены для завершения программы и возврата управления операционной системе. Не случайно столь детально был рассмотрен этот пример. Он отражает практически все специфические особенности программирования на ассемблере.
Глава 9 Разработка многомодульных программ на языке
Дата добавления: 2014-11-09; Просмотров: 971; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |