Команди десяткової арифметики

 

До цієї групи входять команди, що дозволяють працювати з десятковими числами, які можуть бути поданими у двох формах: як упаковані двійково-десяткові числа (BCD-формат), і як розпаковані двійково-десяткові числа (ASCII-формат). У кожному з форматів багаторозрядні десяткові числа представлено послідовностями байтів, з якими і працює МП. Основним робочим регістром в усіх командах десяткової арифметики є регістр AL. Слід зазначити, що команд, спеціально налаштованих на виконання операцій складання, віднімання, множення і ділення десяткових чисел немає, тому що розмірність таких чисел може бути довільною, крім того, виконання множення і ділення десяткових чисел є можливе лише в розпакованому форматі. Тому виконання арифметичних операцій виконується за допомогою команд двійкової арифметики, а потім проводиться корекція результату.

Корекція результату додавання десяткових чиселвиконується після виконання команди ADD або ADC. Як було показано раніше, неправильний результат може бути обумовлений двома причинами:

– у результаті додавання отримали тетраду, двійковий еквівалент якої є більший ніж 9;

– отримано перенесення до старшої тетради з вагою 16.

Корекція результату проводиться за результатами аналізу прапорців AF і CF регістра ознак, які визначаються вмістом регістра AL, в якому розміщено суму.

 

DАА (Decimal Adjust for Addition)– команда десяткової корекції додавання BCD-чисел, які подано в упакованому виді.

Операндів у команди немає, тому що вона працює лише з регістром AL. Алгоритм корекції результату виконання попередньої команди додавання виконується за таким алгоритмом:

- якщо прапорець AF = 1 або молодша тетрада регістра AL має значення, більше ніж 9, то до вмісту AL додається число 06;

- якщо прапорець CF = 1 або старша тетрада регістра AL має значення, більше ніж 9, то до вмісту AL додається число 60;

- якщо мають місце обидві попередні ситуації, то корекція починається з молодшого розряду.

Після виконання команди DАА необхідно перевіряти значення прапорця CF для його урахування при роботі зі старшими розрядами десяткових цифр числа.

 

AAA (Ascii Adjust for Addition)– команда десяткової корекції додавання BCD-чисел, які подано у розпакованому виді. Команда також працює лише з регістром AL. Алгоритм роботи:

- якщо молодша тетрада регістра AL є припустима і значення AF = 0, то необхідно обнулити старшу тетраду AL;

- якщо молодша тетрада регістра AL більша 9 або значення AF = 1, то необхідно додати 06 до вмісту регістра AL і додати 1 до вмісту регістра ;

- обнулити старшу тетраду регістра AL;

- установити прапорець CF у такий стан, в якому знаходиться AF.

 

Корекція результату віднімання десяткових чиселвиконується після виконання команди SUB або SBB. Корекція результату проводиться за результатами аналізу прапорців AF і CF регістра ознак, які визначаються вмістом регістра AL, в якому розміщено віднімання.

DAS (Decimal Adjust for Subtraction)– команда десяткової корекції після віднімання. Алгоритм роботи команди:

- якщо прапорець AF = 1 або молодша тетрада AL має вміст, більший ніж 9, то з вмісту AL віднімається 06;

- якщо CF = 1 або старша тетрада AL має вміст, більший ніж 9, то з вмісту AL віднімається 60.

 

AAS (Ascii Adjust after Subtraction)– команда десяткової корекції після віднімання BCD-чисел, які подано у розпакованому виді. Алгоритм роботи команди:

- якщо молодша тетрада регістра AL припустима і AF = 0, то обнулити старшу тетраду регістра AL;

- якщо вміст молодшої тетради регістра AL не є припустимий або AF = 1, то необхідно відняти число 06 із вмісту AL;

- обнулити старшу тетраду регістра AL;

- надати CF такий же самий стан як і CF.

 

Корекція результатів множеннявиконується командою

AAM (Ascii Adjust after Multiply) –команда корекції результату множення двох розпакованих BCD-чисел і перетворення результату у вигляді двійкового числа, меншого 63Н (99D), у його розпакований BCD-еквівалент.

Команда здійснює ділення вмісту регістра AL на десять (0АН) і завантажує частку у регістр АН, а залишок – у регістр AL. Стан прапорців SF, ZF, PF визначається вмістом AL, а стан прапорців OF AF CF не є визначений.

 

Корекція результатів діленняпроводиться до виконання ділення командою

AAD (Ascii Adjust before Division) –команда підготовки двох розпакованих BCD-чисел для ділення і перетворення двозначного розпакованого числа, меншого 63Н (99D), у двійковий еквівалент. Алгоритм роботи команди:

- вміст регістра АН множиться на 10D і додається до вмісту регістра AL;

- регістр АН обнулюється.

Виконується ділення числа у регістрі АХ за допомогою команди DIV.

 

До групи арифметичних команд також входять такі команди:

 

BSWAP (Byte SWAP)– команда перестановки байтів. Синтаксис команди

 

BSWAP src.

 

