Віднімання двійкових чисел зі знаком виконувати дещо складніше. Останній приклад показав те, що процесору нема чого мати два пристрої - додавання і віднімання. Досить наявності тільки одного - пристрою складання. Але для вирахування способом додавання чисел зі знаком обидва операнда (і зменшуване, і від'ємник) необхідно представляти в додатковому коді. Результат теж потрібно розглядати як значення в додатковому коді. Але тут виникають складнощі. Перш за все, вони пов'язані з тим, що старший біт операнда розглядається як знаковий. Розглянемо приклад віднімання 45 - (-127).
Перший варіант вирахування чисел зі знаком:
Судячи з знакової розряду, результат вийшов негативний, що, в свою чергу, говорить про те, що число потрібно розглядати як доповнення, рівне -44. Правильний результат повинен дорівнювати 172. Тут ми, як і в разі знакового складання, зустрілися з переповненням мантиси, коли значущий розряд числа змінив знаковий розряд операнда. Відстежити таку ситуацію можна по вмісту прапора переповнення OF. Його установка в 1 говорить про те, що результат вийшов за діапазон представлення знакових чисел (тобто змінився старший біт) для операнда даного розміру і програміст повинен передбачити дії щодо коригування результату.
Наступне віднімання чисел зі знаком виконаємо способом складання:
-45 - 45 - -45 + (-45) = -90.
Тут все нормально, прапор переповнення OF скинутий в 0, а 1 у знаковому розряді говорить про те, що значення результату - число в додатковому коді.
Віднімання і додавання операндов великої розмірності.
Якщо ви помітили, команди додавання і віднімання працюють з операндами фіксованою розмірності: 8, 16, 32 біта. А що робити, якщо потрібно скласти числа
більшої розмірності, наприклад 48 бітів, використовуючи 16-розрядні операнди?
Принцип вирахування чисел з діапазоном уявлення, що перевищує стандартні розрядні сітки операндів, той же, що і при додаванні, тобто використовується прапор перенесення CF. Потрібно тільки уявляти собі процес віднімання в стовпчик і правильно комбінувати команди процесора з командою SB В. Щоб написати досить цікаву програму, що моделює цей процес, необхідно залучити ті конструкції мови асемблера, які ми ще не обговорювали. Серед доданих до книги файлів в каталозі даної глави знаходяться вихідні тексти підпрограм, що реалізують чотири основних арифметичних дії для довічних операндів довільній размерності1. Не полінуйтеся уважно вивчити їх, так як вони є хорошою ілюстрацією до матеріалу, що вивчається в цій та наступних розділах. До цих прикладів можна буде звернутися в повній мірі після того, як будуть вивчені механізми процедур і макрокоманд (глави 14 і 15). Крім того, в [8] обговорюються питання програмування цілочисельних арифметичних операцій, але в розширеному контексті.
На завершення обговорення команд додавання і віднімання відзначимо, що крім прапорів CF і OF в регістрі EFLAGS є ще кілька прапорів, які можна використовувати з двійковими арифметичними командами. Мова йде про наступні прапорах:
ZF - прапор нуля, який встановлюється в 1, якщо результат операції дорівнює 0, і в 0, якщо результат не дорівнює 0;
SF - прапор знака, значення якого після арифметичних операцій (і не тільки) збігається зі значенням старшого біта результату, тобто з бітом 7,15 або 31 (таким чином, цей прапор можна використовувати для операцій над числами зі знаком).