Описание системы команд (1110646), страница 5
Текст из файла (страница 5)
После команды daa следует анализировать состояние флага cf. Если онравен 1, то это говорит о том, что был перенос единицы в старший разряд и это нужноучесть для сложения старших десятичных цифр BCD-числа.moval,69hупакованное BCD-числоmovbl,74hупакованное BCD-числоadcal,bldaa;69h —;74h —;al=0ddh;cf=1, al=43h;если перенос, то переход на ту ветвьпрограммы,;где он будет учтен:jc m1См. также: урок 8, Приложение 7 и команды aaa, aad, aam, aas, dasDAS(Decimal Adjust for Subtraction)Десятичная коррекция после вычитанияdasСхема команды:Назначение: коррекция упакованного результата вычитания двух BCD-чисел вупакованном формате.СинтаксисАлгоритм работы:команда das работает только с регистром al и анализирует наличие следующих ситуаций:••Ситуация 1. В результате предыдущей команды сложения флаг af =1 или значениемладшей тетрады регистра al>9.
Напомним, что для случая вычитания флаг afустанавливается в 1 в случае заема двоичной единицы из старшей тетрады вмладшую тетраду регистра al. Наличие одного из этих двух признаков говорит отом, что значение младшей тетрады превысило 9h и его нужно корректировать.Ситуация 2. В результате предыдущей команды сложения флаг сf =1 или значениерегистра al>9fh. Напомним, что для случая вычитания флаг cf устанавливается в 1 вслучае заема двоичной единицы. Наличие одного из этих двух признаков говорит отом, что значение в регистре al превысило 9fh.Если имеет место одна из этих ситуаций, то регистр al корректируется следующимобразом:•••для ситуации 1 содержимое регистра al уменьшается на 6;для ситуации 2 содержимое регистра al уменьшается на 60h;если имеют место обе ситуации, то корректировка начинается с младшей тетрады.Состояние флагов после выполнения команды (в случае, если были переносы):11 07 06 04 02 00OF SF ZF AF PF CFrrr1r1Состояние флагов после выполнения команды (в случае, если переносов не было):11 07 06 04 02 00OF SF ZF AF PF CFrrr0r0Применение:Команду das следует применять после вычитания двух упакованных BCD-чисел с цельюкорректировки получающегося двоичного результата вычитания в правильное двузначноедесятичное число.
После команды das следует анализировать состояние флага cf. Если онравен 1, то это говорит о том, что был заем единицы в старший разряд и это нужно учестьв дальнейших действиях. Если у вычитаемого нет больше старших разрядов, то результатследует трактовать как отрицательное двоичное дополнение. Для определения егоабсолютного значения нужно вычесть 100 из результата в al. Если у вычитаемого еще естьстаршие разряды, то факт заема нужно просто учесть уменьшением младшего из этихоставшихся старших разрядов на единицу.movah,08h ;ah=08hmoval,05h ;al=05haddal,ah;al=al+ah=05h+08h=0dh — не BCD-числоxorah,ah;ah=0aaa;ah=01h,al=03h— результат скорректированСм.
также: урок 8, Приложение 7 и команды aaa, aad, aam, aas, daaDEC(DECrement operand by 1)Уменьшение операнда на единицуdec операндСхема команды:Назначение: уменьшение значения операнда в памяти или регистре на 1.СинтаксисАлгоритм работы:команда вычитает 1 из операнда. Состояние флагов после выполнения команды:11 07 06 04 02OF SF ZF AF PFrrrrrПрименение:Команда dec используется для уменьшения значения байта, слова, двойного слова впамяти или регистре на единицу. При этом заметьте то, что команда не воздействует нафлаг cf....moval,9decal;al=8См. также: урок 8 и команды inc, subDIV(DIVide unsigned)Деление беззнаковоеdiv делительСхема команды:Назначение: выполнение операции деления двух двоичных беззнаковых значений.СинтаксисАлгоритм работы:Для команды необходимо задание двух операндов — делимого и делителя.
Делимоезадается неявно и размер его зависит от размера делителя, который указывается вкоманде:•••если делитель размером в байт, то делимое должно быть расположено в регистреax. После операции частное помещается в al, а остаток — в ah;если делитель размером в слово, то делимое должно быть расположено в паререгистров dx:ax, причем младшая часть делимого находится в ax. После операциичастное помещается в ax, а остаток — в dx;если делитель размером в двойное слово, то делимое должно быть расположено впаре регистров edx:eax, причем младшая часть делимого находится в eax. Послеоперации частное помещается в eax, а остаток — в edx.Состояние флагов после выполнения команды:11 07 06 04 02 00OF SF ZF AF PF CF??????Применение:Команда выполняет целочисленное деление операндов с выдачей результата деления ввиде частного и остатка от деления.
При выполнении операции деления возможновозникновение исключительной ситуации: 0 — ошибка деления. Эта ситуация возникает водном из двух случаев: делитель равен 0 или частное слишком велико для его размещенияв регистре eax/ax/al.movmovdival=частноеax,10234bl,154bl;ah=остаток,См. также: урок 8, приложение 7 и команду idivENTER(setup parameter block for ENTERing procedure)Установка кадра стека для параметров процедурыenter loc_size,lex_levСхема команды:Назначение: установка границы в стеке для локальных переменных процедуры.СинтаксисАлгоритм работы:••поместить текущее значение регистра ebp/bp в стек;сохранить текущее значение esp/sp в промежуточной переменной fp (имяпеременной выбрано случайно);•••если лексический уровень вложенности (операнд lex_lev) не равен нулю, то(lex_lev–1) раз делать следующее:o в зависимости от установленного режима адресации use16 или use32выполнить вычитание (bp–2) или (ebp–4) и записать результат обратно вebp/bp;o сохранить значение ebp/bp в стеке;o сохранить в стеке значение промежуточной переменной fp;записать значение промежуточной переменной fp в регистр ebp/bp;уменьшить значение регистра esp/sp на величину, заданную первым операндом,минус размер области локальных переменных loc_size: esp/sp=(esp/sp)–loc_size.Состояние флагов после выполнения команды:выполнение команды не влияет на флагиПрименение:Команда enter специально введена в систему команд микропроцессора для поддержкиблочно-структурированных языков высокого уровня типа Pascal или С.
В этих языкахпрограмма разбивается на блоки. В блоках можно описать свои собственные (локальные)идентификаторы, которые не могут быть использованы вне этого блока. К примеру, нарисунке ниже в виде блоков изображена структура некоторой программы.Изображение структуры некоторой программы в виде блоковВ правом верхнем углу каждого блока (процедуры) стоит номер лексического уровнявложенности этого блока относительно других блоков программы. Большинство блочноструктурированных языков в качестве основного метода распределения памяти дляпеременных в блоках используют автоматическое распределение памяти. Это означает,что при входе в блок (вызове процедуры и т. п.) в некотором месте памяти (или в стеке)выделяется область памяти для переменных этого блока (ее можно назвать областьюинициализации).
После выхода из этого блока связь программы с этой областью теряется,то есть эти переменные становятся недоступными. Но если, как в нашем примере, в этойпроцедуре есть вложенные блоки (процедуры), то для некоторого внутреннего блока(например, C) могут быть доступны области инициализации (переменные) блоков,объемлющих данный блок. В нашем примере для блока C доступны также переменныеблоков B и A, но не D. Возникает вопрос: как же программа, находясь в конкретной точкесвоего выполнения, может отслеживать то, какие области инициализации ей доступны?Это делается с помощью структуры данных, называемой дисплеем.
Дисплей содержитуказатели на самую последнюю область текущего блока и на области инициализации всехблоков, объемлющих данный блок в программе. Например, если в программе A былавызвана сначала процедура B, а затем C, то дисплей содержит указатели на областиинициализации A, B и C (см. рисунок ниже).Если после этого вызвать процедуру D (в то время как B и C еще не завершены), токартина изменится.После того как некоторый блок (процедура) завершает свою работу, ее областьинициализации удаляется из памяти (стека) и одновременно соответствующим образомкорректируется дисплей.