Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторна робота № 3 МЗКІТ.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
123.15 Кб
Скачать

Лабораторна робота № 3 по дисципліні «Методи і засоби комп’ютерних інформаційних технологій»

«Вивчення арифметичних і логічних команд»

3.1. Мета роботи

Метою даної роботи є вивчення арифметичних і логічних команд мікропроцесора.

3.2 Арифметичні команди

Додавання двійкових чисел без знака. Мікропроцесор виконує додавання операндів за правилами додавання двійкових чисел. Проблем не виникає доти, поки значення результату не перевищує розмірності поля операнда. Наприклад, при додаванні операндів розміром у байт результат не повинен перевищувати число 255. Якщо це відбувається, то результат виявляється невірним. Приміром, виконаємо додавання: 254 + 5 = 259 у двійковому виді. 11111110 + 0000101 = 1 00000011. Результат вийшов за межі восьми біт і правильне його значення укладається в 9 біт, а в 8-бітовому полі операнда залишилося значення 3, що, звичайно, невірно. У мікропроцесорі цей результат додавання прогнозується й передбачені спеціальні засоби для фіксування подібних ситуацій і їх обробки. Так, для фіксування ситуації виходу за розрядну сітку результату, як у цьому випадку, призначений прапор переносу cf. Він розташовується в біті 0 регістру прапорів eflags/flags. Саме установкою цього прапора фіксується факт переносу одиниці зі старшого розряду операнда. Природно, що програміст повинен передбачати можливість такого результату операції додавання й засобу для коректування. Це припускає включення ділянок коду після операції додавання, у яких аналізується прапор cf. Аналіз цього прапора можна провести різними способами. Найпростіший і доступний - використовувати команду умовного переходу jcc. Ця команда в якості операнда має ім'я мітки в поточному сегменті коду.

Перехід на цю мітку здійснюється у випадку, якщо в результаті роботи попередньої команди прапор cf установився в 1.

1. У системі команд мікропроцесора є три команди двійкового додавання:

- inc операнд - операція інкременту, тобто збільшення значення операнда на 1;

- add операнд_1,операнд_2 - команда додавання із принципом дії: операнд_1 = операнд_1 + операнд_2

- adc операнд_1,операнд_2 - команда додавання з урахуванням прапора переносу cf: операнд_1 = операнд_1 + операнд_2 + значення_cf

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

Розглянемо приклад обчислення суми чисел:

<1> ;prg1

<2> masm

<3> model small

<4> stack 256

<5> .data

<6> a db 254

<7> .code ;сегмент коду

<8> main:

<9> mov ax,@data

<10> mov ds,ax

<11> ...

<12> xor ax,ax

<13> add al,17

<14> add al,a

<15> jnc m1;якщо немає переносу, то перейти

;на m1

<16> adc ah,0;в ax сума з урахуванням переносу

<17> m1: ...

<18> exit:

<19> mov ax,4c00h ;стандартний вихід

<20> int 21h

<21> end main ;кінець програми

У рядках 13-14 створена ситуація, коли результат додавання виходить за межі операнда. Ця можливість ураховується рядком 15, де команда jnc (хоча можна було обійтися й без неї) перевіряє стан прапора cf. Якщо він установлений в 1, то це ознака того, що результат операції вийшов більше по розміру, чому розмір операнда, і для його коректування необхідно виконати деякі дії. У цьому випадку ми просто вважаємося, що границі операнда розширюються до розміру AX, для чого враховуємо перенос у старший розряд командою ADC (рядок 15).

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

- прапор переносу cf, установка якого в 1 говорить про те, що відбувся вихід за межі розрядності операндів;

- команду adc, яка враховує можливість такого виходу (перенос із молодшого розряду).

Інший засіб - це реєстрація стану старшого (знакового) розряду операнда, яке здійснюється за допомогою прапора переповнення of у регістрі eflags (біт 11).