Операндом src (джерело) може бути лише 32-розрядний регістр загального призначення. Команда використовується для зміни порядку слідування байтів і переходу від однієї форми адресування до іншої (від форми «молодший байт за молодшою адресою» на звернену). Команда не змінює вміст регістра прапорців. Алгоритм роботи можливо пояснити за допомогою рис. 9.11.

 

 
 

 

 


Рисунок 9.11 – Алгоритм виконання команди BSWAP

 

XADD (eXchange and ADD)– обмін і додавання значень двох операндів. Команда має вигляд

 

XADD dst,src.

 

Операнд dst (приймач) може бути 8-, 16- або 32-розрядним регістром загального призначення або коміркою пам’яті з такою ж кількістю розрядів. Операнд src (джерело) може бути лише пам’яттю відповідної розмірності.

Команда виконується у три етапи:

– вміст операнда dst (приймач) копіюється в операнд src (джерело);

– виконується додавання вмісту операнда dst (приймач) до вмісту операнда src (джерело);

– сума завантажується в операнд dst (приймач). Команда змінює усі прапорці результату.

 

CMP (CoMPare operands)– команда для порівняння двох операндів. Команда має вигляд

 

CMP dst,src.

 

Операнд dst (приймач) розміщується у регістрі загального призначення або комірці пам’яті, а операнд src (джерело) також може бути вмістом регістра загального призначення або комірки пам’яті, але одночасно не можуть бути вмістом комірок пам’яті. Крім того, операндом src (джерело) може бути безпосереднє число.

Алгоритм виконання команди полягає у відніманні від вмісту операнда dst (приймач) вмісту операнда src (джерело). Результат не формується, лише установлюються ознаки результату, які можливо аналізувати і робити висновки про співвідношення операндів між собою.

 

Порівняння елементів рядків байтів, слів, подвійних слів відбувається в залежності від довжини елемента рядків за допомогою команд:

CMPS (CoMPare String)– команда для порівняння елементів двох рядків;

CMPSB (CoMPare String Byte)– команда для порівняння двох рядків байтів;

CMPSW (CoMPare String Word)– команда для порівняння двох рядків слів;

CMPSD (CoMPare String Double word operands)– команда для порівняння двох рядків подвійних слів.

Команда порівняння рядків має узагальнений вид

 

CMPS dst,src.

 

Команди CMPSB, CMPSW, CMPSD опереандів не мають.

Ці команди порівнюють елементи рядка-джерела довжиною байт, слово або подвійне слово, що знаходиться за адресою DS:SI з елементами рядка-приймача, адреса яких визначаються вмістом регістра ES:DI. Зміна регістрів, які визначають адреси оперендів не дозволена.

Алгоритм виконання команди полягає у відніманні від вмісту операнда dst (приймач) вмісту операнда src (джерело). Результат не формується, лише установлюються ознаки результату, які можливо аналізувати і робити висновки про співвідношення операндів між собою.

Після віднімання вміст регістрів SI і DI автоматично змінюється відповідно значення прапорця DF. Якщо прапорець DF дорівнює 0 (була виконана команда CLD), то вміст регістрів SI і DI збільшується, якщо DF має значення 1 (була виконана команда STD), то вміст регістрів SI і DI зменшується. Збільшення/зменшення відбувається на 1, якщо пересилається байт, на 2, якщо пересилається слово, і на 4, якщо пересилається подвійне слово.

Команді може передувати префікс REP, який примушує виконувати порівняння, до поки вміст регістра СХ не стане дорівнювати 0.

 


CMPXCHG (CoMPare and eXCHanGe) –команда для порівняння двох операндів і обміну даними між ними. Синтаксис команди

 

CMPXCHG dst,src.

 

Операнд dst (приймач) розміщується у регістрі загального призначення або комірці пам’яті, а операнд src (джерело) також може бути вмістом регістра загального призначення або комірки пам’яті, але одночасно не можуть бути вмістом комірок пам’яті.

Команда порівнює значення операндів, установлює значення прапорця ZF = 1, якщо операнди рівні або ZF = 0 в іншому випадку, після чого обмінює вміст операндів між собою.

 

SETcc (byte SET on condition)– команда установлення вмісту байта при виконанні певної умови. Команда має вигляд

 

SETcc src.

 

Операнд у цій команді 8-розрядний регістр або комірка пам’яті.

Команда виконує установлення вмісту операнда 01Н, якщо умова виконується, або у 00Н, якщо не виконується.

Значення модифікатора кода операції сс аналогічне значенню модифікатора команд умовних переходів, де вони будуть розглянуті.

 

Сканування елементів рядка байтів, слів, подвійних слів відбувається в залежності від довжини елемента рядка за допомогою команд:

SCAS (SCAn String)– команда для сканування елементів рядка;

SCASB (SCAn String Byte)– команда для сканування елементів рядка байтів;

SCASW (SCAn String Word)– команда для сканування елементів рядка слів;

SCASD (SCAn String Double word)– команда для сканування елементів рядка подвійних слів;

Команда сканування елементів рядка має узагальнений вид

 

SCAS dst.

 

Команди CMPSB, CMPSW, CMPSD опереандів не мають.

