В.Н. Пильщиков - Программирование на языке ассемблера IBM PC (1110551), страница 15
Текст из файла (страница 15)
е. Бахах) обраиеииа: БвсЬ х где х - хв, мВ Па ВВХОДЕ2 Х - ВЗЕДЕВИВЙ СВМВОЛ Ваа(-вывод. Г(рерыванин дбд Ввод целого числа (со злаком я без) размером в слово обрааевве: йайзч х где х - г16А в16 аа заходе: х - ьзедеввое число особеааоств ьзодаА пропускаятса асе пробела и ловца строк перед числом; чясло долаио вачаватьса с цифра, перед аей зозмокев злак; лри мамусе число вводится как отрацатьльвое; ььод идет до первой аецвфрв (» т.ч. до Еасег), оаа глотаетса; врв оаибхе будет печать сообаеаяа в остапов программа; оаибки: "вет цифра" - а числе вет вм одвой цвфрв "переполвеаие" - болевое по модула число (ьве отрезка (-Хдчбд,+66616]) ехкгь ргос1а1ач:Хаг 1айач масго х 1оса1 гедах2 заме <х>,<ах,дг,дх,ах>,гедаку 16 гадах> са11 ргосьа1ач ;;х ах е1зе рсьц ак ;;х<>ак са11 ргосйайаг моч к,ах рор ах еа61Й еабм зосстааоьить запись а листяат: .Хйза дИАЛОГ.
МИФИ Глава 14 ДОПОЛНИТЕЛЬНЫЕ ВОЗМОЖНОСТИ В этой главе рассматриваются те команды ПК и средства ЯА, которые относительно редко используются на практике и которые не были рассмотрены в прелылущих главах книги. 14Л. Двоичио-десятичные числа В гл. 1 уже отмечалось, что в ПК помимо целых чисел, представленных в двоичной системе счисления (двоичных чисел), используются и двоична-десятичные числа (огпагу сооед оесипа), ВС0). В этом разделе рассыатриваются команды ПК, предназначенные лля реализации арифметических операций над такими числами.
14ЛЛ, Представление двоична-десятичных и АВСП-чисел Напоыним, что машинное представление двоична-лесятичных чисел строится по следующему правилу: каждая цифра из десятичной записи (неотрицательного) целого числа заменяется на четверку битов, изображающих эту цифру в двоичной системе счисления. Соответствие между десятичными цифрами и четверками битов следующее: На каждое двоична-десятичное число отводят соседние байты пажити - столько, сколько надо, Порядок, в котором цифры числа занимают эти байты, вообще говоря, не фиксируется и определяется програмыистом. Дело в том, что обработка этих чисел ведется по цифрам и переход от цифры к цифре организует сам программист, а он может с одинаковым успехом переходить от очередного байта как к следующему байту, так и к предыдущему.
Но лля определенности мы в дальнейшем будем располагать левые (старшие) цифры числа в байтах с меньшими адресами, а правые цифры - с большими. В ПК используются лва формата представления двоична-десятичных чисел- упакованный и неупакованный. При упакованном формате в кахсцый байт записываются две соседние цифры числа (при нечетном количестве цифр слева к числу приписывается 0), а при неупакованном формате в каждом байте размещается только одна цифра, которая прижимается к правому краю быйта Ниже приведены представления числа 592 в упакованном (слева) и неупакованном форматах (А - алрес первого из байтов, занятых числом): Доооонигелывме воемоииосги 250 А А+1 А+2 0000 0101 1001 0010 0000 0101 0000 1001 0000 0010 0 5 9 2 5 9 2 В ЯА переменные, значешы которых трактуются как двоична-десятичные числа, можно описазь по директиве ОВ с несколькими операндами: ;число 592 а упакованном виде ;число 592 в неупакованном видо РАСК ПВ 5Ь, 92Ь ОНРАСК ПВ зр 9р 2 Обратите внимание, что для упакованного числа в одном операнде надо указывать две цифры, причем указывать их в шестнадцатеричной системе, чтобы каждая из цифр при трансляции заменялась на соответствуюшую четверку битов независимо от другой цифры (если в качестве операнда указать десятичное число 92, тогда оно заменится на 0101100Ь, а не на 10010010Ь).
В реальных программах двоично-десятичные числа редко выписываются явно. Они обычно получаются из так называемых АЗСП-чисел - из числовых строк, из записи чисел в виде символьных строк (например, '592'), и в конце снова преобразуются в такие строки. Эти преобразования реализуются очень просто: поскольку в системе кодировки АЗСП символы-цифры от '0' до '9' имеют коды ст ЗОЬ до 39Ь, то для преобразования цифры-символа в цифру-число надо лишь выделить 4 правых бита из кола этого символа, а для обратного преобразования цифру-число надо сложить (арифметически или логически) с ЗОЬ. 14.1.2.
Слежение двоична-десятичных чисел Теперь рассмотрим, как реализуются арифметические операции нэд двоичнодесятичными числами. Начнем со сложения, "днвлог-мнои Сложение нвунакованнык двоично-двсяквичнык чисел В ПК нет команды сложения лвоично-десятичных чисел как единых обьектов, поэтому такие числа приходится складывать по цифрам: сначала складывают последние (младшие) цифры, затем - предпоследние и т. д. При этом, учитывая специфику представления таких чисел, при сложении двух их цифр приходится особым образом устанавливать, есть ли перенос в старшие цифры и какую цифру надо записать в соответствуюшую позицию числа-результата Здесь возможны два случы. Если сумма лвух цифр не превосходит 9 (например, 2+Зи5и00000101Ь), тогда переноса в старшие цифры нет (в флаг переноса СР мадо записать 0), а в качестве цифры результата надо взять получившуюся величину. Но если сумыа цифр больше 9 (5+8и13=00001101Ь), тогда перенос в старшие цифры есть и его надо запомнить в флаге СР, а в результат надо записать величину, которы на 10 ввеньше полученной суммы.
В последнем случае можно поступить и иначе: надо к сумме цифр прибавить б и затем обнулить левую половину баГпа (13+6=19о00010011Ь -> 00000011ЬмЗ); отметим, что ПК действует именно по этому варианту. 260 Программирование нв языке ассемблера )ВМ РС Такой анализ и преобразоваиие сумыы двух цифр двоичио-десятичиых чисел реализует следующая команда ПК: ьяс11-коррекция после слоиевия (ьвс11 аййсзе аяеег адазезоа]: ььь Эта команда ставится после команды сложения (иапример, А))П), которая сложила две десятичные цифры и записала сумму в регистр А1. Эгот регистр является неявным операндом команды ААА, именно его содержимое оиа аиализирует и корректирует.
Например: ИОЧ ЬЬрз моч ьь,в ЬЬЬ ;ЬЬ 13 )СР 1, ЬЬ 03 С помощью данной комаидм ью:кио следующим образом сложить два )()-зиачиых иеупаковаииых двоичио-десятичиых числа Х и У и записать сумму в ь (комаида С1 С обиуляет флаг переноса - см. разд. 14.0): в впв Х ОВ И ООР(2) 1 ов и ООР(г) я ов г,и ооэ(г) запись переноса из стариих цифр Теперь приведем полисе описание действия команды ААА: если флаг дополим(ельиого переиоса АР равен 1 или если в 4 правых битах регистра АЬ иаходится величииа от 10 до 15, тогда значение А1.
увеличивается иа б, флаг переиоса СР получает значение 1 и значение регистра АН увеличивается иа 1, иначе лишь обнуляется флаг СР; в любом случае 4 левых бита А1. обиуляются. Отыетим, что команда ААА меняет и друп(е флаги (иапример, флаг АР получает то же самое значение, что и флаг СР), одиако это обычно ие представляет интерес. Поясним действия команды ААА.
Прежде всего отметим, что команда анализирует только 4 правых бита регистра А1., ие обращая внимания иа левые биты (причииа этого будет указана люке). Поэтому, если предыдущая команда сложеиия получила сумму больше 9, то коыаида ААА сможет распознать только суьщы ; слокевне веупакозваияк иоч сх,и МОЧ Вх,д-з СЬС впм: иоч ьь,х(вх) ы)с ьь,т(вг] ЬЭЬ моч 2161+1),ьь овс ах ЬООР ЯОМ моч я,о ьос г,о нервна 6авт - для переноса иэ старэяк цвфр 2-10-вых чисел: Я: Х+1 ;количество цифр з слагаемых ;иадекс цифр слагаемых (справа палево) )СР - перенос вз младиих цвфр (вначале СР О) слокеияе цвфр с учетом переноса вз млад. цифр коррекция суммы и эапясэ з СР переноса запись цифры суммы в Х к предмдупиы цифрам слагаемая (команды Оес н ьоОР пе меняет су) Дололннгвльнме аоэмоиносгн 261 от 10 до 15.
Для распознавания же сумм больше 15 привлекается флаг дополнительного переноса АР. Этот флаг меняется мноп(ми командами, однако интерес представляет только его изменение в командах сложения и вычитания: в командах сложения (АРР, АРС, 1ЧС) флаг АР получает значение 1, если при сложении 4 младших битов операндов получилась сумма больше 15 (если есть перенос из этих битов в более старшие биты), а в командах вычитания (З()В, ЗВВ, РЕС) флаг АР равен 1, если величина 4 младших битов первого операнда меньше величины таких же битов второго операнда (если был заем единицы для младших битов первого операнда).
Так вот, по фва(у АР команда ААА и распознает случай, когда сумма, полученная в предыдущей команде, больше 15. Итак, распознав, что сумма больше 9, команда ААА корректирует ее - добакэяет к ней б и обнуляет левую половину реп)стра А1., что, как уже отмечалось, соответствует получению "правильной" цифры результата. Отметим, что левая половина А1. обнуляется и в случае, когда сумма не превосходит 9, поэтому в регистре АЬ всегда остается только "правильная" цифра.
Что же касается увеличения на 1 значения реп(стра АН, то это можно рассматривать как еще один способ фиксирования переноса (если вначале в АН был О), но вообще-то такое изменение АН нужно для реализации умножения двоично-десятичных чисел (см. рвзд. 14.1.4). Сложение АБСП-чисел Несколько усложненное действие команды ААА обьясняется тем, что она ориентирована на сложение цифр не только неупакованных двоично-десятичных чисел, но и АЗСП-чисел. Например, если по команде АРР слозппь коды цифр 5 и 8, т. е.
коды 35Ь и 38Ь, то получим сумму бРЬ = 01101101Ь. Если после этого выполнить команду ААА, то она будет обращать внимание только на правую половину суммы, т. е. на величину 1101Ь (м13), которая и является насп)яшей суммой цифр (как чисел). Поскольку эта величина больше 9, то команда ААА фиксирует в флаге СР перенос и прибавляет б к А1. (6РЬ+би73Ь), после чего обнуляет левую половину этой суммы, получая "правильную" цифру 3. Осталось только обьединить ее с числом ЗОЬ, чтобы получить АЗСП-код этой цифры - ЗЗЬ.
Если значения описанных в последнем примере переменных Х, У и Е рассл(атривать как АЗСП-числа, тогда сложение Е(иХ+У можно реализовать следующим образом (замечание: посколы(у команда ОК портит флаг СР, то перенос в старшие цифры будем производить через реп(стр АН): )словенке аасхх чисел моч сх и меч ях,н-) моч ьв,э ввмь моч вь,х(вх) ацп ьь,т(вх) ыю ьь,ьв моч ьв,э вьх од аь,зэь (числовик строк)з я: Х+т )количество цифр в слагаемик (индекс цифр слагаемик (слрава ивлево) ;ЬВ - иеремос из младиик цифр (зиачале его иет] )слокеиие цифр с учетом иеремоса из млад.