- •Тема 2. Архітектура процесора і мова асемблера: Основи програмування на мові асемблера
- •1.1. Додавання двійкових чисел без знака
- •1.2. Додавання двійкових чисел зі знаком
- •1.3. Віднімання двійкових чисел без знака
- •1.4. Віднімання двійкових чисел зі знаком
- •1.5. Віднімання і додавання операндів великої розмірності
- •1.6. Множення чисел без знака
- •1.7. Множення чисел зі знаком
- •1.8. Ділення чисел без знака
- •1.9. Ділення чисел зі знаком
1.3. Віднімання двійкових чисел без знака
Як і при аналізі операції додавання, поміркуємо над суттю процесів, що відбуваються під час виконання операції віднімання. Коли зменшуване більше від’ємника, то проблем немає, - різниця додатна, результат вірний. Коли зменшуване менше від’ємника, виникає проблема: результат менше 0, а це вже числа зі знаком. У цьому випадку результат необхідно завернути. Що це означає? При звичайному відніманні (в стовпчик) роблять позику 1 зі старшого розряду. Мікропроцесор робить аналогічно, тобто займає 1 з розряду, наступного за старшим в розрядної сітці операнда. Пояснимо на прикладі.
Приклад
5.
Віднімання
чисел 1 05
= 00000000 00000101 10
= 00000000 00001010
1
00000000 00000101 – 00000000
00001010 11111111
11111011
Тим самим по суті виконується дія
(65 536 + 5) — 10 = 65 531,
0
Приклад
6.
Віднімання
чисел 2
5
= 00000000 00000101 (-10)
= 11111111 11110110
11111111 11111011
тут як би еквівалентний числу 65 536. Результат, звичайно, є помилковим, але мікропроцесор вважає, що все нормально, хоча факт позики одиниці він фіксує встановленням прапора переносу cf. Але подивіться ще раз уважно на результат операції віднімання. Це ж -5 в додатковому коді! Проведемо експеримент: уявимо різницю у вигляді суми 5 + (–10).
Ми отримали той самий результат, що і в попередньому прикладі.
Таким чином, після команди віднімання чисел без знака потрібно аналізувати стан прапора cf. Якщо він встановлений в 1, то це говорить про те, що сталася позика зі старшого розряду і результат вийшов в додатковому коді.
Аналогічно командам додавання, група команд віднімання складається з мінімально можливого набору. Ці команди виконують віднімання за алгоритмами, які ми зараз розглядаємо, а облік особливих ситуацій має проводитися самим програмістом. До команд віднімання відносяться наступні:
dec операнд — операція декременту, тобто зменшення значення операнду на 1;
sub операнд_1,операнд_2 — команда віднімання; її принцип дії: операнд_1 = операнд_1 – операнд_2
sbb операнд_1,операнд_2 — команда віднімання з врахуванням позики (прапора cf ): операнд_1 = операнд_1 – операнд_2 – значение_cf
Як бачите, серед команд віднімання є команда sbb, що враховує прапор переносу cf. Ця команда подібна adc, але тепер вже прапор cf виконує роль індикатора позики 1 зі старшого розряду при віднімання чисел.
Розглянемо приклад (лістинг 2) програмної обробки ситуації, розібраної в прикладі 6.
Лістинг 2. Перевірка при відніманні чисел без знаку <1> ;prg_9_2.asm <2> masm <3> model small <4> stack 256 <5> .data <6> .code ;сегмент коду <7> main: ;точка входу в програму <8> ... <9> xor ax,ax <10> mov al,5 <11> sub al,10 <12> jnc m1 ;немає переносу? <13> neg al ;в al модуль результату <14> m1: ... <15> exit: <16> mov ax,4c00h ;стандартний вихід <17> int 21h <18> end main ;кінець програми |
У цьому прикладі в рядку 11 виконується віднімання. Із зазначеними для цієї команди віднімання початковими даними результат виходить в додатковому коді (від’ємний). Для того щоб перетворити результат до нормального вигляду (отримати його модуль), застосовується команда neg, за допомогою якої виходить доповнення операнда. У нашому випадку ми отримали доповнення доповнення або модуль від’ємного результату. А той факт, що це насправді число від’ємне, відображений у стані прапора cf. Далі все залежить від алгоритму обробки. Дослідіть програму у відлагоджувальнику.