Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lekz._10.doc
Скачиваний:
2
Добавлен:
05.05.2019
Размер:
142.85 Кб
Скачать

Системне програмування, доц. І.І. Мітасов, 2010р. Лекція 10, 8 сторінок

Тема 2. Архітектура процесора і мова асемблера: Основи програмування на мові асемблера

ЛЕКЦІЯ 10. Група арифметичних команд і даних

(продовження)

Питання лекції:

  • Команди перетворення типів;

  • Інші корисні команди ;

  • Арифметичні операції над двійково-десятковими числами

2. Команди перетворення типів

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

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

1. Команди без операндів - ці команди працюють з фіксованими регістрами:

  • cbw (Convert Byte to Word) - команда перетворення байт (в регістрі al) в слово (у регістрі ax) шляхом розповсюдження значення старшого біта al на всі біти регістра ah;

  • cwd (Convert Word to Double) — команда перетворення слова (у регістрі ax) в подвійне слово (в регістрах dx: ax) шляхом розповсюдження значення старшого біта ax на всі біти регістра dx;

  • cwde (Convert Word to Double) — команда перетворення слова (у регістрі ax) в подвійне слово (в регістрі eax) шляхом розповсюдження значення старшого біта ax на всі біти старшої половини регістра eax;

  • cdq (Convert Double Word to Quarter Word) — команда перетворення слова (у регістрі ax) в подвійне слово (в регістрі eax) шляхом розповсюдження значення старшого біта ax на всі біти старшої половини регістра eax;

2. Команди movsx і movzx, що відносяться до команд обробки рядків.Ці команди мають корисну властивість в контексті нашої проблеми:

  • movsx операнд_1,операнд_2 — переслати з розповсюдженням знака.Розширює 8 або 16-розрядне значення операнд_2, яке може бути регістром або операндом в пам'яті, до 16 або 32-розрядного значення в одному з регістрів, використовуючи значення знакового біта для заповнення старших позицій операнд_1.Цю команду зручно використовувати для підготовки операндів із знаками до виконання арифметичних дій;

  • movzx операнд_1,операнд_2 — переслати з розширенням, нулем. Розширює 8 або 16-розрядне значення операнд_2 до 16 або 32-розрядного з очищенням (заповненням) нулями старших позицій операнд_2. Цю команду зручно використовувати для підготовки операндів без знака до виконання арифметичних дій.

Наприклад, обчислимо значення y = (a + b) / c, де a, b, c - байтові знакові змінні (лістинг 5).

Лістинг 5. Обчислення простого виразу

<1> ;prg_10_1.asm

<2> masm

<3> model small

<4> stack 256

<5> .data

<6> a db ?

<7> b db ?

<8> c db ?

<9> y dw 0

<10> .code

<11> main: ;точка входу в програму

<12> ...

<13> xor ax,ax

<14> mov al,a

<15> cbw

<16> movsx bx,b

<17> add ax,bx

<18> idiv c ;в al — частка, в ah — залишок

<19> exit:

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

<21> int 21h

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

У цій програмі ділене для команди idiv (рядок 17) готується заздалегідь. Так як дільник має розмір байта, то ділене повинно бути словом.З урахуванням цього складання здійснюється паралельно з перетворенням розміру результату в слово (рядки 13-16). Для прикладу розширення операндів зі знаком здійснюється двома різними командами - cbw і movsx.

3. Інші корисні команди

xadd призначення, джерело - обмін місцями і додавання.

Команда дозволяє виконати послідовно дві дії:

• обміняти значення призначення і джерело;

• помістити на місце операнда призначення суму: призначення = призначення + джерело.

neg операнд — заперечення з доповненням до двох.

Команда виконує інвертування значення операнд. Фізично команда виконує одну дію: операнд = 0 - операнд, тобто віднімає операнд з нуля.

Команду neg операнд можна застосовувати:

• для зміни знака;

neg ax ; зміна знака (ax)

...

add ax,340 ; фактично віднімання: (ax)=340-(ax)

• для виконання віднімання з константи. Справа в тому, що команди sub і sbb не дозволяють відняти що-небудь з константи, так як константа не може служити операндом-приймачем в цих операціях. Тому дану операцію можна виконати за допомогою двох команд:

4. Арифметичні операції над двійково-десятковими числами

У цьому розділі ми розглянемо особливості кожного з чотирьох основних арифметичних дії для упакованих та неупакованих двійково-десяткових чисел:

1) додавання неупакованих ВСD-чисел;

2) віднімання неупакованих ВСD-чисел;

3) множення неупакованих ВСD-чисел;

4) ділення неупакованих ВСD-чисел;

5) додавання упакованих ВСD-чисел;

6) віднімання упакованих ВСD-чисел.

Справедливо може виникнути питання: а навіщо потрібні BCD-числа? Відповідь може бути наступна: BCD-числа потрібні в ділових програмах, тобто там, де числа мають бути великими і точними. Як ми вже переконалися на прикладі двійкових чисел, операції з такими числами досить проблематичні для мови асемблера. До недоліків використання двійкових чисел можна віднести наступні:

  • значення величин у форматі слова та подвійного слова мають обмежений діапазон. Якщо програма призначена для роботи в галузі фінансів, то обмеження суми в рублях величиною 65 536 (для слова) або навіть 4 294 967 296 (для подвійного слова) буде суттєво звужувати сферу її застосування;

  • наявність помилок округлення. Уявляєте собі програму, яка працює де-небудь в банку і не враховує величину залишку при діях з цілими двійковими числами та оперує при цьому мільярдами? Застосування чисел з плаваючою точкою не врятує - там існує та сама проблема округлення;

  • представлення великого об’єму результатів у символьному вигляді (ASCII-коді). Ділові програми не просто виконують обчислення; однією з цілей їх використання є оперативна видача інформації користувачеві. Для цього, природно, інформація має бути представленою в символьному вигляді. Переклад чисел з двійкового коду в ASCII-код, як ми вже бачили, вимагає певних обчислювальних витрат. Число з плаваючою точкою ще важче перевести в символьний вид. А ось якщо подивитися на шістнадцяткове подання неупакованої десяткової цифри і на відповідний їй символ в таблиці ASCII, то видно що вони відрізняються на величину 30h. Через цю величину перетворення в символьний вигляд і назад виходить набагато простіше і швидше.

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]