Алгоритм виконання команди полягає у відніманні елемента рядка –операнда dst (приймач), який адресується тільки регістром ES:DI, від вмісту акумулятора AL (байт), AX (слово), EAX (подвійне слово). Результат не формується, лише установлюються ознаки результату, які можливо аналізувати і робити висновки про співвідношення операндів між собою.

Після віднімання вміст регістра DI автоматично змінюється відповідно значення прапорця DF. Якщо прапорець DF дорівнює 0 (була виконана команда CLD), то вміст регістру DI збільшується, якщо DF має значення 1 (була виконана команда STD), то зменшується. Збільшення/зменшення відбувається на 1, якщо пересилається байт, на 2, якщо пересилається слово, і на 4, якщо пересилається подвійне слово.

Команді може передувати префікс REP, який примушує виконувати порівняння поки вміст регістра СХ не стане дорівнювати 0.

 

Команди логічних операцій

До цієї групи команд відносяться команди, які при роботі використовують правила алгебри логіки. До таких команд відносяться команди, яки виконують логічні операції над операндами, команди обробки біт і команди зсувів.

Логічні операції мови Асемблер-86:

AND (logical AND)– команда логічного множення операндів (кон’юнкція).

OR (logical OR)– команда логічного додавання операндів (диз’юнкція).

XOR (logical eXclusive OR) – логічне виключне АБО.

TEST (TEST operand)– логічне ТА. Використовується для логічного порівняння операндів.

NOT (NOT operand)– інвертування операнда.

Узагальнене представлення логічних команд має вигляд:

 

AND dst,src.

OR dst,src.

XOR dst,src.

TEST dst,src.

NOT src.

 

В усіх командах операндами можуть бути 8-, 16-, 32-розрядні регістри загального призначення і пам’ять з відповідною кількістю комірок. Операнд src (джерело) також може бути представлено безпосереднім числом (крім команди NOT).

Команди AND, OR, XOR, TEST змінюють прапорці таким чином:

OF і CF – завжди установлюються у нульовий стан;

SF, ZF, PF – установлюються відповідно до результату за тими самими правилами, що і для арифметичних операцій;

AF – не визначається.

 

Команди зсувівподіляються на арифметичні і логічні. Для логічних зсувів характерно, що біт, який виходить за межі регістра, втрачається, а на місце біта, який зсунувся, у регістр записується 0. При виконанні арифметичних зсувів праворуч знаковий біт не втрачається, а зберігається у сусідньому, тим самим зберігаючи знак числа.

Асемблер включає такі команди зсувів:

SHL (Shift logical Left) – зсунути логічно ліворуч;

SAL (Shift Arithmetic operand Left)– зсунути арифметично ліворуч;

SHR (Shift logical Right)– зсунути логічно праворуч;

SAR (Shift Arithmetic operand Right)– зсунути арифметично праворуч;

RCL (Rotate operand through Carry flag Left)– зсунути циклічно ліворуч через перенесення;

RCR (Rotate operand through Carry flag Right)– зсунути циклічно праворуч через перенесення;

ROL (Rotate operand Left) – зсунути циклічно ліворуч;

ROR (Rotate operand Right) – зсунути циклічно праворуч.

Пояснення алгоритму роботи і синтаксис кожної з команд зсувів подано у табл. 9.3.

У таблиці прийнято умовні позначення: opr – операнд (регістр або комірка пам’яті, вміст яких зсувається); cnt– кількість зсувів (може приймати значення 1 або задаватися вмістом регістра-лічильника CL).

 

Таблиця 9.3 – Команди зсувів

Мнемоніка та формат команди Опис виконання
SHL opr,cnt SAL opr,cnt SHR opr,cnt SAR opr,cnt RCL opr,cnt RCR opr,cnt ROL opr,cnt ROR opr,cnt  
 
 

 


opr

 

Контрольні питання:

1 Які команди додавання операндів у мові Асемблер Ви знаєте? Чим вони відрізняються одна від одної?

2 Чим різняться команди SUB і SBB? Поясніть на прикладі.

3 Як виконується команда DEC CX?

4 Як виконується команда MUL і в яких регістрах може розміщуватися операнд src (джерело) і операнд dst (приймач)?

5 Як виконується команда DIV і в яких регістрах може розміщуватися операнд src (джерело) і операнд dst (приймач)?

6 Для чого у командах ділення використовується команда CWD?

7 Для чого використовується команда СМР? Де розміщується результат виконання цієї команди?

8 Які команди логічних операцій Ви знаєте?

9 Який результат буде отримано при виконанні фрагмента програми:

MOV AX,AFH

SHL AX,1

10 Який результат буде отримано при виконанні фрагмента програми:

MOV AX,AFH

ROR AX,1

11 Який результат буде отримано при виконанні фрагмента програми:

MOV AX,AFH

RCL AX,1

 

Контрольні питання підвищеної складності:

1 Чому при виконанні арифметичних команд над двійково-десятковими числами виникає потреба у корекції результату?

2 Як виконується корекція результату при виконанні арифметичних команд над двійково-десятковими числами?

3 Які прапорці формуються при виконанні логічних операцій?

4 Які команди зсувів можливо використовувати як команди множення і ділення на 2?