Додатково до прапора of при переносі зі старшого розряду встановлюється в 1 і прапор переносу cf. Тому що мікропроцесор не знає про існування чисел зі знаком і без знака, то вся відповідальність за правильність дій із числами, що вийшли, лягає на програміста. Проаналізувати прапори cf і of можна командами умовного переходу jc\jnc і jo\jno відповідно.

Що ж стосується команд додавання чисел зі знаком, то вони ті ж, що й для чисел без знака.

Вирахування двійкових чисел без знака. Як і при аналізі операції додавання, порозмірковуємо над суттю процесів, що відбуваються при виконанні операції вирахування. Якщо зменшуване більше від'ємника, то проблем ні, - різниця позитивна, результат вірний. Якщо зменшуване менше від'ємника, виникає проблема: результат менше 0, а це вже число зі знаком. У цьому випадку результат необхідно загорнути. Що це означає? При звичайному вирахуванні (у стовпчик) роблять позику 1 зі старшого розряду. Мікропроцесор надходить аналогічно, тобто займає 1 з розряду, що йде за старшим, у розрядній сітці операнда.

Таким чином, після команди вирахування чисел без знака потрібно аналізувати стан прапора cf. Якщо він установлений в 1, те це говорить про те, що відбулася позика зі старшого розряду й результат вийшов у додатковому коді.

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

- dec операнд - операція декремента, тобто зменшення значення операнда на 1;

- sub операнд_1,операнд_2 - команда вирахування; її принцип дії:

операнд_1 = операнд_1 - операнд_2

- sbb операнд_1,операнд_2 - команда вирахування з обліком заєма (прапора cf ): операнд_1 = операнд_1 - операнд_2 - значення_cf

Як бачите, серед команд вирахування є команда sbb, що враховує прапор переносу cf. Ця команда подібна adc, але тепер уже прапор cf виконує роль індикатору заєма 1 зі старшого розряду при вирахуванні чисел.

Розглянемо приклад програмної обробки ситуації:

<1> ;prg2

<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. Далі все залежить від алгоритму обробки.

Вирахування двійкових чисел зі знаком. Тут усі трохи складніше. Останній приклад показав те, що мікропроцесору нема чого мати два пристрої - додавання й вирахування. Досить наявності тільки одного - пристрою додавання. Але для вирахування способом додавання чисел зі знаком у додатковому коді необхідно представляти оба операнда - і зменшуване, і від'ємник. Результат теж потрібно розглядати як значення в додатковому коді. Але тут виникають складності. Насамперед, вони пов'язані з тим, що старший біт операнда розглядається як знаковий.

Відстежити ситуацію переповнення мантиси можна по вмісту прапора переповнення of. Його установка в 1 говорить про те, що результат вийшов за діапазон представлення знакових чисел ( тобто змінився старший біт) для операнда даного розміру, і програміст повинен передбачити дії по коректуванню результату.

Множення чисел без знака. Для множення чисел без

знака призначена команда

mul співмножник_1

Як бачите, у команді зазначений усього лише один операнд - співмножник. Другий операнд - співмножник_2 заданий неявно. Його місце розташування фіксоване й залежить від розміру співмножників. Враховуючи те, що в загальному випадку результат множення більше, ніж кожний з його співмножників, то його розмір і місце розташування повинні бути теж визначені однозначно. Варіанти розмірів співмножників і розміщення другого операнда й результату наведено в таблиці 4.

Таблиця 4. Розташування операндів і результату при множенні

З таблиці видне, що добуток складається із двох частин і залежно від розміру операндів розміщається у двох місцях - на місці співмножник_2 (молодша частина) і в додатковому регістрі ah, dx, edx (старша частина). Як же динамічно ( тобто під час виконання програми) довідатися, що результат досить малий і вмістився в одному регістрі або що він перевищив розмірність регістру, і старша частина виявилася в іншому регістрі? Для цього залучаються вже відомі нам по попередньому обговоренню прапори переносу cf і переповнення of:

- якщо старша частина результату нульова, те після операції добутку прапори cf = 0 і of = 0;

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

Множення чисел зі знаком. Для множення чисел зі знаком призначена команда