МІНІСТЕРСТВО ОБОРОНИ...

450

Transcript of МІНІСТЕРСТВО ОБОРОНИ...

Page 1: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості
Page 2: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ

НАЦІОНАЛЬНИЙ ТЕХНІЧНИЙ УНІВЕРСИТЕТ

“ХАРКІВСЬКИЙ ПОЛІТЕХНІЧНИЙ ІНСТИТУТ”

В.О. Кравець, О.М. Рисований

СИСТЕМНЕ

ПРОГРАМУВАННЯ

Програмування на мові асемблеру

Рекомендовано Міністерством освіти і науки України

як навчальний посібник для студентів

вищих навчальних закладів напрямку

6.0915 “Комп’ютерна інженерія”

Харків НТУ “ХПІ” 2007

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 3: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

ББК 018.1.32.973

К78

УДК 004.42

Рецензенти: І.О. Фурман, д-р техн. наук, проф., академік АН Вищої шко-

ли України, Харківський національний технічний універси-

тет сільського господарства;

В.І. Хаханов, д-р техн. наук, проф., Харківський державний

технічний університет радіоелектроніки;

І.І. Обод, д-р техн. наук, проф., Харківський університет

Повітряних Сил ім. Кожедуба.

Гриф надано Міністерством освіти і науки України, лист № 1.4/18-Г-

901 від 11.06.07

Кравець В.О.

К78 Системне програмування. Програмування на мові асемблеру. Навч

посібник / В.О. Кравець В.О., О.М. Рисований. – Х.: НТУ “ХПІ”, 2007.

– 448 с.

ISBN 966-593-593-547-6

Наведено подання інформації, архітектурні особливості

16-розрядного МП i8086, 32-розрядного МП PENTIUM, система базових команд МП х86, складання типових обчислювальних процедур у МПТ, організація виведення на екран, складні структури даних, підпрограми, зв’язок асемблеру з мовами високого рівня, робота з консоллю.

Призначено для студентів спеціальностей: 7.091501 “Комп’ютерні

системи та мережі”, 7.091502 “Системне програмування”, 7.091503

“Спеціалізовані комп’ютерні системи”, а також може бути корисне для

спеціалістів.

Іл. 63. Табл. 57. Бібліогр. 21 назв.

ББК 32.973

ISBN 966-593-593-547-6 © В.О. Кравець, О.М. Рисований, 2007

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 4: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

4

ЗМІСТ

ВСТУП ........................................................................................................ 8

1. ПОДАННЯ ІНФОРМАЦІЇ В ЗАСОБАХ МП-ТЕХНІКИ ............ 11

1.1. Системи числення ............................................................................ 11

1.2. Кодування чисел в МП ................................................................... 20

1.2.1. Прямий код ................................................................................ 21

1.2.2. Обернений код ............................................................................ 21

1.2.3. Додатковий код ........................................................................... 22

1.2.4. Виконання операцій алгебраїчного додавання

в машинах з фіксованою точкою ........................................................ 24

1.3. Формати даних ................................................................................. 27

1.4. Двійково-десяткові коди ................................................................. 37

1.5. Кодування символьної інформації ................................................. 39

1.6. Завдання для виконання .................................................................. 41

2. АРХІТЕКТУРНІ ОСОБЛИВОСТІ 16-РОЗРЯДНОГО

МП і8086 .................................................................................................... 43

2.1. Функціонування базового МП ........................................................ 43

2.1.1. Загальна характеристика 16-розрядного МП i8086 ................. 43

2.1.2. Структурна схема МП i8086 ...................................................... 46

2.2. Програмна модель 16-розрядного МП .......................................... 50

2.2.1. Регістри загального призначення .............................................. 50

2.2.2. Вказівні й індексні регістри ....................................................... 52

2.2.3. Покажчик інструкцій .................................................................. 53

2.2.4. Сегментні регістри ..................................................................... 54

2.2.5. Регістр прапорців ....................................................................... 55

2.2.6. Адресний простір пам’яті і введення-виведення .................... 57

2.3. Структурна схема МПС з використанням МП i8086 .................... 63

2.4. Способи адресації 16-розрядного МП та оптимізація програм ... 65

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 5: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

5

3. АРХІТЕКТУРНІ ОСОБЛИВОСТІ 32-РОЗРЯДНОГО МП

PENTIUM ................................................................................................. 73

3.1. Типи даних МП PENTIUM ............................................................ 73

3.2. Регістри МП PENTIUM ................................................................ 76

3.3. Організація пам’яті МП PENTIUM .............................................. 84

3.4. Способи адресації МП PENTIUM ................................................. 91

4. БАЗОВІ КОМАНДИ МП ПЛАТФОРМИ х86 ............................... 95

4.1. Команди пересилання даних .......................................................... 95

4.2. Арифметичні команди .................................................................. 105

4.3. Логічні команди ............................................................................. 112

4.4. Команди обробки бітів та байтів .................................................. 115

4.5. Команди передачі керування ........................................................ 118

4.6. Рядкові операції ............................................................................. 125

4.7. Інші команди .................................................................................. 129

4.8. Числа з рухомою крапкою ........................................................... 133

4.8.1. Типи даних FPU ....................................................................... 134

4.8.2. Регістри FPU ............................................................................. 136

4.8.3. Виключення FPU ...................................................................... 139

4.8.4. Команди пересилання даних FPU ........................................... 140

4.8.5. Базова арифметика FPU ........................................................... 142

4.8.6. Команди порівняння FPU ........................................................ 145

4.8.7. Трансцендентні операції FPU ................................................. 148

4.8.8. Константи FPU ......................................................................... 150

4.8.9. Команди керування FPU .......................................................... 151

5. ДИРЕКТИВИ І ОПЕРАНДИ АСЕМБЛЕРУ ................................ 155

5.1. Директиви асемблеру ......................................................................... 155

5.2. Операнди команд асемблеру ........................................................ 163

5.3. Структура програми на мові асемблеру ...................................... 165

6. СКЛАДАННЯ ТИПОВИХ ОБЧИСЛЮВАЛЬНИХ

ПРОЦЕДУР У МПТ ............................................................................. 167

Page 6: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

6

6.1. Етапи створення програми на мові Асемблеру ........................... 167

6.2. Файли .COM і .EXE ....................................................................... 169

6.3. Програмування в мнемокодах лінійних програм ........................ 175

6.4. Програмування в мнемокодах галузевих і циклічних програм .. 180

6.5. Завдання для самостійного закріплення матеріалу ..................... 194

6.6. Обмін даними із зовнішніми пристроями в МПС ....................... 195

6.6.1. Ознайомлення з середовищем програмування ...................... 195

6.6.2. Організація взаємодії з об’єктом керування ......................... 196

6.6.2.1. Моделювання процесу керування роботою світлофора .. 196

6.6.2.2. Моделювання роботи терморегулятора ............................ 201

6.6.2.3. Моделювання процесу управління роботою мотора ....... 203

6.6.2.4. Моделювання процесу керування роботою ліфта ............ 205

7. ОРГАНІЗАЦІЯ ВИВЕДЕННЯ НА ЕКРАН .................................. 209

7.1. Виведення на екран символьної інформації ................................ 209 7.2. Виведення на екран графічних зображень .................................. 216

7.2.1 Виведення на екран простих графічних зображень ................ 216 7.2.2. Підпрограми та їх використання при відображенні

графічної інформації .......................................................................... 219 7.3. Виведення на екран тексту засобами BIOS ................................. 224

8. СКЛАДНІ СТРУКТУРИ ДАНИХ .................................................. 230

8.1. Масиви ............................................................................................ 230

8.1.1. Загальні відомості про масиви ................................................ 230

8.1.2. Двовимірні масиви .................................................................... 246

8.1.3. Завдання для самостійного дослідження двовимірних

масивів ................................................................................................ 247

8.2. Рядки ............................................................................................... 249

8.2.1. Команди обробки рядків .......................................................... 249

8.2.2. Завдання для самостійного дослідження команд обробки

ланцюжків ........................................................................................... 266

8.3. Структури ....................................................................................... 267

8.4. Об’єднання ..................................................................................... 272

8.5. Записи ............................................................................................. 274

Page 7: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

7

9. ПІДПРОГРАМИ ............................................................................... 281

9.1. Прямий виклик підпрограм .......................................................... 281

9.2. Табличний виклик підпрограм ..................................................... 284

10. ЗВ’ЯЗОК АСЕМБЛЕРУ З МОВАМИ ВИСОКОГО РІВНЯ ... 291

10.1. Характеристика мов системного програмування ..................... 291

10.2. Загальні відомості ....................................................................... 291

10.3. Зв’язок Pascal-асемблер .............................................................. 294

10.4. Зв’язок С++ -асемблер ................................................................ 296

11. МОДУЛЬНЕ ПРОГРАМУВАННЯ І МАКРОЗАСОБИ МОВИ

АСЕМБЛЕРУ ........................................................................................ 316

11.1. Макроасемблер ........................................................................... 316

11.1.1. Стислі відомості про макроасемблер .................................. 316

11.1.2. Псевдооператори equ і = ....................................................... 317

11.1.3. Макрокоманди ....................................................................... 320

11.2. Макродирективи ........................................................................ 327

11.2.1. Директиви повторення .......................................................... 328

11.2.2. Директиви умовної компіляції ............................................. 330

11.2.3. Директиви генерації повідомлень про помилку ERRxx .... 337

11.2.4. Додаткове керування трансляцією ...................................... 340

11.2.5. Константні вирази в умовних директивах .......................... 340

11.3. Процедури мови асемблеру ...................................................... 341

11.3.1. Загальна схема зв’язку модулів на асемблері ..................... 341

11.3.2. Організація інтерфейсу з процедурою ................................ 345

11.3.2.1. Передача аргументів через регістри ............................... 345

11.3.2.2. Передача аргументів через загальну область пам’яті ... 347

11.3.2.3. Передача аргументів через стек ...................................... 349

11.3.2.4. Використання макродиректив extrn і public .................. 352

11.3.3. Повернення результату з процедури ................................... 353

12. РОБОТА З КОНСОЛЛЮ .............................................................. 358

12.1. Робота з консоллю в середовищі MS-DOS ............................. 358

12.1.1. Функції BIOS для роботи з консоллю ................................. 358

Page 8: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

8

12.1.1.1. Функції BIOS для роботи з клавіатурою

(переривання 16h) ............................................................................ 359

12.1.1.2. Функції BIOS для роботи з екраном (переривання 10h) 367

12.1.2. Функції MS-DOS для роботи з консоллю

(переривання 21h) .............................................................................. 373

12.1.2.1. Функції MS-DOS для введення даних із клавіатури ...... 374

12.1.2.2. Функції MS-DOS для виведення даних на екран ........... 379

12.2. Робота з консоллю в середовищі Windows ................................ 382

12.2.1. Асемблер у середовищі Windows .......................................... 382

12.2.2. Два підходи до забезпечення роботи

з консоллю в середовищі Win32 ....................................................... 385

12.2.3. Програма мінірисьного консольного додатка ...................... 387

12.3. Високорівневе консольне введення-виведення ......................... 389

12.3.1. Функції API для забезпечення високорівневого кон-

сольного введення-виведення ............................................................ 389

12.3.2. Приклад програми консольного введення-виведення ......... 392

12.3.3. Програма обробки подій ........................................................ 397

12.4. Низькорівневе консольне введення-виведення ......................... 404

12.4.1. Робота з мишкою в консолі ................................................... 404

12.4.2. Робота з клавіатурою консолі ................................................ 410

12.4.3. Вікно консолі й екранний буфер ........................................... 415

12.5. Аналіз функцій BIOS ................................................................... 420

ДОДАТКИ .............................................................................................. 427

Додаток 1. Система команд МП І8086 ................................................. 427

Додаток 2. Таблиці кодування символів .............................................. 437

Додаток 3. Варіанти задач ..................................................................... 441

ЛІТЕРАТУРА ......................................................................................... 446

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 9: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

9

ВСТУП

Незважаючи на бурхливий розвиток математичного забезпечення і

алгоритмічних мов високого рівня, інтерес до мови асемблеру для IBM

PC постійно зростає. Мова асемблеру допомагає розкрити всі секрети

апаратного і програмного забезпечення. Більшість програмістів працю-

ють з мовами високого рівня, де окремий оператор перетворюється в

безліч процесорних команд. Кожна команда мови асемблеру має взаємну

однозначну відповідність з машинними командами, що дає підставу

вважати її мовою низького рівня та відрізняє від таких мов високого рів-

ня, як Pascal, BASIC і C++, для яких характерна трансляція одного опе-

ратора в безліч машинних команд.

Найчастіше мова асемблеру використовується для безпосереднього

керування операційною системою або для прямого доступу до апарату-

ри. Також він необхідний при оптимізації критичних блоків у приклад-

них програмах з метою підвищення їх швидкодії.

Мова асемблеру існує для кожного типу процесорів або цілого сі-

мейства процесорів.

Асемблер – це програма, що перетворює початкові коди мови асе-

мблеру в машинні команди. Асемблер може створювати лістинг програ-

ми з номерами рядків, адресами пам’яті, початковими операторами і

таблицею перехресних посилань символів і змінних, використовуваних в

програмі. Спільно використовувана з асемблером програма-

завантажувач (linker) збирає окремі файли, створені асемблером, в єдину

виконувану програму. В блок базових програм входить також налаго-

джувач (debugger), що дозволяє програмісту трасувати виконувану про-

граму і перевіряти вміст пам’яті. Наведені в даній книзі програми запус-

катимуться або в операційній системі MS-DOS, або в режимі емуляції

MS-DOS у вікні Windows 95/NT/XP. Найбільш популярними асемблера-

ми для сімейства процесорів Intel є: MASM (Microsoft Assembler), TASM

(Borland Turbo Assembler) і ASM86.

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 10: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

10

В деяких випадках обслуговуючі програми (утиліти) неможливо

реалізувати на мовах високого рівня. Або, наприклад, необхідно реалізу-

вати безпосередній зв’язок з операційною системою. В комп’ютерних

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

Крім того, деяким програмам необхідне пряме з’єднання з принтером

або послідовним портом комп’ютера. Програми, написані на мові Visual

Basic, для підвищення швидкодії можуть викликати процедури DLL,

написані на мові асемблеру. Тобто мову асемблеру можна застосовувати

в багатьох ситуаціях, де необхідно створити економічний код і підви-

щити швидкість роботи програм.

Процедури на мові асемблеру можуть легко обходити перешкоди,

що виникають при написанні програм на мові високого рівня. Напри-

клад, Pascal не дозволяє приєднувати символьне значення до числової

змінної. Це правило даної мови, якого доводиться дотримуватися. Та

іноді виникають вагомі причини, щоб обійти це правило. Програміст

може знайти ці обхідні шляхи, але це неминуче ускладнить програму і

зробить її неможливою для інших систем. Мова ж асемблеру дозволяє

легко вирішувати подібні проблеми, але ціною за таку “свободу” може

стати необхідність обліку великої кількості деталей, які в мові високого

рівня обробляються автоматично.

Мова асемблеру вимагає особливої уваги до деталей. На зорі про-

грамування більшість прикладних програм були частково або повністю

написані на мові асемблеру, оскільки виходили невеликі виконавчі мо-

дулі, які займали мало місця в пам’яті і дозволяли досягти прийнятної

швидкості роботи на “повільних” комп’ютерах. З часом комп’ютери ста-

вали потужнішими, програми розросталися і ставали більш універсаль-

ними. Це зажадало застосування мов високого рівня, таких як С,

FORTRAN і COBOL, що сприяли створенню структурованих програм,

які полегшують їх написання і налагодження. На черговому етапі розви-

тку такі об’єктно-орієнтовані мови, як C++ і Java, стали необхідним ін-

струментом написання величезних програм.

Написати складну програму на асемблері дуже важко. Тому в осно-

вному мова асемблеру використовується при написанні окремих сегмен-

тів прикладних програм для підвищення швидкості роботи і прямого

доступу до устаткування. Мова асемблеру використовується і для напи-

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

пам’яті (PROM) окремих пристроїв.

C++ має унікальну здатність поєднання мовних структур високого

Page 11: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

11

рівня з низькорівневими деталями. Прямий доступ до апаратури в прин-

ципі можливий, але в результаті вийде нездійснена програма. Більшість

компіляторів C++ мають можливість створювати асемблерний код, з

яким може працювати програміст перед тим, як одержати виконуваний

код.

Програмісти часто використовують комбінацію C++ і мову асемб-

леру при розробці додатків для вбудованих систем. Вони пишуть підпро-

грами на мові асемблеру і викликають їх з програм, написаних на мовах

високого рівня. В деяких випадках такі підпрограми називають “інтер-

фейсними підпрограмами” (interface subroutines), оскільки вони забезпе-

чують взаємодію з устаткуванням комп’ютера. В комп’ютерних іграх,

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

туп до апаратних портів відеоадаптера і звукової плати для досягнення

високого рівня продуктивності.

Підпрограми на мові асемблеру, що викликаються операційною си-

стемою для роботи з окремими пристроями, називають “драйверами

пристроїв” (device drivers). Як правило, драйвери обслуговують всі при-

кладні програми. Наприклад, коли програмі необхідно рахувати блок

даних, операційна система викликає підпрограму драйвера.

При програмуванні на мові асемблеру необхідно добре уявляти

розподіл даних, інакше помилки неминучі. Мови високого рівня прихо-

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

специфіку окремих пристроїв і має менше обмежень.

Таким чином, перевагами мови асемблеру є:

висока ефективність;

швидкодія;

лаконічність програм для процесора;

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

машинними кодами;

можливість напряму керувати процесором.

Головним недоліком мови асемблеру є те, що написана для одного

типу комп’ютерів програма не може бути перекомпільована і використа-

на на інших типах комп’ютерів. Для кожного сімейства процесорів ви-

користовується своя мова асемблеру зі своїм синтаксисом. Це є наслід-

ком того, що мова асемблеру дуже близька машинним командам і архі-

тектурі процесора. Коли створювана програма повинна використовува-

тися на різних комп’ютерах, необхідно застосовувати мови високого

рівня, такі як C++ або Java.

Page 12: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

12

1. ПОДАННЯ ІНФОРМАЦІЇ В ЗАСОБАХ МП-ТЕХНІКИ

1.1. Системи числення

Система числення (number system) – це сукупність прийомів і пра-

вил найменування та позначення чисел, за допомогою яких можна вста-

новити взаємно однозначну відповідність між будь-яким числом і його

поданням у вигляді сукупності кінцевого ряду числових символів.

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

в ЕОМ, є числа, що подані в двійковій системі числення, а також алфаві-

тно-цифрові символи. Для кодування символів використовують спеціа-

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

двійкові коди, наприклад ASCII коди (американський стандартний код

для передавання інформації).

Тип системи числення визначається за її основою. На рис. 1.1 наве-

дено класифікацію систем числення.

Системи числення

Позиційні Непозиційні

З безпосереднім

поданням числа

(однорідні)

З кодованим

поданням числа

З основою р

2 8 10 16

1010 12 10 А

Двійково-десяткова

0001 0000

Унітарна

У залишкових кла-сах

Римська

Рис. 1.1. Класифікація систем числення

Х

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 13: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

13

До непозиційних систем числення належать: 1) римська;

2) унітарна; 3) система залишкових класів.

У римській системі числення використовують такі цифри: I = 1,

V = 5, Х = 10, L = 50, С = 100, D = 500, M = 1000. У цій системі число

2001 записують як ММІ. В унітарній системі число подають загальною

сукупністю однорідних об’єктів. У системі залишкових класів числа по-

дають остачами від ділення на прості числа. У цій системі всі операції

можна проводити окремо для цифр кожного розряду.

До позиційних систем числення відносять системи, в яких кожна

цифра займає певне положення (розряд або позицію) у ряду цифр, що зо-

бражують число. Щоб одержати значення числа, потрібно кожну цифру

розряду помножити на число, яке називається вагою розряду. Ваги окре-

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

дорівнює основі системи числення р. Наприклад, розряди десяткового

числа 1327,45 мають ваги: 103 = 1000; 102 = 100; 101 = 10; 100 = 1; 10–1’ =

0,1; 10–2 = 0,01.

Позиційні системи числення, в яких цифри всіх розрядів набувають

значень 0, 1, ... , p – 1, а основа р є однаковою для всіх розрядів, назива-

ються однорідними. Подання цілого числа X в однорідній позиційній сис-

темі числення з основою р має вигляд:

X = ∑ x(і)pn – 1 = x(1)pn – 1 + x(2)pn – 2 + … + x(n)p0.

Основою системи числення є цілі позитивні числа 2, 8, 16 або

будь-які похідні від них. Відповідно і системи числення є двійкові, вісі-

мкові, шістнадцяткові і т. ін.

Для будь-якої системи числення з основою b величина числа вира-

жається як

(Nb)P = (PnPn–1 ... Pi...P1P0 , P–1P–2 ... ),

де Pi – позиційна цифра – ціле число 0 Pi b – 1,

i = ...–2, –1, 0, 1, 2, ..., n.

Значимість позиційної цифри (Pi) визначається числом Pi, помно-

женим на позиційну вагу.

Вага визначається наступним чином

... b3 b2 b1 b0, b–1 b–2 ...

Наприклад, в десятковій системі числення число 237,58 подано як

2102 + 3101 + 7100 + 510–1 + 810–2.

Page 14: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

14

Десяткова система, або система з основою 10 (р = 10) оперує з 10

цифрами (від 0 до 9). У системах числення з основою більше 10 викори-

стовують десять цифр для молодших значень цифр розрядів і латинські

літери А, В, С ...– для старших.

Якщо необхідно позначити основу системи числення, то викорис-

товують числові індекси або латинські літери: для двійкового числа ін-

декс 2 або літеру В (Binary), для десяткового – індекс 10 або літеру D

(Decimal), для шістнадцяткового – індекс 16 або літеру Н (Hexadecimal).

Символ “,” називається комою (точкою) системи числення. Час-

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

тиною числа, справа – дробовою частиною.

ЕОМ може бути побудована на будь-якій системі числення. Проте

всі сучасні системи побудовані на двійковій системі, виходячи з переваг

технічної реалізації системи. Дійсно, значно легше розрізняти два стани

ніж десять.

Основою двійкової системи є цифра 2. Кома системи числення, та-

ким чином, буде двійковою комою. У системі можливі тільки дві цифри

– 0 та 1.

Вага розрядів зліва направо має послідовність, яка називається

таблицею ваги:

23 22 21 20, 2–1 2–2 2–3 ...

Ця таблиця використовується для переведення двійкових чисел в

більш звичну десяткову систему. Наприклад, десятковий еквівалент

двійкового числа 1010 переводиться так, як наведено на рис. 1.2.

Рис. 1.2. Переведення двійкового числа за таблицею ваги

Існують спеціальні терміни, що широко використовуються в обчис-

лювальній техніці – “біт”, “байт”, “слово”.

23 22 21 20 Таблиця ваги

1 0 1 0 Двійкове число

8 4 2 1 Вага розряду

01 = 0

12 = 2

04 = 0

18 = 8

= 10

Page 15: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

15

Біт (bit – двійковий знак) – один з двох знаків – “0” або ”1”, що

використовується в обчислювальній техніці для внутрішньомашинного

подання чисел, знаків і команд. Біт – найменша “порція” інформації або

пам’яті в будь-якій двійковій системі. Це також двійковий розряд. Роз-

ряд зліва називають старшим (має найбільшу вагу), справа – молод-

шим (має найменшу вагу).

Байт (byte) – частина машинного слова з восьми бітів.

Слово (machine word, computer word) – вектор бітів, що розпізнаєть-

ся апаратною частиною ЕОМ як єдине ціле. Це інформація, яка зберіга-

ється в одному регістрі або комірці пам`яті. При поданні десяткового

числа в двійкове ціла та дробова частини числа переводяться в двійко-

вий еквівалент окремо. Повне подання числа здійснюється шляхом

об`єднання обох частин і вказування місця для коми. Як правило, вико-

ристовують методи віднімання, ділення та множення.

Метод віднімання полягає в тому (рис. 1.3, 1.4), що від числа від-

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

ється одиниця у відповідний розряд числа, що формується.

Рис. 1.3. Метод віднімання для цілого числа

Ця процедура повторюється, поки десяткове число не зменшиться

до нуля. Якщо після попереднього віднімання наступного ступеня від

числа двійка не віднімається, то записуємо “0” (нуль).

0,5625

– 0,5

0,0625

– 0,0625

2-1

0

2-4

2–1 2–2 2–3 2–4 2–5

1 0 0 1 0

Дробова частина десяткового числа обчислюється, як (0,5625)10 = (10010)2

Рис. 1.4. Метод віднімання для дробового числа

25 24 23 22 21 20

1 1 1 1 1 0

20

62 -32

30 -16

25

24

22

(62)10 = (111110)2

14 -8

6 -4

23

2 -2

0

21

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 16: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

16

Метод ділення. Для переведення цілої частини десяткового числа в

двійковий еквівалент використовуємо ділення на два. У цьому разі, якщо

при діленні є залишок, пишемо “1”, якщо немає – пишемо “0”. Продов-

жуємо цей процес, поки в залишку не залишиться “0”. При цьому перет-

воренню десяткове число має вигляд, який наведено на рис. 1.5.

Метод множення полягає в послідовному множенні на два і вико-

ристовується при перетворенні десяткового дробового числа в двійковий

еквівалент (рис. 1.6).

При цьому, якщо перший результат менше одиниці, то старший

двійковий розряд еквівалента є 0, якщо більший – 1. Процедура повто-

рюється до досягнення потрібної точності.

Процедуру переведення дробової частини числа з однієї системи

числення в іншу ще можна проводити шляхом перемноження чисел у

стовпчик (рис. 1.7).

Задачі на переведення цілих чисел

Задача № 1. Подати число X = [967]10 в двійковій системі числення.

Розв’язання:

53 2

26 2

13 2

6 2

3 2

1

(55310 =

= (110101)2

1

0

1

0

1

1

Залишок

Рис. 1.5. Метод ділення

Перенос 0,5625 ×2 = 1,1250 1

0,1250 ×2 = 0,0250 0

0,0250 ×2 = 0,5 0

0,5 ×2 = 1,0 1

0,0 ×2 = 0 0

(0,5625)10 = (0,10010)2

Рис. 1.6. Метод множення

0, 0 0 1 1 0, 2

0, 4 2 х

2 х 0, 8 2 х 1, 6 2 х 1, 2

Рис. 1.7. Метод множення в стовпчик

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 17: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

17

967 2

966 483 2

1 482 241 2

1 240 120 2

1 120 60 2

0 60 30 2

0 30 15 2

0 14 7 2

1 6 3 2

1 2 1

1

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

залишку, одержуємо відповідь: X = [967]10 = [1111000111]2

Задача № 2. Подати число X = [11001101]2 у десятковій системі

числення.

Розв’язання:

11001101 = 1 27 + 1 26 + 0 25 + 0 24 + 1 23 + 1 22 + 0 21 + 1 20 =

= 128 + 64 +8 + 4 +1 = 205.

Відповідь. X = [11001101]2 = [205]10.

Задача № 3. Подати число X = [16278]10 у вісімковій системі чис-

лення.

Розв’язання:

16278 8

16272 2034 8

6 2032 254 8

2 248 31 8

6 24 3

7

Відповідь. X = [16278]10 = [37626]8

Задача № 4. Подати число X = [3416]8 у десятковій системі числен-

ня.

Розв’язання:

3416 = 3 83 + 4 82 + 1 81 + 6 80 = 3 512 + 4 64 + 1 8 + 6 1 =

= 1536 + 256 + 8 + 6 = 1806.

Відповідь. X = [3416]2 = [1806]10

Задача № 5. Представити число X = [110101001100000]2 у восьми-

річній системі числення.

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 18: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

18

Розв’язання: 110101001100000 = 110 101 001 100 000 = [65140]8 6 5 1 4 0

110 = 1 22 + 1 21 + 0 20 = 4 + 2 + 0 = 6

101 = 1 22 + 0 21 + 1 20 = 4 + 0 + 1 = 5

001 = 0 22 + 0 21 + 1 20 = 0 + 0 + 1 = 1

100 = 1 22 + 0 21 + 0 20 = 4 + 0 + 0 = 4

000 = 0 22 + 0 21 + 0 20 = 0 + 0 + 0 = 0

Відповідь. X = [3416]2 = [65140]8

Задача № 6. Подати число X = [31524]8 у двійковій системі числен-

ня.

Розв’язання: 315248 = 011 001 101 010 100 = [011001101010100]2

Звернути увагу на необхідність додавання зліва від нуля до трьох

розрядів.

Відповідь. X = [31524]8 = [011001101010100]2

Задача № 7. Подати число X = [1C8E]16 у десятковій системі чис-

лення.

Перед початком розв’язання задачі повторити відповідність шістна-

дцяткових і десяткових чисел.

Розв’язання: 1C8E = 1 * 163 + 12 * 162 + 8 * 161 + 14 * 160 =

= 1 * 4096 + 12 * 256 + 8 * 16 + 14 * 1 = 4096 + 3072 + 128 + 14 =

[7310]10.

Відповідь. X = [1C8E]16 = [7310]10.

Задача № 8. Подати число X = [26442]10 у шістнадцятковій системі

числення.

Розв’язання:

26442 16

26432 1652 16

А 1648 103 16

4 96 6

7

Відповідь. X = [26442]10 = [674А]16

Задача № 9. Подати число X = [01110110110100010101]2 в шістна-

дцятковій системі числення.

Розв’язання:

01110110110100010101 = 0111 0110 1101 0001 0101 = [76D15]16

7 6 D 1 5

0111 = 0 23 + 1 22 + 1 21 + 1 20 = 0 + 4 + 2 + 1 = 7

Page 19: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

19

0110 = 0 23 + 1 22 + 1 21 + 0 20 = 0 + 4 + 2 + 0 = 6

1101 = 1 23 + 1 22 + 0 21 + 1 20 = 8 + 4 + 0 + 1 = 13 (D)

0001 = 0 23 + 0 22 + 0 21 + 1 20 = 0 + 0 + 0 + 1 = 1

0101 = 0 23 + 1 22 + 0 21 + 1 20 = 0 + 4 + 0 + 1 = 5

Відповідь. X = [01110110110100010101]2 = [76D15]16

Задача № 10. Подати число X = [AF3]16 у двійковій системі числен-

ня.

Розв’язання: AF3 = 1010 1111 0011 = [101011110011]2

Відповідь. X = [AF3]16 = [101011110011]2

Задача № 11. Представити число X = [B438]16 у вісімковій системі

числення.

Розв’язання:

B438 = 1001 0100 0011 1000 = 001 001 010 000 111 000 = [112070]8

1 1 2 0 7 0

Переведення числа складається з двох етапів. На першому етапі

здійснюється переведення чисел з шістнадцяткової системи числення у

двійкову. На другому етапі з двійкової системи числення перегрупуван-

ням тетрад у тріади виконується переведення чисел у вісімкову систему

числення.

Відповідь. X = [B438]16 = [112070]8

Задача № 12. Подати число X = [7513]8 у шістнадцятковій системі

числення.

Розв’язання: 7513 = 111 101 001 011 = 1111 0100 1011 = [F4B]16

F 4 B

Переведення числа складається з двох етапів. На першому етапі

здійснюється переведення чисел з вісімкової системи числення у двійко-

ву. На другому етапі з двійкової системи числення перегрупуванням трі-

ад у тетради виконується переведення чисел у шістнадцяткову систему

числення

Задачі на переведення дрібних чисел

Задача № 13. Представити число X = [0,84]10 у двійковій системі

числення.

Для переведення правильного дробу з десяткової системи числення

у двійкову необхідно послідовно помножати дріб на 2. При цьому кож-

ного разу помножується на 2 не весь дріб, а тільки дробова частина про-

Page 20: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

20

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

них результатів, починаючи з першої.

Розв’язання:

Відповідь. X = [0,84]10 = [0,1101]2.

Задача № 14. Подати число X = [0,101101]2 у десятковій системі чи-

слення.

Розв’язання: 0,101101 = 1 2-1 + 0 2-2 + 1 2-3 + 1 2-4 + 0 2-5 + 1 2-6 =

= 0,5 + 0,125 + 0,0625 + 0,015625 = [0,703125]10

Відповідь. X = [0,101101]2 = [0,703125]10

Задача № 15. Подати число X = [0,326]10 у вісімковій системі чис-

лення.

Для переведення правильного дробу з десяткової системи числення

у вісімкову необхідно послідовно помножати дріб на 8. При цьому кож-

ного разу помножується на 8 не весь дріб, а тільки дробова частина про-

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

них результатів, починаючи з першої.

Розв’язання:

Відповідь. X = [0,326]10 = [0,2467]8.

Задача № 16. Подати число X = [0,874]10 в шістнадцятковій системі

числення.

Для переведення правильного дробу з десяткової системи числення

в шістнадцяткову необхідно послідовно помножати дріб на 16. При цьо-

0, 84

2

1 68

2

1 36

2

0 72

2

1 44

0, 326

8

2 608

8

4 864

8

6 912

8

7 296

Page 21: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

21

му кожного разу помножується на 16 не весь дріб, а тільки дробова час-

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

проміжних результатів, починаючи з першої.

Розв’язання:

Відповідь. X = [0,874]10 = [0,DFBE]16.

1.2. Кодування чисел у МП

У МП арифметичні операції виконуються не над числами, а над їх

кодами. Застосування кодів полегшує визначення знака результату опе-

рації, вироблення ознаки переповнення розрядної сітки та дозволяє звес-

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

зглянуті раніше арифметичні операції додавання, віднімання, множення

та ділення, як неважко було помітити, містять операції зсуву, додавання

та віднімання. Отже, якщо операцію віднімання замінити операцією ал-

гебраїчного додавання, причому віднімання повинно бути подано в пев-

ному коді, то будь-яка арифметична операція може бути виконана за

допомогою тільки двох операцій: додавання та зсуву. В результаті цьо-

го спрощуються пристрої, що виконують ці операції.

Будь-яка інформація (числа, команди, текстова інформація) пода-

ється в МП у вигляді двiйкових кодів (двiйкових слів) фіксованої або

змінної довжини. Окремі елементи двiйкового коду, в яких є значення 0

або 1, мають назву розрядів або бітів.

Старший розряд сітки є знаковим. Для подання знака двійкових чи-

сел у МП використовують додатковий розряд. Значення “+” та “–“ відо-

бражають 0 та 1 відповідно.

Залежно від способу обробки бітів, розміщених у розрядній сітці,

розрізняють два види кодів: паралельний, якщо в кожний момент часу

всі розряди сітки доступні для обробки, і послідовний, якщо в кожний

0, 874

16

13(D) 984

16

15(F) 744

16

11(B) 904

16

14(E) 464

Page 22: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

22

момент часу доступний один розряд сітки. Числа, подані паралельним

кодом, доступні за один такт, а числа, подані послідовним кодом, – за п

тактів, де п — розрядність сітки. Якщо розрядність числа перевищує дов-

жину сітки, то його обробка здійснюється частинами.

Для подання цілих знакових чисел використовують такі коди: пря-

мий, обернений та додатковий.

1.2.1. Прямий код

Якщо цифрова частина коду містить модуль числа незалежно від

знака, то код числа називається прямим. Наприклад, для А = +0.011010

прямий код дорівнює Апр = 0.011010, а для – А = – 0.101101,

Апр = 1.101101.

Знаковий розряд у коді прийнято відділяти точкою.

Одиницю знакового розряду можна умовно прийняти за одну цілу.

Тоді в загальному випадку для прямого коду дробового числа А можна

отримати наступні співвідношення:

Подання від’ємного числа у прямому коді здійснюється так: у старшо-

му знаковому розряді розміщається одиниця, а в інших розрядах – модуль

числа.

Переваги прямого коду:

звичайний запис числа;

простота технічного рішення.

Недоліки прямого коду:

для віднімання чисел необхідно використовувати відраховувач;

присутня неоднозначність нуля.

1.2.2. Обернений код

Подання від’ємного числа в оберненому коді здійснюється обчис-

ленням числа, яке доповнює додатне число з тим самим модулем до

найбільшого беззнакового числа, яке може бути розміщене в даній роз-

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

Апр =

|А| , якщо А ≥ 0;

1 + |А| , якщо А ≤ 0.

Page 23: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

23

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

Оскільки 102 – 102– n = 1.11 … 1, для отримання коду за числом до-

статньо створити тільки розрядне обернення числа.

Наприклад, якщо А = – 0.110100 (n = 6), то 10 – 10–6 = 1.111111, і

для Аоб одержуємо Аоб = 1.111111 – 0.110100 = 1.001011.

Тобто одержуємо

|А| = 10 – 10 – n – [А]об.

Отже, перехід від оберненого коду до числа або прямого коду вико-

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

якщо Aоб = 1.110010, то Апр = 1.001101.

Недоліки оберненого коду:

присутня неоднозначність нуля;

при виникненні одиниці переносу зі знакового розряду необхід-

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

шення часу виконання операції.

1.2.3. Додатковий код

Додатковий код визначається співвідношенням

Утворення додаткового коду від’ємного двійкового числа відніман-

ням його абсолютного значення з 102 є неприйнятним (коди вводимо для

заміни віднімання додаванням).

Знайдемо інший, більш зручний спосіб. Нехай А = – 0.110100. Тоді

одержуємо Адод = 10 – 0.110100 = 1.001100.

Подамо число 102 так:

102 = 1.111111 + 0.000001.

Тоді для Адод отримаємо:

Адод = 1.111111 – 0.110100 + 0.000001 = 1.001011 + 0.00001.

Аоб =

|А| , якщо А ≥ 0;

102 – 102– n + А = 102 – 102

– n – |А| , якщо А ≤ 0.

Адод =

А = |А| , якщо А ≥ 0;

102 + |А| = 102 – |А| , якщо А < 0.

Page 24: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

24

Порівнявши перший доданок отриманої суми з числом А, відзнача-

ємо, що воно може бути знайдене безпосередньо за числом А операцією

звернення коду, тобто це є обернений код числа А. Тепер залишається до

отриманого після звертання числа додати одиницю молодшого розряду.

Додатні числа подають однаково у всіх трьох кодах.

Правило утворення додаткового коду від’ємного двійкового чис-

ла: необхідно виробити звернення всіх розрядів числа, включаючи і роз-

ряд знака, і до отриманого коду додати одиницю молодшого розряду.

Наприклад:

А = – 0,01101 А = – 0,00000

1,10010 1,11111

+ 0,00001 + 0,00001 __________ __________

Адод = 1.10011 Адод = 10.00000

У ланому прикладі сума дорівнює 102, а в межах розрядної сітки во-

на дорівнює 0, тому що 1 перенесення виходить за розрядну сітку. Отже,

0 в додатковому коді незалежно від знака має одне зображення.

Зауважимо, що в оберненому коді 0 має два зображення: + 0 0.0000;

– 0 1.1111. Ця обставина вигідно відрізняє додатковий код від обер-

неного.

Розглянемо такий приклад. Нехай А = – 0.0101000, утворимо з нього

додатковий код:

1.1010111

+ 0.0000001

Адод = 1.1011000 .

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

утворення додаткового коду.

Для утворення додаткового коду від’ємного числа необхідно всі

цифри числа, починаючи з молодшого розряду до першого значущого

включно, залишити без змін, а значення всіх інших розрядів замінити

на протилежні.

Обернене перетворення, тобто отримання числа або прямого коду з

додаткового, здійснюється за правилами, які випливають зі співвідно-

шення для Адод.

Page 25: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

25

Оскільки Адод = 10 – А , для числа А одержуємо А = 10 – Адод.

Якщо, наприклад, Адод = 1.10011, то Апр = 1.01101 і А = – 0.01101.

Можна використати інший підхід: з додаткового коду утворити обе-

рнений, а вже з оберненого шляхом обернення розрядів отримати число

або прямий код.

Наприклад:

Адод = 1.10011,. Аоб = Адод – 0.00001 = 1.10010 Апр = 1.01101.

1.2.4. Виконання операцій алгебраїчного додавання

в машинах з фіксованою точкою

При додаванні чисел, поданих додатковим або оберненим кодами,

сума повинна бути одержана також у додатковому або оберненому коді.

З’ясуємо правила складання на прикладах додавання двох чисел: А і В у

додатковому та оберненому кодах при всіх можливих поєднаннях знаків

доданків. Одразу введемо обмеження, що А + В < 1, тобто не відбува-

ється переповнення розрядної сітки.

Випадок 1. А > 0; B > 0;

Адод = Аоб = А; Вдод = Воб = В.

В результаті додавання кодів одержуємо

Адод + Вдод= Аоб + Воб = А + В.

Оскільки за умовою (А + В) > 0, то (А + В)дод = (А + В)об = А + В.

Отже, сума як додаткових, так і обернених кодів в цьому випадку

відразу дає додатковий (обернений) код суми.

Наприклад:

А = 0,10011 Адод = 0.10011 Аоб = 0.10011

+ + +

В = 0,01010 Вдод = 0.01010 Воб = 0.01010

А + В = 0,11101 Адод + Вдод = 0.11101 Аоб + Воб = 0.11101

Випадок 2. А > 0; В < 0;

Адод = Аоб = А; Вдод = 10 + В;

Воб = 10 – 10–n;

Адод + Вдод = 10 + (А + В);

Аоб + Воб = 10 – 10–n + (А + В).

У цьому випадку (як і у випадку А < 0; В > 0) існує три варіанти:

Page 26: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

26

(А + В) > 0; (А + В) < 0 і (А + В) = 0. То ж зупинимося на кожному з

них.

Випадок 2,а. (А + В) > 0.

Оскільки (А + В) > 0 , то (А + В)дод = (А + В)об = А + В, а в сумі

одержано 10 + (А + В) для додаткових кодів і 10 – 10– n + (А + В) – для

обернених.

Отже, для отримання правильного результату число 10 з суми дода-

ткових кодів та число 10 – 10– n з суми обернених кодів необхідно від-

няти (відкинути), а залишити тільки А + В. Звідси для випадку, що роз-

глядається, одержимо:

(А + В)дод = Адод + Вдод – 10;

(А + В)об = Аоб + Воб – 10 – 10– n .

Віднімання числа 10 від суми додаткових кодів здійснюється шля-

хом відкидання перенесенням зі знакового розряду, що в цьому випадку

обов’язково виникає, оскільки при (А + В) > 0 сума одержується більше

двох.

Для корекції суми обернених кодів необхідно від суми кодів відня-

ти (відкинути) число 10, а в молодший розряд додати 1. З цією метою

перенесення зі знакового розряду при додаванні обернених кодів не від-

кидається, а передається в молодший розряд отриманої суми та підсумо-

вується з нею. Така операція називається циклічним перенесенням.

Наприклад: А = 0,10011 Адод = 0.10011 Аоб = 0.10011

+ + +

В = 0,01010 Вдод = 1.10110 Воб = 1.10101

А + В = 0,01001 Адод + Вдод = 1 0.01001 Аоб + Воб = 1 0.11101

+ 1

(А + В)дод = 0.01001 (А + В)об = 0.01001

Випадок 2,б. (А + В) < 0.

При (А + В) < 0 (А + В)дод = 10 – (А + В),

а (А + В)об = 10 – 10– n + (А + В).

Отже, в цьому випадку результатом додавання кодів є додатковий

(обернений) код суми і жодної корекції не вимагається.

Однак, оскільки сума одержується від’ємною, необхідно перетвори-

ти її на прямий код.

Наприклад:

Page 27: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

27

А = 0,01010 Адод = 0,01010 Аоб = 0,01010

+ + +

В = 0,01011 Вдод = 1.01101 Воб = 1.01100

А + В = – 0,01001 Адод + Вдод = 1.10111 Аоб + Воб = 1.10110

(А + В)дод = 1.10111 (А + В)об = 1.10110

(А + В)пр = 1.01001 (А + В)пр = 1.01001

Випадок 2,в. (А + В) = 0.

При (А + В) = 0 (А + В)дод = 10, а (А + В) = 10 – 10–n.

Поява числа 10 у сумі додаткових кодів означає наявність перене-

сення зі знакового розряду, що відкидається і в сумі кодів залишається 0.

У сумі обернених кодів одержують число менше двох. Отже, тут

перенесення зі знакового розряду не виникає і корекція суми не відбува-

ється. Нуль наводять числом 10 – 10– n = 1.11…1.

Наприклад: А = + 0,10100 Адод = 0.10100 Аоб = 0.10100

+ + +

В = – 0,10100 Вдод = 1.01100 Воб = 1.01011

А + В = 0,000000 Адод + Вдод = 10.00000 Аоб + Воб = 1.11111

(А + В)дод = 0.00000 (А + В)об = 1.11111

Таким чином, в додатковому коді 0 має одне зображення, а в обер-

неному коді – два зображення.

Випадок 3. А < 0; В < 0.

Адод = 10 + А; Вдод = 10 + В; Аоб = 10 – 10–n + А; Воб = 10 – 10– n + В;

Адод + Вдод = 10 + 10 + (А + В);

Аоб + Воб = 10 – 10– n + 10 – 10– n + (А + В).

Оскільки (А + В) < 0, то

(А + В)дод = 10 + (А + В),

(А + В)об = 10 – 10– n + (А + В).

Тут, як і у випадку 2,а, необхідно суму кодів корегувати шляхом

відкидання перенесення із знакового розряду в сумі додаткових кодів та

реалізації перенесення в сумі обернених кодів.

Приклад. А = – 0,10011 Адод = 1.01101 Аоб = 1.01100

+ + +

В = – 0,01010 Вдод = 1.10110 Воб = 1.10101

А + В = – 0,11101 Адод + Вдод = 11.00011 Аоб + Воб= 11.00001

+ 1

(А + В)дод = 1.10111 (А + В)об= 1.00010

(А + В)пр = 1.01001 (А + В)пр= 1.11101

Page 28: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

28

Виявляється наступна закономірність. Якщо при додаванні кодів

перенесення зі знакового розряду не виникає, то суму відразу одержують

у відповідному коді. Якщо ж перенесення зі знакового розряду виникає,

то в додатковому коді це перенесення відкидається, а в оберненому коді

передається в молодший розряд суми. Реалізується операція циклічного

переносу.

При переповненні розрядної сітки (¦А + В¦ > 1) результат отримують

як за величиною, так і за знаком, оскільки ціла частина суми А + В пот-

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

як знак числа. Для виявлення випадків переповнення розрядної сітки зі

збереженням знака суми використовуються модифіковані додатковий та

обернений коди.

1.3. Формати даних

Будь-яка інформація (числа, команди, текстова інформація) пода-

ється в ПК у вигляді двiйкових кодів (двiйкових слів) фіксованої або

змінної довжини. Окремі елементи двiйкового коду зі значеннями 0 або

1 мають назву розрядів або бітів.

Двійковий розряд подається в ЕОМ різноманітними технічними

пристроями, наприклад тригером, двом окремим станам якого надають

значення 0 або 1. Різноманітні коди чисел використовують для компакт-

ного подання чисел в МП (табл. 1.1).

Набір відповідної кількості таких пристроїв служить для подання

багаторозрядного двiйкового числа (слова).

Існують три форми подання чисел:

природна;

з фіксованою крапкою (комою);

з плаваючою крапкою (комою).

Природна форма подання числа є записом числа у вигляді поліно-

ма, поданого у скороченому вигляді:

X = Р(x) = anxn + a n – 1xn – 1 +… + a0 , a–1x–1 + a– 2x– 2 + … + a

–(n – 1)x– (n – 1)

При цьому підрахунок ваги розрядів ведеться від точки. У природ-

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

цілою i дробовою частинами числа. У цьому вигляді подання для кожно-

го числа необхідно вказати положення точки, що пов’язане з додаткови-

ми витратами на устаткування. До недоліків такого подання необхідно

Page 29: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

29

також віднести: ускладнення обладнання для обробки таких чисел; труд-

нощі оперування з дуже великими або дуже малими за абсолютною ве-

личиною числами.

Таблиця 1.1

Подання чисел у різних системах числення Десяткове число

Двійкове число

Вісімкове число

Шістнадцяткове число

0 1 2 3 4 5 6 7 8 9

10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

256

4096 65536

0 1

01 11

100 101 110 111

1000 1001 1010 1011 1100 1101 1110 1111

10000 10001 10010 10011 10100 10101 10110 10111 11000 11001 11010

100000000

1000000000000 100000000000000000

0 1 2 3 4 5 6 7

10 11 12 13 14 15 16 17 20 21 22 23 24 25 26 27 30 31 32

400

10000 200000

0 1 2 3 4 5 6 7 8 9 A B C D E F

10 11 12 13 14 15 16 17 18 19 1A

100

1000 10000

Цю форму застосовують лише в калькуляторах, незважаючи на зви-

чність подання чисел.

У більшості ЕОМ використовують дві форми подання чисел:

з фіксованою крапкою (ФК) (комою);

з плаваючою крапкою (ПК) (комою).

Причому в ЕОМ повинні використовуватись обидва способи подан-

ня інформації.

Page 30: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

30

Форма з фіксованою крапкою використовується для подання цілих

чисел (крапка зафіксована після молодшого розряду). На рис. 1.8 пока-

зані приклади форматів даних для подання двійкових чисел з фіксова-

ною крапкою і відповідні розрядні сітки із вказанням розрядів.

Використовують два варіанти подання цілих чисел:

зі знаком;

без знака.

У варіанті подання цілих чисел без знака всі розряди розрядної сіт-

ки служать для подання модуля числа. У першому варіанті у форматі

даних для знака виділяється старший розряд. У цьому розряді 0 відпові-

дає плюсу, а 1 – мінусу. В n-розрядній сітці цілих чисел зі знаком 0 його

можна подати як додатним, так і від’ємним цілим двійковим числом. В

МП застосовуються формат подання двійкових чисел з фіксованою кра-

пкою, а подання чисел з плаваючою крапкою знайшло застосування в

арифметичних співпроцесорах. Останні ще називають процесорами з

ПК.

Для розміщення двійкового числа, що містить цілу і дробову части-

ни (без урахування знака) в n-розрядній сітці k комірок виділяють для

розміщення цілої частини та n – k комірок – для розміщення дробової

частини. При такому поданні двійкових чисел положення крапки в роз-

рядній сітці фіксовано. Якщо кількість розрядів у дробовій частині пере-

вищує n – k, то молодші розряди, що знаходяться за межами розрядної

сітки, не сприймаються МП. Будь-яке двійкове число, менше ніж 2 –(n – k),

сприймається як нульове і називається машинним нулем. У результаті

відкидання молодших розрядів дробової частини числа, розташованої за

межами розрядної сітки, виникає похибка подання. Максимальне зна-

Рис. 1.8. Формати даних для двійкових чисел з фіксованою крапкою:

а) крапка перед старшим розрядом; б) крапка після молодшого розряду

а)

Знак

20 2-1 2-2 2–(n – 2) 2 –(n – 1)

0, 1 2 .. . n – 2 n – 1

0,0. . . 01 X 0,1. . . 1

2–(n – 1) X 1 – 2–(n – 1)

1 – 0,0. . .01 = 1 – 2 –(n – 1)

б)

2n-1 2n-2 2n-3

Знак

21 20

n – 1 n – 2 n – 3 . . . 1 0,

1 |X| 2n – 1 – 1

Page 31: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

31

чення абсолютної похибки подання Δ1 не перевищує одиниці молодшого

розряду сітки:

Δ1 =2 – (n – k).

З такою формою подання чисел мінімальне число m = 2 – (n – k), мак-

симальне М = 2k – 2 – (n – k).

Тоді відносне значення похибки подання δ1 деякого числа

N (m ≤ N ≤ М) дорівнює

δ1 = [Δ1/N] 100 %.

Мінімальне значення відносної похибки має місце з поданням мак-

симального числа М

δn = Δi/N 100 % = [2 – (n – k)/[2k – 2– (n – k)]] 100 % ,

а максимальне значення відносної похибки – з поданням мінімального

числа m δm = Δi/m 100% = [2 –(n – k)/[2–(n – k)]] 100 % = 100 %.

Подання чисел з плаваючою крапкою

Числа з плаваючою крапкою призначені для подання дійсних чисел

і можуть бути типу слова (float), подвійного слова (double) або збільше-

ного вчетверо слова (long double).

У загальному випадку подання чисел з плаваючою точкою має ви-

гляд:

Х = SP g, g < 1,

де g – мантиса Х = SP g; S – характеристика числа; Р – порядок чис-

ла; S – основа характеристики числа.

Розмір простору, який персональний комп’ютер використовує для

зберігання характеристики і мантиси, встановлений стандартом IEEE

724-1985 і підтримується всією сучасною комп’ютерною архітектурою.

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

вою, що дорівнює S, знак числа збігається зі знаком мантиси, а порядок

визначає положення крапки в числі X. Для спрощення операцій над по-

рядками використовують порядок, що зміщується вбік позитивних зна-

Page 32: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

32

чень. У цьому випадку операції над порядками зводяться до дій над ці-

лими додатними числами без знака.

З метою підвищення точності подання чисел при фіксованому числі

розрядів мантиси використовують в нормалізованій формі (рис. 1.9).

Нормалізованим двійковим числом називається двійкове число,

яке починається з одиниці. Для нормалізованого числа мантиса задово-

льняє умові

1 > g ≥ 1/S.

Старший розряд мантиси відрізняється від нуля. Нормалізація числа

r старших розрядів мантиси, що дорівнюють нулю, зводиться до пере-

міщення мантиси на r розрядів ліворуч і зменшення порядку на r оди-

ниць. При цьому в молодші розряди мантиси r записується 0.

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

системою числення.

Число наводиться у вигляді

Х = 2P g 1 > g > 1/2.

Це дозволяє досягти найбільшої точності обчислень при фіксованій

довжині мантиси на відміну від восьме- і шістнадцяткових основ, однак

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

Мантиса і порядок є знаковими числами. Для зазначення знаків у

розрядній сітці відводять два додаткових розряди. З такою формою по-

дання існують різні варіанти запису одного і того ж самого числа. На-

приклад, число 11,012 можна записати як 0,011012 × 211B або як 0,11012 ×

210B. Таким чином, крапка у мантисі може зсуватися (плавати), а мантиса

може набувати різних значень, менших одиниці, при відповідних зна-

ченнях порядку. Таку форму подання числа, в якому старший розряд

мантиси не дорівнює нулю, називають нормалізованою. Усі інші форми

подання є ненормалізованими. У мікропроцесорних системах, в яких реалізовано подання чисел у

формі з плаваючою крапкою, числа зберігаються в нормалізованому ви-

гляді. При цьому більша кількість розрядів використовується для збері-

Рис. 1.9. Формат даних для чисел з плаваючою крапкою

Знак Порядок, що зміщується (Рзм) Мантиса

Page 33: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

33

гання дробової частини, внаслідок чого підвищується точність обчис-

лень. Якщо після виконання арифметичних операцій (наприклад, відні-

мання) результат виявляється ненормалізованим, то перед занесенням

числа в пам’ять виконується його нормалізація, тобто зсув мантиси вліво

на відповідну кількість розрядів і зменшення порядку числа на відповід-

ну кількість одиниць. При запису двійкового числа у формі з плаваючою крапкою у

(n + 2)-розрядній сітці k комірок приділяється для розміщення мантиси, а

n – k комірок – для розміщення порядку, а два розряди – Зн. для зазна-

чення знаків (рис. 1.10).

У нормалізованій формі значення мантиси завжди більше або до-

рівнює 1/2, але не перевищує 1. Вага молодшого розряду мантиси дорів-

нює 2– k, а вага старшого розряду – 2–1. Максимальне значення мантиси

складає 1 – 2– k, при збільшенні k наближається до 1. Максимальне зна-

чення числа, що визначає порядок, дорівнює 2n – k – 1.

При максимальних значеннях мантиси і порядку значення M пода-

ного числа є максимальним:

M = [1 – 2– k ]×2 [2 – 1].

При мінімальному значенні мантиси і максимальному за модулем

від’ємному значенні порядку значення m поданого числа є мінімальним:

m = 2– 12 – [2 – 1] .

Формат слова (float) має такий вигляд: 1 – прихований (невидимий людині) розряд

v

Зн Характеристика Нормалізована мантиса

31 30 . . . 23 22 21 . . . 1 0

Зміщення складає: – 7F16 = 12710.

n – k

n – k

Зн. . . .

k

Код мантиси

. . .

n – k

Код порядку

Рис. 1.10. Подання чисел у формі з плаваючою крапкою

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 34: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

34

Формат подвійного слова (double) має такий вигляд: 1 – прихований (невидимий людині) розряд

v

Зн Характеристика Нормалізована мантиса

63 62 . . . 52 51 50 . . . 1 0

Зміщення складає – 3FF16 = 102310.

Формат збільшеного учетверо слова (long double) має такий вигляд: S Характеристика Нормалізована мантиса

79 78 . . . 64 63 62 . . . 1 0

Особливість останнього формату полягає у тому, що мантиса не

має прихованого розряду.

Зміщення складає: – 3FFF16 = 1638310.

Задача № 17. Нормалізувати число А = [±0.5]10 і подати його у фо-

рматі слова з плаваючою крапкою.

Розв’язання: А = [0.5]10 = [0.1]2 = [1.0]2 * 2-1

Характеристика = 7F – 1 = 7E.

У мантисі тільки один розряд, який невидимий для людини. Тому

виходить, що мантиса дорівнює нулю.

1 – прихований розряд

v

0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0

Зн Характеристика Нормалізована мантиса

31 30 29 28 27 26 25 24 23 22 21 20 19 18 . . . 1 0

3 F 0 0 0 0 0 0 0

Для негативного числа нічого не зміниться, за винятком знакового

розряду. Тоді: 1 – прихований розряд

v

1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0

S Характеристика Нормалізована мантиса

31 30 29 28 27 26 25 24 23 22 21 20 19 18 . . . 1 0

B F 0 0 0 0 0 0 0

Відповідь. А = [0.5]10 = [1.0]2 * 2-1

Page 35: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

35

Задача № 18. Нормалізувати число А = [117.25]10.

Розв’язання: А = [117.25]10 = [1110101.01]2 = [1.11010101]2 * 26

Відповідь: А = [117.25]10 = [1.11010101]2 * 26

Виконання арифметичних операцій в пристроях з плаваючою

крапкою

Складання. Ця операція в пристроях з плаваючою крапкою здійс-

нюється в чотири етапи:

1. Зрівнюються порядки доданків: молодший порядок збільшується

до старшого. При цьому відповідно коректується мантиса перетворюва-

ного числа.

2. Виконується перетворення мантис у додаткові коди.

3. Здійснюється підсумовування мантис за правилами, розглянути-

ми вище для чисел з фіксованою комою.

4. До суми приписується порядок доданків і у разі потреби вироб-

ляється нормалізація результату.

Можливі два випадки денормалізації:

а) денормализація ліворуч, що відповідає переповнюванню розряд-

ної сітки;

б) денормалізація праворуч, що виникає, коли в прямому коді ман-

тиси після коми є один або декілька нульових розрядів.

Наявність денормалізації ліворуч визначається тими ж способами,

що і переповнювання розрядної сітки. Для денормалізації праворуч ха-

рактерне однакове значення розрядів мантиси по обидві сторони від ко-

ми.

Як приклад розглянемо складання двох чисел, які наведені в пока-

зовій формі:

а = + 0,10101 × 102+101; b = – 0,11001 × 102

011.

Зрівнюємо порядок другого числа до порядку першого числа:

b = – 0,0011001 × 102+101

Підсумовуємо мантиси:

+ 0,1010100

– 0,0011001

+ 0,0111011

Результат одержали в денормалізованій формі, оскільки в мантисі

розряд, безпосередньо слідуючий за комою, має нульове значення. Пря-

мий код позитивної мантиси результату 0,0111011 має однакові (рівні

нулю) розряди по обидві сторони від коми.

Page 36: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

36

Для нормалізації необхідно зсунути всі розряди мантиси вліво на

один розряд і зменшити на одиницю значення порядку. Остаточно одер-

жимо число + 0,1110110 × 102100, яке повинне бути розміщене в розряд-

ній сітці обчислювального пристрою.

Якби мантиса денормалізованого результату була негативною, на-

приклад – 0,0111011, то її зворотний код 1,1000100 також мав би одна-

кові (тепер уже рівні одиниці) значення розрядів по обидві сторони від

коми.

Множення і ділення. Операція множення чисел, поданих у формі з

“плаваючою” крапкою, тобто в показовій фермі, також виробляється в

чотири етапи:

1. Визначається знак результату.

2. Перемножуються мантиси співмножників за правилами для чи-

сел з фіксованою комою.

3. Встановлюється порядок добутку складанням алгебри порядків

співмножників за правилами підсумовування цілих чисел зі знаком.

4. Виробляється нормалізація одержаного результату в разі її необ-

хідності.

Як приклад знайдемо добуток двох чисел, поданих в показовій фор-

мі:

а = + 0,10101 × 102+100; b = – 0,10001 102 + 011.

Мантиса добутку в денормалізованій формі – 0,0101100101 має не-

гативний знак, порядок результату дорівнює 111. Після нормалізації зна-

чення порядку повинне бути зменшене на одиницю. Остаточно маємо –

0,101100101 × 10+110, тобто результат поданий в нормалізованій формі.

Ділення чисел у пристроях з «плаваючою» комою виробляється так

само, як і множення. Оскільки всі числа в цьому випадку не повинні пе-

ревищувати 1, мантиса дільника завжди повинна бути вибрана менше

мантиси дільника, що досягається масштабуванням. Порядок частки ви-

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

разі потреби також виробляється нормалізація результату.

Таким чином, при використовуванні двійкової системи числення всі

чотири арифметичні операції – складання, віднімання, множення і ділен-

ня – зводяться тільки до однієї основної операції – складання і додатко-

вих операцій – інвертування кодів і зрушення. Ці операції виконуються в

спеціальному вузлі, званому арифметичним пристроєм. Принципи побу-

дови таких пристроїв розглядаються нижче.

Page 37: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

37

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

1. Яке з двох чисел А = 0,0371 × 103, В = 0,1751 × 104 наведено в но-

рмалізованій формі?

2. Як виробляється складання двох чисел, які наведені у формі з

“плаваючою” крапкою, якщо числа мають різні порядки?

3. Записати в нормалізованій формі двійкові числа А = 11011,01011

і В = 0,01101111.

4. Перемножити числа А = – 0,1001012 × 26 і В = – 0,1100012 × 27,

якщо задана розрядність машини: сім розрядів – для наведення мантиси і

чотири розряди – для наведення порядку (не враховуючи знакових роз-

рядів).

Абсолютна похибка Δ2 подання двійкових чисел – є різницею між

істинним значенням вхідної величини А і її значенням, одержаним з ма-

шинного зображення А. Відносну похибку подання двійкового числа N визначають як

δ2 = [Δ2/N] × 100 %.

При поданні максимального числа значення відносної похибки є

мінімальним

δm = [Δ2/M] ×100 % = [2–k/ [1 – 2 –k ]] × 100 %.

При поданні мінімального числа значення відносної похибки є мак-

симальним

δm = [Δ2/m] ×100 % = 2–k/2–1 × 100 .

Відносна похибка подання чисел з плаваючою крапкою незначно

змінюється в усьому діапазоні і є малою навіть для малих чисел.

Діапазон чисел з плаваючою крапкою істотно ширший, ніж із фік-

сованою крапкою. Наприклад, при 16-розрядній сітці (n = 16) діапазон

подання чисел у формі зі фіксованою крапкою визначається 16 двійко-

вими розрядами. У формі з плаваючою крапкою, в якій для розміщення

мантиси відведено k – 10 розрядів з урахуванням знакових розрядів, діа-

пазон M/m = 2127 визначається 127 розрядами.

Максимальна відносна похибка в першому випадку δm = 100 %, а в

другому – δM = 2–9 ×100 % = 0,1953 %.

Page 38: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

38

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

потрібної швидкодії, точності виконання арифметичних операцій та діа-

пазону зміни значень величин, з якими оперує МП.

1.4. Двійково-десяткові коди

Більшість сучасних ЕОМ здійснюють обробку інформації не тільки

двійкових кодів, а i десяткових, наведених за допомогою того або іншого

двійково-десяткового коду.

Залежно від вимог до швидкодії та економічності обробка двійково-

десяткових кодів може здійснюватись як розрядами, так i відразу над

всім кодом.

Додавання в Д-кодах

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

бражуються тетрадою двійкових символів xi = x4ix3

ix2ix1

i, де десяткова xi

– цифра i-го розряду; – xji двійкова цифра i-ї тетради.

Десятковий код, кодований двійковими символами, називають

Д-кодом.

З усієї множини відомих Д-кодiв найбільше розповсюдження отри-

мали код Д1 прямого заміщення (система 8421) i код Д2 з надлишком 3

(система 8421 + 3).

Через заборонені комбінації при додаванні чисел в будь-якому з

Д-кодiв виникають необхідність у корекції результату i труднощі у фор-

муванні десяткового переносу в наступну тетраду.

Особливості додавання чисел у Д-кодах рiзноманiтнi, тому розгля-

немо їх окремо. Будемо вважати, що задані числа

X = xnxn – 1 … x1x0 та Y = ynyn – 1 … y1y0,

де xi , yi – двійково-кодовані десяткові цифри (тетради).

Необхідно отримати

X + Y = Z = znzn – 1 … z1z0

причому

Zi = xi + yi + Пi – 1 – Пi p; zn + 1 = Пn,

Page 39: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

39

де Пi = {0.1}, Пi – 1 = {0.1} – десятковi переноси; р = 10 – основа системи

числення.

Значення результату додавання лежить у межах від 0 до 19. При

цьому одиниця в другому переносі являє собою десятковий перенос в

наступну тетраду, а сума одержується в двійковому коді, відмінному від

необхідного двійково-десяткового подання, тобто вона потребує коригу-

вання.

Код Д1

При додаванні чисел в коді Д1 може виникнути наступне:

1) якщо xi + yi + Пi – 1 < 10, то при виконанні дій над розрядами тет-

ради за правилами двійкової арифметики одразу одержують правильний

результат;

2) якщо xi + yi + Пi – 1 ≥ 10 то виникає десятковий перенос, тому сума

в даній тетраді повинна дорівнювати

Zi = xi + yi + Пi – 1 – Пi 10,

де Пi = 1.

При цьому ознакою невірного результату є:

виникнення тетрадного переносу Пi = 16;

поява забороненої комбінації, якщо xi + yi + Пi – 1 ≥ 10.

У будь-якому випадку необхідно коригувати результат в даній тет-

раді введенням поправки + 01102 = 6. Це призводить до виникнення пе-

реносу i в другому випадку. Корекція зумовлена тим, що кожний пере-

нос виносить із собою з даної тетради 16 одиниць, а приносить в наступ-

ну тільки 10 одиниць.

Приклад. Скласти тетради xi = 1000 i yi = 1001 при Пi – 1 = 1.

1000

Zi = xi + yi + Пi – 1 1001

0001

10010

Оскільки Пi = 1 необхідна корекція,

Zi = 0010 + 0110 = 1000, Пi = 1.

Page 40: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

40

Отже, якщо в i-й тетраді сума цифр з переносом з (i – 1)-ї тетради

менша 10, то додавання виконується без поправок; якщо ж сума більша

або дорівнює 10, то виконується корекція результату шляхом введення

поправки + 0110, а виникаючий при цьому перенос додається до вмісту

(i + 1)-ї тетради.

Якщо в декількох тетрадах, починаючи з (i + 1)-ї, розрядна сума до-

рівнює 1001, то перенос призведе до формування забороненої комбінації

в (i + 1)-й тетраді. Потрібна буде корекція, що в свою чергу призведе до

забороненої комбінації (i + 2)-ї тетради i т.д.

Отже, через послідовне розповсюдження тетрадних переносів час

додавання в коді Д1 складе в гіршому випадку n тактів, де n – кількість

тетрад.

Звичайно схеми будують таким чином, щоб перенос, що виникає

при додаванні тетрадної поправки, проходив крізь тетради, в яких по-

передня сума дорівнювала б 910 = 10012, і скидав їх в нульовий стан.

При цьому сума завжди формується за два такти.

1.5. Кодування символьної інформації

Сучасні ЕОМ обробляють не тільки числову, і текстову інформацію,

іншими словами, алфавітно-цифрову інформацію, яка містить цифри,

букви, знаки, математичні та інші символи. Характер цієї інформації

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

Сукупність всіх символів, що використовують в обчислювальній си-

стемі, являє собою її алфавіт. Символу відповідає машинна одиниця

інформації – склад. Так називають групу двійкових розрядів, які служать

для зображення символу в машині (двійковий код символу). Використо-

вують різні варіанти кодування символів.

Необхідно, щоб пам’ять машини ефективно використовувалась при

розміщенні в ній як алфавітно-цифрової, так і десяткової інформації.

Найбільше розповсюдження знайшло зображення алфавітно-

цифрової інформації за допомогою 8-розрядних слів, так званих байтів.

За допомогою байта можна закодувати 256 різних символів.

Для зображення алфавітно-цифрових символів в пам’яті машини та

на носіях інформації в ЄС ЕОМ і деяких інших ПК використовують код

для обробки інформації (ДКОІ), а в мікропроцесорах, персональних

комп’ютерах – розширений із врахуванням букв російського та україн-

Page 41: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

41

ського алфавіту код ASCII.

Алфавітно-цифрова інформація подається словами змінної довжи-

ни, що містять потрібне число байт-символів. Наприклад, у ЄС ЕОМ

алфавітно-цифрове слово може мати довжину від 1 до 256 байти.

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

вий принцип кодування символів. Двійкове число, що відповідає коду

символу, називається його вагою. При ваговому кодуванні вага кодів

цифр послідовно зростає, а ваги кодів букв зростають в алфавітному

порядку. Вага букви Б на 1 більша ваги коду букви А і т.д.

Для економії пам’яті та для зручності виконання арифметичних

операцій над десятковими числами в машинах із байтовим зображенням

інформації поряд з описаним вище способом зображення алфавітно-

цифрових символів передбачаються спеціальні формати для десяткових

чисел – зонний (“розпакований”) та ущільнений (“запакований”). Десят-

кові дані розглядаються як десяткові числа зі знаком. Числа можуть мати

змінну довжину. Для зображення від’ємних чисел застосовується прямий

код.

Десяткові цифри 0, 1, ... , 9 зображують двійково-десятковою фор-

мою – кодом 8421, в якому десяткова цифра зображується 4-розрядним

двійковим числом. При цьому комбінації, що не використовуються (1010

– 1111), служать для кодування знаків та службових символів.

Для зонного формату в кожному байті міститься тільки одна десят-

кова цифра та службовий знак (зона). При цьому чотири правих розряди

служать для зображення десяткової цифри двійково-десятковим кодом, а

чотири лівих зайняті спеціальним 4-розрядним кодом, що зветься зоною.

Молодший байт у цьому форматі складається з кодів знака та молодшої

десяткової цифри числа.

У ДКОІ прийнято кодувати: плюс 1100, мінус – 1101 та зона –

1111.

При кодуванні десяткового числа без знака в ліві чотири розряди

молодшого байта записується код зони.

Важливою перевагою 8-розрядного слова є розміщення в одному

форматі кодів двох десяткових цифр, чим досягається економія пам’яті.

Ця можливість реалізується в запакованому десятковому форматі. В

цьому форматі код знака розміщується в правих чотирьох розрядах мо-

лодшого байта. Десяткове число завжди займає ціле число байтів. Якщо

Page 42: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

42

ліві чотири розряди самого лівого (старшого) байта вільні, вони запов-

няються нулями.

Число – 6.285 у запакованому десятковому форматі має вигляд:

0 6 2 8 5 –

0000 0110 0010 1000 0101 1101

Байт Байт Байт

В ЄС ЕОМ у запакованому форматі десяткове число може мати до-

вжину від 1 до 16 байтів. У цьому випадку максимальна довжина числа –

31 десяткова цифра плюс знак. При виконанні операцій над десятковими

числами в ЄС ЕОМ використовують запакований формат. Результат

отримують також в цьому форматі. Числа, що приймають участь в опе-

рації, можуть мати різну довжину. Вони розглядаються як цілі числа, що

вирівняні за молодшими розрядами. Формат із зоною використовується

при операціях введення-виведення десяткових даних.

В обчислювальних машинах, що використовують різні формати, є

команди для перетворення десяткових чисел зонного формату на запако-

ваний та зворотно.

1.6. Завдання для виконання

Номер завдання відповідає номеру стовпця у табл. 1.2.

Таблиця 1.2

Варіанти завдань

№ 1 2 3 4 5 6 7 8 9

1 57,125 2806,125 57,5 1DC,2B 84; 94 – 42 23, –34 567 89,54

2 66,25 2906,5 67,25 9DC.89 74; 46 65 –14, –7 853 74, 46

3 94,125 3808,25 54,125 7E,FDA 56; 35 – 53 13, –23 543 56, 35

4 115,5 4806,5 66,25 C5D,F3 82; 12 – 28 -14, –12 268 82, 12

5 134,125 2106,25 48,125 38E,FDA 89; 54 – 73 18, –23 684 89,54

6 146,25 1806,125 37,5 96A,ED1 74; 46 – 42 23, –34 567 57, 82

7 152,5 2306,125 87,25 38E,FDA 56; 35 65 –14, –7 853 84, 94

8 164,125 1606,5 97,125 96A,ED1 82; 12 – 53 13, –23 543 74, 46

9 88,125 2206,125 47,25 9DC,89D 89; 54 – 28 – 14, –12 268 56, 35

10 97,25 1605,5 53,5 17E,FDA 57; 82 – 73 18, –23 684 82, 12

Page 43: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

43

1. Перевести ціле та дрібне числа з десяткової у двійкову систему

числення.

2. Перетворити число з десяткової системи числення в шістнадцят-

кову та вісімкову системи числення.

3. Перетворити число спочатку у двійкову систему числення, а по-

тім у шістнадцятковий та вісімковий еквіваленти.

4. Перетворити число з шістнадцяткової системи числення у двійко-

вий еквівалент.

5. Подати числа у 2-10 кодах та виконати операцію складання.

6. Записати число в прямому, зворотному та додатковому кодах.

7. Скласти числа в додаткових кодах.

8. Подати число у формі з фіксованою та плаваючою комами для

N = 6, m = 4.

9. Скласти числа у форматі з плаваючою комою: N = 6, m = 4.

10. Розташуйте наступні числа у порядку зростання:

а) 748, 1100102, 7010, 3816;

б) 6E16, 1428, 11010012, 10010;

в) 7778, 1011111112, 2FF16, 50010;

г) 10010, 11000002, 6016, 1418.

11. Запишіть числа в прямому коді (формат 1 байт):

а) 31; б) -63; в) 65; г) – 128.

12. Запишіть числа в зворотному та додатковому кодах (формат 1

байт):

а) -9; б) -15; в) – 127; г) – 128.

13. Знайдіть десяткові представлення чисел, записаних в додатково-

му коді:

а) 1 1111000; б) 1 0011011; в) 1 1101001; г) 1 0000000.

14. Знайдіть десяткові представлення чисел, записаних в зворотному

коді:

а) 1 1101000; б) 1 0011111; в) 1 0101011; г) 1 0000000.

15. Виконайте віднімання чисел шляхом складання їх зворотних (до-

даткових) кодів у форматі 1 байт. Вкажіть, в яких випадках має місце

переповнювання розрядної сітки:

а) 8 – 3; б) 3 – 9; в) – 7 – 9; г) – 20 – 10; д) 50 – 25;

е) 127 –1; ж) – 120 – 15; з) – 127 – 1.

Page 44: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

44

2. АРХІТЕКТУРНІ ОСОБЛИВОСТІ 16-РОЗРЯДНОГО МП і8086

2.1. Функціонування базового МП

2.1.1. Загальна характеристика 16-розрядного МП i8086

ВІС i8086 (К1810ВМ86) являє собою однокристалічний

16-розрядний МП, виконаний за n-канальною МОП-технологією, що

дозволяє одержати середній час затримки поширення сигналів на вен-

тиль 2 нс і забезпечити високу функціональну щільність (29 тис. транзи-

сторів на кристал).

Основні системні характеристики МП К1810ВМ86:

Тактова частота, МГц – 5

Ємність адресованої пам’яті, Мбайт – 1

Розрядність адресної шини – 20

Розрядність шини даних – 16

Число адресованих пристроїв

вводу-виводу – 216/216

Основних команд – 133

Максимальна споживана потужність, Вт – 1,75

Тип корпуса – 2123.40–6(7)

Складові частини МПК серії К1810:

К1810ВМ86 Центральний процесор n-МДП

К1810ВМ88 Центральний процесор з 8-бітовою

зовнішньою шиною даних n-МДП

К1810ВМ87 Арифметичний співпроцесор n-МДП

К1810ВМ89 Спеціалізований процесор вводу-виводу n-МДП

К1810ГФ84 Генератор тактових сигналів ТТЛШ

К1810ВГ88 Системний контролер ТТЛШ

К1810ВБ89 Арбітр системної шини ТТЛШ

К1810ВТ02 Контролер динамічної пам’яті (16 кВ) n-МДП

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 45: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

45

К1810ВТ03 Контролер динамічної пам’яті (64 кВ) n-МДП

К1810ВИ54 Інтервальний таймер n-МДП

К1810ВТ37 Удосконалений контролер прямого

доступу до пам’яті n-МДП

К1810ВН59 Програмований контролер переривань n-МДП

К1810ИР82/83 Регістр-засувка ТТЛШ

К1810ВА86/87 Шинний формувач ТТЛШ

Навантажувальна здатність кожного виходу ВІС відносно невелика

і відповідає одному входу мікросхеми, виконаної за стандартною ТТЛ-

технологією. Тому практично завжди вихідні сигнали ВІС необхідно

буферизувати за допомогою зовнішніх схем, що забезпечують необхідну

навантажувальну здатність.

Параметр Значення (min/max)

Напруга живлення, U 5,75 – 5,25

Вхідна напруга низького рівня, U – 0,8

Вхідна напруга високого рівня, U – 2,0

Вихідна напруга низького рівня, U – 0,45

Вихідна напруга високого рівня, U – 2,4

Вихідний струм високого рівня, мA – 0,4

Вихідний струм низького рівня, мA – 2,0

Струм витоку на входах/виходах, мкА входах-виходах, мкА – ±10

Ємність входу/виходу, пФ – 10

Ємність навантаження, пФ – 100

Позначення виводів МП наведені в табл. 2.1.

Таблиця 2.1

Позначення виводів МП Позначення Призначення Тип

AD15 – AD0 Лінії шини адреси/даних (ШАД) Вих. (z)

A16/S3

A17/S4

A18/S5

A19/S6

Лінії адреси/стану. Протягом такту Т1 містять

старші біти адреси при звертанні до пам’яті

ЗовПр, а протягом Т2, ТЗ, TW і Т4 – інформа-

цію про стан МП

Вих. (z)

BHE/S7 Дозвіл старшого байта шини/стан Вих. (z)

RD МП виконує цикл читання Вих. (z)

Page 46: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

46

Продовження табл. 2.1 Позначення Призначення Тип

RDY Готовність. Сигнал підтвердження того, що пристрій

готовий до взаємодії з МП при передачі даних

Вх.

AD15 – AD0 Лінії шини адреси/даних (ШАД) Вих. (z)

A16/S3

A17/S4

A18/S5

A19/S6

Лінії адреси/стану. Протягом такту Т1 містять старші

біти адреси при звертанні до пам’яті ЗовПр, а протягом

Т2, ТЗ, TW і Т4 – інформацію про стан МП

Вих. (z)

BHE/S7 Дозвіл старшого байта шини/стан Вих. (z)

RD Читання (строб). Сигнал вказує на те, що МП виконує

цикл читання

Вих. (z)

RDY Готовність. Сигнал підтвердження того,

що адресований пристрій готовий до взаємодії з МП

Вх.

INTR Запит переривання, за яким МП переходить

на підпрограму обробки переривання, якщо є дозвіл

Вх.

NMI Немасковане переривання. Сигнал викликає перериван-

ня за фіксованим вектором (тип 2); не може бути заборо-

нено внутрішніми засобами МП (програмно)

Вх.

TEST Вхідний сигнал, що перевіряється командою WAIT, яка

переводить МП у стан чекання, якщо TEST = 1

Вх.

CLK, (CLC) Тактові імпульси, що забезпечують синхронізацію ро-

боти МП

Вх.

RESET

(CLR)

Скидання, що змушує МП негайно припинити викону-

вані дії і потім відновити виконання програми спочатку

Вх.

MN/MX Min/max, забезпечує відповідний режим роботи МП Вх.

INTA Підтвердження переривання, що стробує читання век-

тора (типу) переривання

Вих.

ALE (STB) Дозвіл регістра-засувки адреси, що стробує появу адре-

сної інформації в такті Т1 на ШАД

Вих.

DEN, (DE) Дозвіл даних, що стробує появу даних на шині адре-

си/даних

Вих. (z)

DT/R

(OR/IP)

Передача/прийом даних, що визначає напрямок переси-

лання даних по ШАД

Вих. (z)

M/O Звертання до ЗП або ЗовПр у даному циклі шини Вих. (z)

WR Запис (строб), указую на цикл запису Вих. (z)

HOLD Запит захоплення, що вказує на те, що деякий прист-

рій запитує шини МП

Вх.

Page 47: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

47

Закінчення табл. 2.1 Позначення Призначення Тип

HLDA Підтвердження захоплення, що вказує на те, що МП

перевів свої шини адреси/даних, адреси/стану

і управління в z-стан

Вих.

S2,S1,S0

(ST2-ST0)

Лінії стану, що характеризують тип виконуваного ци-

клу; необхідні для вироблення управляючого сигналу

Вих. (z)

RQ/GT0

RQ/GT1

RQ/E0,

RQ/E1

Запит/надання, що використовується для обміну сиг-

налами між процесорами в багатопроцесорній системі,

для управління процедурою використання шин

Вх/Вих.

LOCK Блокування (зайнятість) шини, що інформує інші про-

цесори і пристрої про те, що вони не повинні звертатися

до шини

Вих.

QS1, QS0 Стан черги, вказує на стан внутрішньої 6-байтової

черги команд МП

Вих.

2.1.2. Структурна схема МП i8086

Структура 16-розрядного однокристального МП виконується з апа-

ратно розподіленими функціями, що дає можливість поєднати операції,

пов’язані з формуванням виконавчих адрес, та вибірку даних і команд із

процесом їх обробки. Це досягається завдяки наявності в їхній структурі

двох асинхронно працюючих пристроїв: пристрою обробки і пристрою

поєднання з каналом (рис. 2.1). Пристрій обробки складається з двох

частин: операційного пристрою (ОПр) і мікропрограмного пристрою

управління (МППУ).

Рис. 2.1. Узагальнена схема МП К1810ВМ86

Операційний пристрій дозволяє вести обробку найпотужнішої си-

стеми команд із розширеними можливостями адресації пам’яті, що

включає команди множення, ділення й організації циклів. З цією метою

поряд з регістрами загального призначення (AX, BX, CX, DX) до складу

Пристрій зв’язку з каналом

Пристрій обробки

ОПр МППУ

Page 48: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

48

операційного пристрою включений покажчик бази (ВР), що використо-

вується для задання сегментного способу адресації стекового сегмента

пам’яті, та індексні регістри джерела SI і приймача DI, які використову-

ються для збереження відносних адрес у межах сегмента даних.

Структурна схема мікропроцесора К1810 наведена на рис. 2.2.

МП має магістральну структуру, однак з метою скорочення можли-

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

А і даних D.

МППУ складається зі схеми формування адреси мікрокоманд

(МК), регістра адреси мікрокоманд (PrАМК), пам’яті мікрокоманд

(ПМК) і регістра мікрокоманд (PrМК).

Робота МППУ полягає у виконанні мікропрограм, що зберігаються

в ПМК. Вихід на ту чи іншу мікропрограму здійснюється за кодом опе-

ШУ

ША, ШД

А16

А17

А18

А19

Прист.

упр.

Буфер адр.

SM

CS

DS

SS

ES

IP

Сегменти

програм

стека

даних

Проміжн. результат

Покажчик команди

Пристрій зв’язку з

шиною

ША ШД

Рг. К6

Рг. К5

Рг. К4

Рг. К3

Рг. К2

Рг. К1

Рг черг. команд

AH AL

BH BL

CH CL

DH DL

SP

BP SI

DI

АЛП

F

AX BX

CX DX

Вказ. стека

Вказ. бази

Індекс прм.

Рг АМК

П

М

К

Рг МК

Сх.

фор.

адр.

МППУ

Рис. 2.2. Структурна схема МП i8086

ОПр

Індекс ліч.

Page 49: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

49

рації команди, що надійшла в регістр команд з основної пам’яті МПС

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

чає адресу першої мікрокоманди.

Ця адреса завантажується в регістр адреси МК, за вмістом якої

здійснюється вибірка мікрокоманди з ПМК і завантаження в регістр МК.

Операційна МК кодує певним чином мікрооперації, що повинні викону-

ватися протягом машинного такту роботи МП в операційному пристрої.

Управляюча МК задає спосіб формування адреси наступної МК і надхо-

дить на схему утворення адреси мікрокоманди МППУ.

Ця схема формує адресу наступної мікрокоманди на підставі зада-

ного способу з урахуванням значення визначеної ознаки результату, що

надійшов з РrF операційного пристрою. Тим самим реалізується перехід

у мікропрограмі на потрібну мікрокоманду з урахуванням вироблених

ознак результату виконання попередньої операції.

Якщо наступна команда є операційною (тобто не виконується умо-

ва переходу), то регістр адреси МК працює як лічильник МК, збільшую-

чи свій вміст на одиницю: тим самим здійснюється перехід на наступну

мікрокоманду.

Пристрій поєднання з каналом містить блок сегментних регіст-

рів, що зберігає адреси сегментів пам’яті: CS-програмного, DS-

даних, ES-проміжних результатів і SC-стекового, а також покажчик ко-

манд IP. Виконавчі адреси утворюються додаванням вмісту стекових

регістрів до вмісту одного з регістрів блока покажчика й індексних ре-

гістрів або до вмісту адресної частини команди. Важливою особливістю

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

буфер забезпечує випереджальну вибірку команд.

Управління роботою пристрою поєднання з каналом здійснюється

пристроєм управління і синхронізації з апаратно реалізованою логі-

кою його роботи.

Пристрій шинного інтерфейсу (або просто шинний інтерфейс)

містить блок сегментних регістрів, покажчик команд, суматор адрес,

чергу команд і буфери, що забезпечують зв’язок із шиною. Шинний ін-

терфейс виконує операції обміну між МП і пам’яттю чи портами вводу-

виводу за запитами операційного пристрою. Коли операційний пристрій

зайнятий виконанням команди, шинний інтерфейс самостійно ініціює

випереджальну вибірку кодів чергових команд із пам’яті.

Page 50: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

50

Черга команд являє собою набір байтових регістрів і виконує роль

регістра команд, у якому зберігаються коди, вибрані з програмної

пам’яті. Довжина черги складає 6 байтів, що відповідає максимально

довгому формату команд. Наявність черги команд, а також здатність

операційного пристрою і шинного інтерфейсу працювати паралельно

дозволяють поєднати за часом фази вибірки команди і виконання заданої

операції: поки одна команда виконується в операційному пристрої, шин-

ний інтерфейс здійснює вибірку наступної команди. Таким способом

досягаються висока щільність завантаження шини і підвищення швидко-

сті виконання програми.

Шинний інтерфейс ініціює вибірку наступного командного слова

автоматично, як тільки в черзі звільняться два байти. Як правило, в черзі

знаходиться мінімум один байт потоку команд, так що операційний при-

стрій не очікує вибірки команди. Ясно, що випереджальна вибірка ко-

манд дозволяє заощаджувати час тільки при природному порядку вико-

нання команд. Коли операційний пристрій виконує команду передачі

управління (переходу) в програмі, шинний інтерфейс скидає чергу, ви-

бирає команду за новою адресою, передає її до операційного пристрою,

а потім починає заповнення (реініціалізацію) черги з наступних комірок

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

підпрограм, поверненнях з підпрограм і при обробці переривань.

У міру необхідності операційний пристрій зчитує байт із черги і

виконує запропоновану командою операцію. При багатобайтових ко-

мандах з черги зчитуються й інші байти команди. В тих рідких випадках,

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

пристрій очікує вибірку чергового командного слова, що ініціює шинний

інтерфейс. Якщо команда вимагає звертання до пам’яті чи порту вводу-

виводу, операційний пристрій запитує шинний інтерфейс на виконання

необхідного циклу шини для передачі даних. Коли шинний інтерфейс не

зайнятий вибіркою команди, він задовольняє запит негайно; в протилеж-

ному разі операційний пристрій очікує завершення поточного циклу ши-

ни. Зі свого боку, шинний інтерфейс припиняє вибірку команд під час

обміну даними між операційним пристроєм і пам’яттю чи портами вво-

ду-виводу.

Буфер шини адреси/даних (БАД) містить 16 двонаправлених під-

силювачів із трьома вихідними станами і забезпечує номінальну наван-

тажувальну здатність ліній AD15 – AD0.

Page 51: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

51

2.2. Програмна модель 16-розрядного МП

До програмної моделі МП належать ті вузли МП, до яких

програміст має доступ, а також комірки пам’яті для розміщення

інформації.

Усього до складу мікропроцесора і8086 входять чотирнадцять

16-бітових регістрів:

a) чотири регістри загального призначення (регістри даних):

AX – регістр-акумулятор,

BX – базовий регістр,

СХ – лічильник,

DX – регістр-розширювач акумулятора;

б) три адресних регістри:

SI – регістр індексу джерела,

DI – регістр індексу результату,

BP – регістр-покажчик бази;

в) три управляючі регістри:

SP – регістр-покажчик стека,

IP – регістр-лічильник команд,

FLAGS – регістр прапорців (ознак):

С – переносу,

Р – паритету,

А – додаткового переносу,

Z – нуля,

S – знака,

О – переповнення,

DF – прапорець напрямку,

IF – прапорець дозволу переривань,

TF – прапорець трасування.

г) чотири сегментних регістри:

CS – регістр сегмента кодів,

DS – регістр сегмента даних,

ES – регістр додаткового сегмента даних,

SS – регістр сегмента стека.

2.2.1. Регістри загального призначення

Вісім регістрів загального призначення процесора х86 (кожен роз-

Page 52: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

52

міром 16 бітів, для процесорів вище 386SX – 32 біти) використовуються

в операціях більшості інструкцій (як джерело або приймач) при перемі-

щенні даних і обчисленнях. Кожен регістр загального призначення має

свою особливість.

Регістр AX

Регістр AX називають також накопичувачем (акумулятором). Цей

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

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

ефективних операцій (арифметичних, логічних або операцій передачі

даних).

Молодші 8 бітів регістра AX називаються також регістром AL, а

старші 8 бітів – регістром AH. Це може виявитися зручним при роботі з

даними розміром 1 байт. Таким чином, регістр AX можна використову-

вати як два окремих регістри.

Регістри BX, CX і DX можуть аналогічним чином використовувати-

ся або як один 16-розрядний регістр, або як два 8-розрядних (0 – 6 –

AL, 7 – 15 – AH, 0 – 15 – AX, 0 – 31 – EAX).

Регістр BX

Регістр BX може використовуватися для посилання на комірку

пам’яті (покажчик). 16-бітове значення, записане в BX, може використо-

вуватися як частина адреси комірки пам’яті, до якої відбувається доступ.

За замовчуванням, коли BX використовується як покажчик на еле-

мент пам’яті, він посилається на неї як до сегментного регістра DS.

Регістр CX

Спеціалізація регістра CX – використання як лічильника.

Зменшення значення лічильника та цикл – це часто використовува-

ні елементи програми. Тому в процесорі х86 використовується спеціаль-

на інструкція для того, щоб цикли виконувалися швидше і були більш

компактними.

Регістр DX

Регістр DX – це єдиний регістр, що може використовуватись як по-

кажчик адреси вводу-виводу в інструкціях IN і OUT. Крім використання

регістра DX немає іншого способу адресуватися до портів вводу-виводу

з 256 по 65535. Інші унікальні якості регістра DX належать до операцій

ділення і множення.

Page 53: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

53

2.2.2. Вказівні й індексні регістри

Індексні регістри використовують для розширення адресації та в

операціях з рядками.

SI – індекс джерела – операції над рядками (зв’язаний з DS);

DI – індекс приймача – операції над рядками (зв’язаний з ES).

Ці регістри можна використовувати нарівні з регістрами загального

призначення.

Вказівні регістри забезпечують системі доступ до даних у сегменті

стека:

ВР – покажчик бази;

SP – покажчик стека.

Регістр SI

Як і регістр BX, регістр SI може використовуватись як покажчик на

елемент пам’яті. Особливо корисно використовувати регістр SI для по-

силання на пам’ять у рядкових інструкціях процесора х86.

Регістр DI

Регістр DI дуже схожий на регістр SI у тому плані, що його можна

використовувати як покажчик комірки пам’яті.

Коли регістри SI і DI використовуються як покажчики на елементи

пам’яті в інших інструкціях, то вони завжди адресуються до пам’яті як

до регістра DS.

Регістр BP

Як і регістри BX, SI і DI, регістр BP також може використовуватись

як покажчик на елемент пам’яті, але тут є деякі відмінності. Регістри BX,

SI і DI звичайно посилаються до пам’яті як до сегментного регістра DS

(або у випадку використання в рядкових інструкціях регістра DI як до

сегментного регістра ES), а регістр BP адресується до пам’яті як до регі-

стра SS (сегментний регістр стека).

Регістр BP створений для забезпечення роботи з параметрами, ло-

кальними змінними іншої адресації до пам’яті з використанням стека.

Регістр SP

Стек являє собою спеціальним способом організовану область

пам’яті, що допускає послідовний запис елементів даних довжиною 2

байти (слово) і читання їх у порядку, зворотному порядку запису. Для

збереження адреси останнього слова, занесеного в стек, служить регістр-

покажчик стека SР.

Page 54: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

54

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

наприклад при виклику підпрограм, коли в стек заноситься адреса пове-

рнення і значення параметрів, переданих у підпрограму.

Формат команд мікропроцесора 8086 дозволяє вказувати в команді

тільки один операнд, розміщений в основній пам’яті, тобто однією ко-

мандою не можна, наприклад, скласти вміст двох комірок пам’яті.

Регістр SP називається також покажчиком стека. Це “найменш за-

гальний” із регістрів загального призначення, оскільки він практично

завжди використовується для спеціальної мети – забезпечення стека.

Регістр SP на будь-який момент часу вказує на вершину стека.

Хоча процесор х86 і дозволяє записувати значення в SP або додава-

ти і віднімати значення, які знаходяться в регістрі SP (як це можна роби-

ти зі звичайними регістрами загального призначення). Якщо змінювати

SP, то змінюється розташування вершини стека, що швидко може приз-

вести до неприємностей. Занесення в стек і витяг з нього не є єдиним

способом використання стека. Стек використовується всякий раз, коли

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

Крім того, стек використовують деякі системні ресурси (такі, як клавіа-

тура або системний таймер), коли вони переривають процесор х86, щоб

виконати свої функції.

2.2.3. Покажчик інструкцій

IP – лічильник команд (покажчик команд) не програмується.

Покажчик інструкцій (регістр IP) завжди містить зміщення у

пам’яті, за яким зберігається наступна виконувана інструкція. Звичайно

наступною виконуваною інструкцією є інструкція, збережена за наступ-

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

можуть призвести до того, що в покажчик інструкцій буде завантажене

нове значення. Таким чином буде виконаний перехід до іншої частини

програми.

Значення лічильника інструкцій не можна прочитати або записати

безпосередньо. Завантажити в покажчик інструкцій нове значення може

тільки спеціальна інструкція переходу.

Покажчик інструкцій самостійно не визначає адреси, за якою зна-

ходиться наступна виконувана інструкція. Для витягу інструкції перед-

бачений регістр CS, де зберігається базова адреса. При цьому покажчик

інструкцій задає зміщення щодо цієї базової адреси.

Page 55: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

55

Починаючи з процесора і486, вибірку команд виконує не тільки на-

ступна команда, а і декілька послідовних команд у спеціальний буфер

(розмір 4 кбайт). Ця технологія зветься конвеєром команд і дозволяє

скоротити час на завантаження наступної команди в регістровій парі

CS:IP.

2.2.4. Сегментні регістри

Для розміщення програм і даних в основній пам’яті виділяють спе-

ціальні області – сегменти. Адреси цих областей зберігаються в спеціа-

льних сегментних регістрах.

Кожен з чотирьох сегментних регістрів використовується для збе-

реження адреси визначеного сегмента:

сегмента кодів, тобто області програм;

сегмента даних, тобто області розміщення даних;

додаткового сегмента даних, що використовується деякими

командами;

сегмента стека, тобто області розміщення стека.

Аналогічно регістрам загального призначення кожен сегментний

регістр відіграє свою конкретну роль. Довжина кожного регістра

16 бітів. Регістр CS вказує на код програми, DS вказує на дані, SS – на

стек, ЕS – це “трафаретний” (додатковий) сегмент даних, що може вико-

ристовуватися так, як це необхідно. Починаючи з процесора 486 існують

ще два сегментних регістри даних FS, GS. Сегментні регістри ініціюють-

ся операційною системою і містять базові сегментні адреси.

Регістр CS

Регістр CS вказує на початок блока пам’яті ємністю 64 кбайт або

сегмент коду, в якому знаходиться наступна виконувана інструкція. На-

ступна інструкція, яку потрібно виконати, знаходиться за зміщенням,

обумовленим у сегменті коду регістра IP, тобто на неї вказує адреса (у

формі “сегмент:зміщення”) CS:IP. Процесор х86 ніколи не може витягти

інструкцію із сегмента, відмінного від того, який визначається регіст-

ром CS.

Регістр CS можна змінювати за допомогою багатьох інструкцій,

включаючи окремі інструкції переходу, виклики і повернення управлін-

ня. Ні за яких обставин регістр CS не можна завантажити безпосередньо.

Ніякі інші режими адресації або покажчики пам’яті, відмінні від IP, не

можуть нормально працювати щодо регістра CS.

Page 56: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

56

Регістр DS

Регістр DS вказує на початок сегмента даних, що являє собою блок

пам’яті ємністю 64 кбайт, де знаходиться більшість розміщених у

пам’яті операндів. Звичайно для посилання на адреси пам’яті використо-

вуються зміщення, що припускають використання регістрів BX, SI або

DI.

Регістр ES

Регістр ES вказує на початок блока пам’яті ємністю 64 кбайт, що

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

додаткового блока пам’яті для даних. Однак доступ до пам’яті в додат-

ковому сегменті менш ефективний, ніж доступ до пам’яті в сегменті да-

них.

Особливо корисний додатковий сегмент, коли використовуються

рядкові інструкції. Всі рядкові інструкції, що виконують запис у пам’ять,

використовують як адресу пам’яті, в яку потрібно виконати запис, пару

регістрів ES:DI. Це означає, що регістр ES особливо корисний при вико-

ристанні його як цільового сегмента при копіюванні блоків, порівнянні

рядків, перегляді пам’яті й очищенні блоків пам’яті.

Регістр SS

Регістр SS вказує на початок сегмента стека, що являє собою блок

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

неявно використовують регістр SP (включаючи занесення в стек, витяг зі

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

тому що тільки регістр SP може використовуватися для адресації пам’яті

в сегменті стека. Регістр BP також працює щодо сегмента стека. Це до-

зволяє використовувати регістр BP для доступу до параметрів і змінних,

які зберігаються в стеці сегмента.

2.2.5. Регістр прапорців

Регістр прапорців F (рис. 2.3) містить ознаки виконання операцій:

CF – прапорець переносу, фіксує значення переносу (позику), що

виникає при додаванні чи відніманні байтів, а також значення висунуто-

го біта при зсуві операнда. FH FL

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

OF DF IF TF SF ZF AF PF CF

Рис. 2.3. Формат регістра прапорців

Page 57: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

57

PF – прапорець парності (чи паритету), фіксує наявність парного

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

ристаний, наприклад, для контролю правильності передачі даних.

AF – прапорець допоміжного переносу, фіксує перенос (позику) з

молодшої тетради, тобто з біта 3, у старшу при додаванні (відніманні).

Використовується тільки для двійково-десяткової арифметики, що опе-

рує винятково молодшими байтами.

ZF – прапорець нуля, сигналізує про одержання нульового резуль-

тату операції.

SF – прапорець знака, дублює значення старшого біта результату,

що при використанні додаткового коду відповідає знаку числа.

OF – прапорець переповнення, сигналізує про втрату старшого біта

результату у зв’язку з переповненням розрядної сітки. При додаванні цей

прапорець встановлюється в одиницю, якщо відбувається перенос у

старший біт і немає переносу зі старшого біта чи є перенос зі старшого

біта, але відсутній перенос до нього. У протилежному разі прапорець OF

встановлюється в нуль. При відніманні він встановлюється в одиницю,

коли виникає позика зі старшого біта, але позика в старший біт відсутня

або є позика в старший біт, але відсутня позика з нього. Є спеціальна

команда переривання при переповненні, що у зазначених випадках гене-

рує програмне переривання.

Для управління деякими діями МП призначені три додаткових

прапорці.

DF – прапорець напрямку, керований командами CLD і STD; ви-

значає порядок обробки ланцюжків у відповідних командах: від менших

адрес (DF = 0) чи від великих (DF = 1).

IF – прапорець дозволу переривань, керований за допомогою ко-

манд CLI і STI; при IF = 1 макропроцесор сприймає (розпізнає) і відпо-

відно реагує на запит переривання по входу INTR; при IF = 0 перериван-

ня по цьому входу забороняються (маскуються) і МП ігнорує запити пе-

реривань, що надходять. Значення прапорця IF не впливає на сприйняття

зовнішніх немаскуємих переривань по входу NMI, а також внутрішніх

(програмних) переривань, виконуваних командою INT.

TF – прапорець трасування (простежування). При TF = 1 МП пере-

ходить у покомандний (покроковий) режим роботи, застосовуваний при

налагодженні програм, коли автоматично генерується сигнал внутріш-

нього переривання типу 1 після виконання кожної команди з метою пе-

реходу до відповідної підпрограми, що звичайно забезпечує індикацію

Page 58: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

58

вмісту внутрішніх регістрів МП. Команди чи установки скидання прапо-

рця TF відсутні, тому керування цим прапорцем здійснюється не прямо,

а шляхом пересилання вмісту регістра прапорців F через стек у загаль-

ний регістр, установки необхідного значення восьмого біта і оберненого

пересилання сформованого слова в регістр F.

Таким чином, структурною особливістю 16-розрядних МП є наяв-

ність двох основних асинхронно працюючих процесорів – операційного

й інтерфейсного, виконаних в одному кристалі БІС, спільно реалізуючий

конвеєр операцій вибірки і виконання команд.

2.2.6. Адресний простір пам’яті і введення-виведення

Розміщення байтів і слів у пам’яті. Пам’ять логічно організована

як одновимірний масив байтів, кожен з якихмає 20-бітову фізичну адре-

су в діапазоні 00000 – FFFFF. (Для запису адрес тут і далі використову-

ють шістнадцяткову систему числення). Будь-які два суміжні байти в

пам’яті можуть розглядатися як 16-бітове слово (рис. 2.4).

7 0

01000 84 Зміщення 3784

01001 37

01002 20 Сегмент А020

01003 А0

Рис. 2.4. Розміщення слів у пам’яті

Молодший байт слова має менша адреса, а старший – більша. Адре-

сою слова вважається адреса його молодшого байта. Таким чином, 20-

бітова адреса пам’яті може розглядатись і як адреса байта, і як адреса

слова.

Повна інформація, необхідна для визначення фізичної адреси, міс-

титься в адресному об’єкті “сегмент:зміщення”, що називається покаж-

чиком адреси і містить адреси сегмента і внутрішньосегментне зміщен-

ня. Для запам’ятовування покажчика адреси потрібно два слова пам’яті,

причому слово з меншою адресою завжди містить зміщення, а слово з

Page 59: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

59

більшою адресою – базову адресу сегмента. Кожне слово зберігається

звичайно, тобто за принципом “молодший байт – за меншою адресою”.

Команди, байти і слова даних можна вільно розміщати за будь-якою

адресою, що дозволяє заощаджувати пам’ять завдяки її щільному упаку-

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

ти слова даних у пам’яті за парними адресами, тому що МП передає такі

слова за один цикл шини. Слова з парною адресою називаються вирівня-

ними на межі слів. Слова з непарними адресами (невирівняні) також

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

продуктивність МП. (Кожен цикл має чотири обов’язкових такти Т).

Відзначимо, що шинний інтерфейс ініціює необхідне для вибірки слова

число звертань до пам’яті автоматично. Тому дворазове звертання до

пам’яті не вимагає спеціальної вказівки в програмі. Особливо важливо

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

асть тільки слова. Отже, покажчик стека SP необхідно завжди ініціалізу-

вати на парну адресу.

Команди завжди вибирають словами за парними адресами, за виня-

тком першої вибірки після передачі керування за непарною адресою,

коли вибирається один байт. Потік команд розділяється на байти при

заповненні черги команд усередині МП, тому вирівнювання команд не

впливає на продуктивність і не використовується.

Сегментація пам’яті й обчислення адрес. Адресована область

пам’яті складає 1 Мбайт і, отже, формат адреси дорівнює 20 біт. Хоча

МП генерує 20-розрядні адреси пам’яті, сам він маніпулює логічними

адресами, що містять 16-розрядну сегментну (базову) адресу і

16-розрядне внутрішньосегментне зміщення. Логічні адреси перетворю-

ються МП на фізичні (виконавчі).

Весь адресний простір розбивається на сегменти ємністю 64 кбайт

кожен. Початкова адреса кожного сегмента (20 біт) має в чотирьох мо-

лодших розрядах нулі – ХХХХ16, тобто сегменти можуть починатися на

межах блоків по 16 байт.

Структура пам’яті така, що два суміжних байти утворюють дво-

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

адресою. Слово може починатися за парною чи непарною адресою. У

першому випадку слово передається за один цикл шини, а в другому –

за два цикли. Отже для досягнення найвищої продуктивності МП слова

необхідно розміщати за парними адресами пам’яті даних. (Порядок роз-

Page 60: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

60

міщення команд у пам’яті на продуктивність МП не впливає, тому що їх

довжина складає від 1 до 6 байт).

Сегментна адреса (початкова адреса сегмента) зберігається в

16-розрядному сегментному регістрі, а звертання до байта чи слова усе-

редині сегмента здійснюється з використанням 16-розрядного зміщення,

сформованого в ОПр.

Якщо вміст сегментного регістра дорівнює нулю, то виконавча ад-

реса дорівнює зсуву. (У системах, де ємність пам’яті не перевищує 64

кбайт, сегментні регістри заповнюються нулями і не використовуються).

Кожному сегменту програмою призначається початкова (базова)

адреса, що є адресою першого байта сегмента в просторі пам’яті. Почат-

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

в сегментні регістри CS, DS, SS і ES, тим самим фіксуються поточні сег-

менти коду (програми), даних, стека і додаткових даних. Для звертання

до команд і даних, що знаходяться в інших сегментах, необхідно зміню-

вати вміст сегментних регістрів, що дозволяє використовувати весь про-

стір пам’яті ємністю 1 Мбайт. Сегментні регістри ініціалізуються на по-

чатку програми шляхом розміщення в них відповідних констант. Окре-

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

до відміни від сегментації пам’яті.

У сегментному регістрі зберігається 16 старших бітів 20-бітової по-

чаткової адреси сегмента. Чотири молодших біти адреси приймаються

рівними нулю і дописуються праворуч до вмісту сегментного регістра

при обчисленні фізичних адрес комірок пам’яті. Тому початкові адреси

сегментів завжди кратні 16. Оскільки інших обмежень на розміщення

сегментів у пам’яті немає, сегменти можуть бути сусідніми (суміжними),

що не перекриваються, частково чи цілком перекриваються. Фізична

комірка пам’яті може належати одному чи декільком сегментам.

Фізична адреса комірки пам’яті представляє 20-бітове число в діа-

пазоні 0 – FFFFF, що однозначно визначає положення кожного байта в

просторі пам’яті ємністю 1 Мбайт. На початку кожного циклу шини,

зв’язаного зі звертанням до пам’яті, фізична адреса видається на шину

адреси і супроводжується сигналом ALE. Оскільки МП ВМ86 є

16-бітовим, всі операції при обчисленні фізичної адреси здійснюються з

16-бітовими адресними об’єктами.

Логічна адреса комірки пам’яті складається з двох 16-бітових без-

знакових значень: початкової адреси сегмента, що називається також

Page 61: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

61

просто базою чи сегментом, і внутрішньосегментного зміщення, що ви-

значає відстань від початку сегмента до цієї комірки.

Для обчислення фізичної адреси база сегмента зміщується вліво на

4 біти і додається зі зміщенням, як показано на рис. 2.5, де також наве-

дені можливі джерела компонентів логічної адреси (ЕА – ефективна ад-

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

Нехай в сегментному регістрі розміщений код 1А0316. Адреса ко-

манди в сегменті команд, адреса коду даних в сегменті даних, адреса

вершини стека в сегменті стека генеруються в МП за визначеними пра-

вилами. Ця 16-розрядна адреса фактично задає зміщення від початку

сегмента до потрібного (в прикладі ця адреса дорівнює FFFB16).

Повна 20-розрядна фізична адреса розраховується в МП як сума

вмісту сегментного регістру, зсунутого вліво на 4-двійкові розряди або

доповненого справа кодом 00002 і адреса в сегменті

1 A03016

+ FFFB16

2 A02B16,

тобто в прикладі вибирається байт (або слово ) з фізичною адресою

2А02В16.

Перенос зі старшого біта, що може виникнути при підсумовуванні,

ігнорується. Це призводить до так званої кільцевої організації пам’яті,

при якій за коміркою з максимальною адресою FFFFF випливає комірка

з нульовою адресою. Аналогічну кільцеву організацію має і кожен сег-

мент.

Джерела логічної адреси для різних типів звертання до пам’яті на-

ведені в табл. 2.2.

19 0

(CS, SS, DS, ES) 19 4

15 0

Зміщення

Сегментний Рг

Суматор

Виконавча адреса

(IP, SP, SI, DI)

Рис. 2.5. Механізм адресації пам’яті

Page 62: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

62

Таблиця 2.2

Джерела логічної адреси для різних типів звертання до пам’яті Тип звертання

до пам’яті

Сегмент

(за замовчуванням)

Варіант Зміщення

Вибірка команди CS Немає IP

Стекова операція SS Немає SP

Змінна DS CS, SS, ES ЕА

Ланцюжок-джерело DS CS, SS, ES SI

Ланцюжок-приймач ES Немає DI

ВР як базовий регістр ES CS, SS, DS SA

Команди завжди вибираються з поточного сегмента коду відповідно

до логічної адреси CS:IP. Стекові команди завжди звертаються до пото-

чного сегмента стека за адресою SS:SP. Якщо при обчисленні адреси ЕА

використовується регістр ВР, то звертання здійснюється також до стеко-

вого сегмента. В останньому випадку принцип стека “перший прийшов –

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

ються як ОЗП з довільною вибіркою, що забезпечує велику гнучкість у

використанні цих комірок.

Операнди, як правило, розміщаються в поточному сегменті даних, і

звертання до них організується за адресою DS:EA. Однак програміст

може змусити МП звернутися до змінної, що знаходиться в іншому по-

точному сегменті. Вважається, що ланцюжок-джерело знаходиться в

поточному сегменті даних, а його зміщення задається регістром SI. Лан-

цюжок-одержувач обов’язково розміщується в поточному додатковому

сегменті, а зміщення береться з регістра DI. Команди обробки ланцюж-

ків автоматично модифікують вміст індексних регістрів SI і DI у міру

просування по ланцюжку в напрямку, що відповідає прапорцю DF. У

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

способом: MOV АХ, CS: [ВХ] – пересилання в АХ слова з кодового сег-

мента зі зміщенням із ВХ; ADD ВL, ES:ROW[DI], –додавання байта з

додаткового сегмента (зі зміщенням + ROW) із вмістом регістра BL і

розміщення результату в ОЗП на місці першого доданка.

Сегментна структура пам’яті забезпечує можливість створення по-

зиційно незалежних чи динамічно переміщуваних програм, що необхід-

но в мультипрограмному середовищу для ефективного використання

оперативної пам’яті. Щоб забезпечити позиційну незалежність, усі змі-

щення в програмі повинні задаватися щодо фіксованих значень, які міс-

Page 63: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

63

тяться в сегментних регістрах. Це дозволяє довільно переміщувати про-

граму в адресному просторі пам’яті, змінюючи тільки вміст сегментних

регістрів.

Стек, як звичайно, організується в ОЗП, і його положення визнача-

ється вмістом регістрів SS і SP. Регістр SS зберігає базову адресу поточ-

ного сегмента стека, а регістр SP вказує на вершину стека, тобто містить

зміщення вершини стека в стековому сегменті. При кожному звертанні

до стека пересилається одне слово, причому вміст SP модифікується

автоматично: при записі (включенні) у стек воно зменшується на два,

при читанні (витягу) зі стека – збільшується на два.

При всіх перевагах прийнятої у ВМ86 організації пам’яті вона має

недолік, що полягає в труднощах маніпуляції фізичними адресами при

необхідності їх програмної обробки.

Організація введення-виведення. Введення і виведення даних

може здійснюватися двома способами:

з використанням адресного простору вводу-виводу,

з використанням загального з пам’яттю адресного простору,

тобто з відображенням на пам’ять.

При першому способі застосовуються спеціальні команди IN (вве-

дення) і OUT (виведення), що забезпечують передачу даних між акуму-

ляторами AL чи АХ і адресованими портами. При виконанні цих команд

виробляється сигнал М/10 = 0, що ідентифікує вибір простору вводу-

виводу й у сукупності із сигналами WR і RD дозволяє сформувати сис-

темні сигнали IOW і IOR для управління операціями запису даних у

порт і читання з порту.

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

адреса порту міститься у вигляді константи в другому байті команди, і

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

У першому випадку можна адресувати по 256 портів для введення і

виведення даних.

У другому випадку забезпечується адресний простір до 64 К 8-

бітових чи до 32 К 16-бітових портів. Непряма адресація дозволяє обчи-

слювати адреси портів при виконанні програми і зручна при організації

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

гою однієї процедури.

Page 64: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

64

Вісім комірок F8 – FF у просторі вводу-виводу зарезервовані для

системних цілей, і використовувати їх у прикладних програмах не реко-

мендується.

При другому способі адреси портів розміщаються в загальному ад-

ресному просторі, і звертання до них не відрізняються від звертання до

комірок пам’яті. Це підвищує гнучкість програмування, тому що для

введення – виведення можна використовувати будь-яку команду зі звер-

танням до пам’яті при будь-якому способі адресації. Так, команда MOV

дозволяє передавати дані між будь-яким загальним регістром чи комір-

кою пам’яті та портом вводу-виводу, а логічні команди AND, OR, XOR і

TEST дозволяють маніпулювати бітами в регістрі порту. При цьому, од-

нак, варто враховувати, що команди зі звертанням до пам’яті мають бі-

льший формат і виконуються довше, ніж прості команди IN і OUT. Крім

того, трохи ускладнюється дешифрування 20-бітової фізичної адреси

порту і скорочується число адрес, що можуть використовуватись для

комірок пам’яті.

МП може передавати по шині байт чи слово в/із ЗовПр. Щоб слово

передавалося за один цикл шини, адреса ЗовПр повинна бути парною.

Адреса байтового ЗовПр може бути парною чи непарною і відповідно

порти цих зовнішніх пристроїв підключаються до ліній молодшого і ста-

ршого байтів шини даних. Для роздільного звертання до цих портів де-

шифрування адрес здійснюється з урахуванням відповідних сигналів.

2.3. Структурна схема МПС з використанням МП i8086

Виконання команд можна подати послідовністю циклів шини (цик-

лів обміну), протягом яких МП звертається до пам’яті за командами чи

обмінюється даними з пам’яттю чи зовнішніми пристроями. Кожен цикл

шини ініціюється пристроєм шинного інтерфейсу і містить чотири

обов’язкових такти: Т1 – Т4. У такті Т1 видається адреса на об’єднану

шину адреси/даних, у такті Т2 здійснюється комутація напрямку переда-

чі, у тактах Т3 і Т4 – передача даних.

Залежно від значення сигналу на управляючій лінії МІН/МАКС

МП може працювати в мінімальному чи максимальному режимі. У за-

лежності від значення сигналу на цій управляючій лінії зміняється інтер-

претація восьми зовнішніх сигналів МП.

Page 65: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

65

У мінімальному режимі МП формує сигнали для управління внут-

рішньосистемним інтерфейсом МПС и використовується для побудови

однопроцесорних контролерів и мікроЕОМ. При цьому для побудови

блока центрального процесора використовується невелике число ІС: ге-

нератор К1810ГФ84, буферні регістри К1810ИР82/83 і шинні формувачі

К1810ИР86/87.

У максимальному режимі МП використовується для побудови ба-

гатопроцесорних систем (МПС), в котрих сигнали управління шиною

виробляються системним контролером К1810ВГ88 на основі коду, що

сформував МП.

Центральний процесор К1810ВМ88 на відміну від К1810ВМ86 має

8-бітову зовнішню шину даних. Арифметичний співпроцесор

К1810ВМ87 підключається паралельно центральному процесору і вико-

нує призначені для нього команди із загального потоку команд ЦП.

Обидва процесори фактично працюють поперемінно, причім співпроце-

сор є залежним від центрального процесора. Процесор вводу – виводу

К1810ВМ89 та ЦП є незалежними, і кожний із них виконує власний по-

тік команд, що дозволяє розпаралелити виконання програми.

Центральний процесор має вбудовані засоби для координації роботи

процесорів обох типів в багатопроцесорній системі. Ці засоби дозволя-

ють здійснювати розподіл та відключення магістралей за допомогою

сигналів по лініях запиту – надання каналу, а також за допомогою ВІС

арбітра магістралі К1810ВБ89.

Як показано на рис. 2.6, у мінімальній конфігурації, розрахованій на

прості системи, МП виробляє управляючі сигнали для системи (для

пам’яті й ПВВ), а в максимальній конфігурації, розрахованій на великі

складні системи, МП виробляє управляючі сигнали тільки для спеціалі-

зованої BІС контролера шини, що у свою чергу управляє системою.

читання, запис

D0-15

A0-15 AD0-15 МБР

МП

МБР

ОЗП

ПЗП

ППЗП

ПрВВ

ГТІ

RESET

Контр. ПДП

Рис. 2.6. Мінімальна конфігурація МПС

Контр. перер.

Page 66: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

66

2.4. Способи адресації 16-розрядного МП та оптимізація програм

Розглянемо стандартні режими адресації 16-розрядного МП i8086

(К1810ВМ86).

При виконанні будь-якої програми процесор звертається до

пам’яті, в якій зберігаються команди і дані. Спосіб або метод визна-

чення в команді адреси операнда або адреси переходу називається

режимом адресації або просто адресацією.

Принципово допускається 8 способів задання зміщення (виконав-

чої адреси) операндів, розміщених в основній пам’яті:

SI + <індексне зміщення>

DI + <індексне зміщення>

BP + <індексне зміщення>

BХ + <індексне зміщення>

BP + SI + < індексне зміщення>

BP + DI +< індексне зміщення>

BX + SI + <індексне зміщення>

BX + DI + <індексне зміщення>

В усіх випадках виконавча адреса операнда визначається як сума

вмісту зазначених регістрів і індексного зміщення, що являє собою деяке

число (одно- чи двобайтове).

У найбільш простому режимі адресації, названому прямою адреса-

цією, адреса знаходиться в самій команді. Однак використання цього

режиму, хоча і передбачено в більшості сучасних процесорів, призво-

дить до надмірної довжини команд, особливо в умовах, коли постійно

збільшується ємність пам’яті. Тому на даний час у процесорах застосо-

вують багато інших режимів адресації, спрямованих на досягнення на-

ступних цілей:

скорочення довжини команд (визначення адреси пам’яті

найменшим числом бітів);

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

пам’яті (обчислення адреси щодо поточної команди (так звана від-

носна адресація));

здійснення доступу до комірок пам’яті, адреси яких обчис-

люються при виконанні програми, що спрощує доступ до регуляр-

них структур даних;

Page 67: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

67

оперування адресами в такій формі, яка найзручніша для

таких структур даних, як масиви і стеки.

Режими адресації значно розширюють гнучкість і зручність корис-

тування системою команд.

У МП К1810 ефективна адреса пам’яті являє собою 16-бітове без-

знакове ціле, що є зміщенням щодо бази деякого сегмента. Повна (фізи-

чна) адреса пам’яті формується із залученням одного з сегментних регіс-

трів.

Режими адресації поділяють на прямі і непрямі.

При прямій адресації ефективна адреса або утримується в коман-

ді, або обчислюється з використанням значення, що знаходиться в ко-

манді, і вмісту, зазначеного в команді регістра (або двох регістрів).

При непрямій адресації ефективна адреса команди визначає ре-

гістр або комірку пам’яті, що містить остаточна ефективна адреса.

Регістрова адресація. При використанні регістрової адресації опе-

ранд знаходиться в одному із загальних регістрів МП, а в деяких коман-

дах – в одному із сегментних регістрів.

Приклади асемблерних команд із реєстровою адресацією:

MOV AX, SI ; Передати вміст SI в АХ: AX:= SI

ADD DI, ВХ ; Додати вміст ВХ до DI: DI := BX

XOR AL, АН ; Виключне АБО регістрів AL і АН: AL := AL AH

PUSH DS ; Запам’ятання DS в стеці

MOV BP, SP ; Пересилання змісту SP в ВР

Безпосередня (непосредственная – рос.) адресація. Безпосередні

операнди являють собою константи довжиною 8 чи 16 бітів, що розмі-

щуються в командах. Доступ до таких операндів здійснюється дуже

швидко, тому що вони знаходяться у внутрішній черзі команд і циклів

шини для зчитування операндів з пам’яті не потрібно. Безпосередні опе-

ранди змінити в ході виконання команди неможливо.

Приклади запису команд із безпосередніми операндами:

SUB AL, 30Н ; Відняти із вмісту AL число 4810 : AL := AL – 30h

MOV CL, 0АН ; Завантажити в регістр CL число 1010 : CL := 0Ah

AND AX, F000H ; Виділити старші 4 біти АХ: AX := AX ^ F000h

XOR DH, 1 ; Інвертувати молодший біт DH: DH := DH 01h

CMP BL, 40H ; Порівняти вміст BL з числом 64: BL – 40h

Page 68: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

68

MOV DX, offset mas ; Адреса (зміщення) масиву mas

; запам’ятається в DX

MOV DL, ‘!’ ; Завантажити в DL операнд – код ASCII символу “!”

Пряма адресація. Пряма адресація являє собою найпростіший ре-

жим адресації – ефективна адреса ЕА береться прямо з поля зміщення

команди, і ніякі регістри для його обчислення не залучаються.

Приклади асемблерних команд із прямою адресацією:

MOV AX, [0000] ; Занести в АХ число з комірки пам’яті [0000]

; AX := [0001, 0000]

MOV AX, GAMMA ; Завантажити в АХ змінну з іменем GAMMA

ADD TEMP, BL ; Додати число з BL до змінної з іменем TEMP

Непрямі (косвенные – рос.) способи адресації до пам’яті

У цих режимах ефективна адреса ЕА операнда знаходиться в одно-

му з базових (BP, BX) чи індексних регістрів (SI, DI), позначення якого

наводиться в квадратних дужках.

При адресації через регістри ВХ, SI або DI як сегментний регістр за

замовченням приймається DS; при адресації через ВР – SS. Таким чином,

непряма адресація через регістр ВР призначена для роботи зі стеком.

При необхідності можна явно вказати необхідний сегментний регістр.

Квадратні дужки в командах MOV необхідні для вказання по-

силання до адреси пам’яті, а не до безпосередніх даних.

Команда MOV AL, [0000] означає, що в АL заноситься число, що

знаходиться за адресою 0000 сегмента даних DS.

Команда MOV AL, [SI] означає, що необхідно занести в регістр AL

дані з адреси пам’яті, що зберігається в регістрі SI.

Команда MOV [DI], AL означає, що необхідно занести дані з регіс-

тра AL у комірку пам’яті, адреса якої знаходиться в регістрі DI.

Базова адресація. При базовій адресації ефективна адреса операн-

да є сумою значення зміщення і вмісту регістрів ВХ чи ВР.

Приклади запису команд із базовою адресацією:

MOV АХ, [ВР]10 ; Передати в АХ слово з комірки пам’яті,

; сегментна адреса якої знаходиться в SS, а зсув визначається як сума

; вмісту регістра ВР і константи 10

MOV АХ, [ВР+10] ; Те ж саме, що і попередня команда

ADD [BX]TEMP, СХ ; Додати СХ до слова у масиві пам’яті

; з іменем TEMP, адреса якого знаходиться в ВХ

Page 69: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

69

MOV AL, [BX] ; Передати в AL зміст комірки пам’яті,

; сегментна адреса якої находиться в DS, а зсув в ВХ

MOV DL, ES:[BX] ; Передати в DL зміст комірки пам’яті,

; сегментна адреса якої находиться в ES, а зсув – в ВХ

MOV DX, [BP] ; Передати в DX зміст комірки пам’яті,

; сегментна адреса якої находиться в SS, а зсув – в ВР

Індексна адресація. В режимі індексної адресації ефективна адре-

са обчислюється як сума зміщення, що знаходиться в команді, і вмісту

регістрів SI або DI.

Приклади команд з індексною адресацією:

MOV ARRAY[SI], АХ ; Передати АХ до масиву пам’яті ARRAY,

; сегментна адреса якого знаходиться в DS, a зсув в SI

ADD CX, ROW[DI] ; Додати до СХ елемент масиву пам’яті ROW,

; сегментна адреса якого знаходиться в DS, a зсув в DI:

; CX := CX + [DI + 1, DI]

XOR DL, MATRIX[SI] ; Виключне АБО операнда DL та операнда

; масиву пам’яті MATRIX, сегментна адреса якого знаходиться в DS,

; a зсув в SI

MOV AL, [DI] ; Передати в AL зміст комірки пам’яті,

; сегментна адреса якої находиться в DS, зсув в DI

Базова або індексна адресація із зсувом. Відносна адреса операнда

визначається сумою вмісту регістра (ВХ, ВР, SI або DI) і вказаного в

команді числа, яке досить невдало називають “зсувом”.

Приклади:

mas db 9, 8, 7, 6, 7, 9, 8, 2, 1 ; Масив символів

MOV ВХ, 2 ; ВХ-індекс елемента в масиві

MOV DL, mas[BX] ; B DL заноситься третій елемент масиву

В даному прикладі відносна адреса елемента масиву mas обчислю-

ється як сума вмісту регістра ВХ (2) і значення символічного позначення

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

таті в регістр DL буде завантажений елемент масиву mas з індексом 2,

тобто число 7. Передбачається, що базова адреса сегмента, в який вхо-

дить масив mas, завантажений в сегментний регістр DS. Такий же ре-

зультат можна одержати при виконанні наступної послідовності команд:

MOV BX, offset mas ; ВХ := відносна адреса комірки mas

MOV DL, 2[BX]

Page 70: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

70

В цій послідовності відносна адреса елемента масиву mas обчислю-

ється як сума вмісту регістра ВХ і додаткового зсуву, що задається конс-

тантою 2. Остання команда може бути записана в наступному вигляді:

MOV DL [BX + 2]

MOV DL [BX] + 2

Адресація за допомогою регістрів SI і DI здійснюється аналогічно.

При використанні регістра ВР слід пам’ятати, що як сегментний регістр

за умовчанням використовується регістр SS

Базово-індексна адресація. Відносна адреса операнда визначається

сумою вмісту базового і індексного регістрів. Допускається використан-

ня наступних пар:

[BX][SI]

[BX][DI]

[BP][SI]

[BP][DI]

Якщо як базовий регістр виступає ВХ, то як сегментний – DS (перші

дві команди). При використанні як базового регістра ВР сегментним ре-

гістром за умовчанням призначається SS (другі дві команди). При необ-

хідності можна явно вказати необхідний сегментний регістр.

Приклади

MOV BX, [BP][SI] ; B ВХ засилається слово із стека

; (сегментна адреса знаходиться в SS),

; а зсув обчислюється як сума вмісту ВР і SI

MOV ES:[BX + DI], AX ; B комірку пам’яті, сегментна адреса

; якої зберігається в ES, а зсув обчислюється як сума вмісту

; ВХ і DI, пересилається вміст АХ

Базово-індексна адресація із зсувом. Відносна адреса операнда ви-

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

а також додаткового зсуву. Допускається використання тих же пар регіс-

трів, що і в базово-індексному способі; так само діють і правила визна-

чення сегментних регістрів.

Приклади

MOV mas[BX][SI], 10 ; Символ з кодом 10 пересилається в комірку

; пам’яті, сегментна адреса якої зберігається у DS, а зсув дорівнює

; сумі вмісту ВХ, SI і відносної адреси осередку mas

Page 71: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

71

MOV AX[BP + 2 + DI] ; B AX пересилається із стека слово

; зсув якого дорівнює сумі ВР DI і добавки, яка дорівнює двом

Автоінкрементна (автодекрементна) адресація. При автоінкре-

ментній адресації адреса операнда обчислюється так само, як і при не-

прямій адресації, а потім здійснюється збільшення вмісту регістра: на

одиницю – для звернення до наступного байта, на два – для звернення до

наступного слова. Розмір операнда визначається кодом операції. ІNC GAMMA[DІ] ; Комірка пам’яті DEC BX ; Віднімання 1 із змісту Рг ВХ та завантаження

; нового значення в Рг ВХ (16 бітів)

Відносна адресація. У режимі відносної адресації ефективна адре-

са обчислюється як сума фіксованого зміщення, що знаходиться в ко-

манді, і поточного значення програмного лічильника PC. У МП К1810

відносна адресація застосовується тільки в командах умовних і безумов-

них переходів, викликах програм і управління ітераціями (або циклами).

Неявна адресація. Об’єкт, вмістом якого маніпулює команда, вка-

зується за допомогою першого байта команди разом з кодом операції без

виділення адресного поля для цієї мети.

Оптимізація програм

Значна частина розглянутих вище способів адресації служить для

звернення до елементів пам’яті. Таким чином, один і той же кінцевий

результат можна одержати за допомогою різних способів адресації. На-

приклад, всі три наведені нижче команди

MOV DL, mas + 3

MOV DL, mas[BX] ; У ВХ наперед занесено число 3

MOV DL, [SI][BX] ; У ВХ наперед занесено число 3 а в SI – зсув mas

приведуть до завантаження в регістр DL четвертого елемента масиву

mas (якщо виконуються описані в коментарях умови). Проте команди з

використанням різних способів адресації займають різний об’єм пам’яті

і виконуються за різний час. Так, перша з наведених вище команд зажа-

дає для виконання 15 машинних тактів, друга – 18, а третя – 16. Різниця

невелика, проте при багаторазовому виконанні команд у циклах сумар-

ний ефект може бути значний. З іншого боку, перші дві команди займа-

Page 72: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

72

ють в пам’яті по 4 байти, а третя – тільки 2. Таким чином, ретельний

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

за часом виконання або необхідною пам’яттю, а іноді і за тим, і за ін-

шим.

Час виконання команди можна визначити, розділивши потрібне для

її виконання число машинних тактів на частоту роботи конкретного про-

цесора. Остання величина коливається в дуже широких межах – від 1 до

100 МГц і більш. Тому час виконання команд оцінюють за кількістю

машинних тактів.

Повний час виконання команди можна подати у вигляді суми двох

складових: базового часу виконання команди, яке залежить від виду ко-

манди і способу адресації, і часу обчислення виконавчої адреси, якщо

операнд знаходиться в пам’яті. Друга складова теж залежить від способу

адресації. Розкид часів виконання для різних команд може бути вельми

значний. Так, команда складання вмісту двох регістрів вимагає 3 тактів,

прямого внутрішньосегментного переходу – 15 тактів, а команда ділення

– близько 100 тактів. Те ж, хоч і у меншій мірі, відноситься до часу об-

числення виконавчої адреси. Якщо зсув елемента пам’яті вказується в

регістрі (базовому або індексному), то до базового часу виконання ко-

манди слід додати 5 тактів, при базово-індексній адресації – 8, а у разі

базово-індексної адресації зі зсувом – 12.

Розглянемо декілька прикладів оптимізації програми при звертанні

до пам’яті і часу виконання.

1. Заповнення нулями регістра

MOV AX, 0 ; 4 такти, 3 байт

SUB AX, AX ; 3 такти, 2 байт

ХОR АХ, АХ ; 3 такти, 2 байт

Видно, що перша команда, будучи найбільш наочною, в той же час

поступається двом іншим за своїми оптимізаційними характеристиками.

2. Завантаження в регістр відносної адреси елемента пам’яті

MOV DX, offset mem ; 4 такти, 3 байт

LEA DX, mem ; 8 тактів, 4 байт

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

відношеннях. З іншого боку, команда LEA має більше можливостей,

оскільки в ній можна використовувати будь-які способи адресації.

3. Завантаження в пару регістрів повної двослівної адреси

Page 73: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

73

addr dd агrау_1 ; Повна адреса масиву аггау_1

; у двослівній комірці addr

MOV ВХ, word ptr addr ; Зсув 14 тактів, 4 байт

MOV ES, word ptr addr + 2 ; Сегмент, 14 тактів, 4 байт

LES BX, addr ; Отримання сегменту і зсуву 16 тактів, 4 байт

Результат виконання двох перших команд такий ж, як і однієї тре-

тьої. Проте використання команди LES (або IDS для завантаження сег-

ментного регістра DS) дає істотну економію і часу, і пам’яті.

4. Множення цілого числа на ступінь числа два

MOV ВХ, 32 ; 4 такті, 3 байті

MUL ВХ ; Множення, до 133 тактів, 2 байт

MOV CL, 5 ; Зсув, 4 такти, 3 байт

SAL AX, CL ; Зсув, 28 тактів, 2 байт

Останній приклад дещо специфічний. Множення на ступінь числа 2

(2, 4, 8, 16...) можна істотно прискорити, замінивши множення зсувом

вліво на число позицій, що дорівнює показнику ступеня. Кожний зсув

вліво на одну позицію приводить до множення на два. Таким чином,

перша і друга пари команд у наведеному вище прикладі еквівалентні за

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

в декілька разів. Ті ж міркування застосовні до ділення на ступінь числа

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

Page 74: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

74

3. АРХІТЕКТУРНІ ОСОБЛИВОСТІ 32-РОЗРЯДНОГО МП

PENTIUM

32-розрядні процесори можуть оперувати з 8-, 16- і 32-бітовими

операндами, рядками байтів, слів і подвійних слів, а також з бітами, бі-

товими полями і рядками бітів.

В архітектуру процесорів вводять засоби налагодження і тестуван-

ня.

3.1. Типи даних МП PENTIUM

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

знакові цілі числа, рядки байтів, цифр і символів, бітові рядки, покажчи-

ки і числа з плаваючою точкою. У сімействі х86 прийнято, що слова за-

писують в двох суміжних байтах пам’яті, починаючи з молодшого. Ад-

ресою слова є адреса його молодшого байта. Подвійні слова записують

в чотирьох суміжних байтах. Цей порядок називається Little-Endian

Memory Format. В інших сімействах процесорів застосовують і зворот-

ний порядок – Big-Endian Memory Format. Для взаємного перетворення

форматів слова є інструкція XCHG, подвійного слова – BSWAP (486+).

Біт (Bit) – одиниця інформації. Біт у пам’яті задається базою (ад-

ресою слова) і зміщенням (номером біта в слові).

Бітове поле (Bit Field) – група до 32 суміжних бітів, що розміщу-

ються не більш ніж у 4 байтах.

Бітовий рядок (Bit String) – набір суміжних бітів довжиною до 4

Гбітів.

Байт (Byte) – 8 бітів.

Числа без знака – байт (8 р.)/слово (16 р.)/подвійне

(32 р.)/збільшене у 4 рази (64 р.) слово (Unsigned Byte/ Word/Double

Word/Quade Word), 8/16/32/64 біти.

Цілі числа зі знаком: байт/слово/подвійне/збільшене у 4 рази слово

(Integer Byte/ Word/Double Word/Quade Word). Одиничне значення най-

Page 75: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

75

старшого біта (знак) є ознакою від’ємного числа, що зберігається в дода-

тному коді.

Двійково-десяткові числа (BCD – Binary Coded Decimal):

• 8-розрядні упаковані (Packed BCD), що містять два десяткових

розряди в одному байті;

• 8-розрядні неупаковані (Unpacked BCD), що містять один десят-

ковий розряд у байті (значення бітів 7 – 4 при додаванні і відніманні не-

суттєво, при множенні та діленні вони повинні бути нульовими).

Рядки байтів, слів і подвійних слів (Bit String, Byte String, Word

String, Double Word String) довжиною до 4 Гбайт.

Покажчики:

• довгий покажчик (48 біт) – 16-бітний селектор (чи сегмент) і 32-

бітне зміщення;

• короткий покажчик – 32-бітове зміщення;

• просто покажчик (32 біт, єдиний тип покажчика для 8086 і 80286)

– 16-бітовий селектор (чи сегмент) і 16-бітове зміщення.

Числа у форматі з плаваючою точкою і упаковані 80-бітові BCD-

числа обробляються блоками FPU процесорів класу 486 і вище, а також

співпроцесорами 8087/287/387. Упаковані 64- і 128-бітові дані обробля-

ються процесорами з ММХ (мультимедійні інструкції) і SSE (потокові

інструкції).

Дійсні числа у форматі з плаваючою крапкою:

одинарної точності (Single Precision), 32 біт – 23 біт мантиса,

8 біт порядок;

подвійної точності (Double Precision), 64 біт – 52 біт мантиса,

11 біт порядок;

підвищеної точності (Extended Precision), 80 біт – 64 біт манти-

са, 15 біт порядок.

Двійково-десяткові 80-бітові упаковані числа (18 десяткових ро-

зрядів і знак).

Упаковані дійсні числа одинарної точності у форматі з плаваю-

чою точкою обробляються блоком ХММ, який призначений для роботи з

векторними та скалярними інструкціями.

Упаковані цілі числа, знакові і беззнакові, обробляються блоком

ММХ:

• упаковані байти (Packed byte) – вісім байтів;

• упаковані слова (Packed word) – чотири слова;

Page 76: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

76

• упаковані подвійні слова (Packed doubleword) – два подвійних

слова;

• збільшене у 4 рази слово (Quadword) – одне слово.

Типи даних, які обробляються блоками FPU/MMX та XMM, наведені

на рис. 3.1.

Для 16-розрядних процесорів, природно, всі формати чисел для

блоків ММХ і ХММ недоступні.

32-розрядні процесори платформи х86 мають регістри, що підроз-

діляються на такі категорії:

• регістри загального призначення;

Рис. 3.1. Типи даних, які обробляються блоками FPU/MMX та XMM

Мантиса (др. частина) Порядок Зн

0 22 23 31 Число з ПК одинарної точ-ності

0

BCD0 BCD1 BCD2 . . . BCD17 ХХХ Зн

3 68 71 72 79 Упаковане двійково-десяткове ціле число

0 Число 0 Число 1

Упаковані подвійні слова для ММХ

63

Мантиса (др. частина) Порядок Зн

51 52 63 Число з ПК подвій-ної точності

0

0 Байт 0 Байт 1 Байт і-й Байт 7

63 Упаковані байти

для ММХ

0

Число 0 Число і Число 3

63

Упаковані слова

для ММХ

0

0

Число Збільшене у 4 рази слово для ММХ

63 0

Мантиса Порядок Мантиса Порядок Мантиса Порядок Мантиса Порядок

Упаковані числа з ПК одинарної точності ХММ

22 31 127 0

Page 77: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

77

• покажчик інструкцій;

• регістр прапорців;

• регістри сегментів;

• системні адресні регістри;

• керуючі регістри;

• регістри налагодження;

• регістри тестування;

• модельно-специфічні (залежні від конкретної моделі процесора)

регістри.

3.2. Регістри МП PENTIUM

Основні регістри процесора архітектури IA-32, з якими працюють

прикладні програми, показані на рис. 3.2.

Ці регістри відносяться до видимої для прикладних програм части-

ни архітектури х86 і являють собою розширення набору регістрів 16-

розрядних процесорів 8086/8088 і 80286 (розширення виділені сірим

кольором).

У 16-розрядних процесорів регістри загального призначення AX,

BX, CX, DX складаються з двох 8-бітових половинок, до яких можна не-

залежно звертатися за символічними іменами АН, ВН, СН, DH (старші

байти – High) і AL, BL, CL, DL (молодші байти – Low).

0 16 15 31

16 0 16 15 0 31

Регістри загального призначення

АН AX AL 16

BН BX BL

CН CX CL

DН DX DL

SI DI BP SP

EAX

EBX

ECX

EDX

ESI

EDI

EBP

ESP

РГ сегментів

CS

SS

DS

ES

FS

GS

Код

Стек

Дані

Показчик інструкцій і Рг прапорців

IP

FLAGS

EIP

EFLAGS

Рис. 3.2. Загальні Рг 32-розрядного МП

Page 78: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

78

Регістри-покажчики SP (Stack Pointer – покажчик стека), ВР (Base

Pointer – базовий регістр) та індексні регістри SI (Source Index – індекс

джерела), DI (Destination Index – індекс призначення) допускають тіль-

ки 16-бітне звертання.

Адреса поточної інструкції зберігається в 16-бітному покажчику

команд IP (Instruction Pointer).

Регістри в командах можуть адресуватись явно. У ряді команд іс-

нує неявне використання регістрів:

АХ – множення, ділення, введення і виведення слова;

AL – множення, ділення, введення і виведення байта; десяткова

арифметика, трансляція (XLAT);

АН – множення і ділення байта;

BX – трансляція;

CX – лічильник циклів і покажчик довжини рядкових операцій;

CL – зміщення із вказуванням змінної;

DX – множення і ділення слова, введення і виведення з непря-

мою адресацією;

• SP – операції зі стеком;

• SI, DI – рядкові операції.

У процесорах IA-32 всі ці регістри розширені до 32 біт, і до колиш-

нього позначення їх імен додалася приставка Е (Extended – розширений).

Відсутність приставки в імені означає посилання на молодші 16 біт роз-

ширених регістрів.

У реальному режимі за замовчуванням розрядність адреси і да-

них – 16 біт.

У захищеному режимі розрядність адреси і даних за замовчуван-

ням визначається дескриптором кодового сегмента.

Покажчик інструкцій EIP містить зміщення наступної інструкції,

що виконується, щодо бази сегмента коду. При 16-бітовій адресації ви-

користовуються тільки молодші 16 біт (IP).

Регістр прапорців EFLAGS є розширенням регістра FLAGS до 32

бітів (рис. 3.3).

0

0 .

..

0 0 0 0 0 0 0 V I P x

V I F x

A C x

V M x

R F x

0

N T x

IOPL

O F s

D F c

I F x

T F x

S F s

Z F s

0 A F s

0 P F s

1 C F s

Рис. 3.3. Регістр прапорців EFLAGS (x – системний прапорець, s – прапорець стану, с – керуючий прапорець)

0

Page 79: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

79

Біти 0 – 15, визначені для 8086 і 80286, мають колишнє призначен-

ня. Прапорці стану OF, SF, ZF, AF, PF і CF зберігають ознаки резуль-

татів виконання арифметичних і логічних операцій над операндами, ро-

зміщеними в регістрах загального призначення й у пам’яті. Операції

пересилання даних на прапорці стану впливу не здійснюють. Значен-

ня цих прапорців аналізується при виконанні умовних інструкцій. Крім

прапорців стану в регістрі є управляючі та системні прапорці, що

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

апаратних переривань (IF) і на напрямок руху в рядкових операціях

(DF). Прапорці стану можуть бути скопійовані в регістр АН і, навпаки,

завантажені з нього. Крім того, прапорці стану можуть бути завантажені

з блока FPU, і тоді результати виконання інструкцій у FPU можна вико-

ристовувати в умовних інструкціях.

Призначення бітів регістра EFLAGS:

• ID (Id Flag) – прапорець доступності команди ідентифікації

CPUID (P5+ і деякі 486).

• VIP (Virtual Interrupt Pending) – віртуальний запит переривання

(P5+).

• VIF (Virtual Interrupt Flag) – віртуальна версія прапорця IF (до-

зволу переривання) для багатозадачних систем (P5+).

• AC (Alignment Check) – прапорець контролю вирівнювання. При

виконанні програм з рівнем привілеїв 3 у випадку звертання до операн-

да, що не вирівняний за відповідною межею (2, 4, 8 байтів), і при вста-

новленому прапорці АС відбувається виключення #АС з нульовим кодом

похибки. На рівнях привілеїв 0, 1, 2 контроль вирівнювання не здійсню-

ється (486+).

• VM (Virtual 8086 Mode) – у захищеному режимі включає режим

віртуального процесора 8086. Спроба використати привілейовані інстру-

кції у цьому режимі викликає виключення #GP. Біт може встановлюва-

тися тільки в захищеному режимі: інструкцією IRET на нульовому рівні

чи привілеїв переключенням задач на будь-якому рівні привілеїв. На біт

не діє інструкція POPF, а інструкція PUSHF у цей біт завжди заносить 0.

Його одиничне значення може зберегтися тільки в EFLAGS, що зберіга-

ється при перериванні, переключенні задач чи переході в режим SMM.

• RF (Resume Flag) – прапорець поновлення, використовується ра-

зом з регістрами точкою зупину.

Page 80: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

80

• IOPL (Input/Output Privilege Level) – рівень привілеїв введення-

виведення.

• NT (N sted Task Flag) – прапорець вкладеної задачі.

• OF (Overflow Flag) – прапорець переповнення. Встановлюється,

якщо результат арифметичної операції не вміщується в операнді призна-

чення.

• DF (Direction Flag) – прапорець керування напрямком у рядкових

операціях. При одиничному значенні індексні регістри, що беруть участь

у рядкових операціях, автоматично декрементуються на кількість байтів

операнда, при нульовому – інкрементуються. Прапорець керування про-

грамно інструкціями CLD і STD.

• IF (Interrupt-enable Flag) – прапорець керування перериваннями.

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

переривань. На цей прапорець можна впливати програмно, явними ін-

струкціями (CLI і STI) і неявними інструкціями відновлення регістра

прапорців; процесор маніпулює прапорцем і автоматично, при обробці

переривань. У захищеному режимі з’являються додаткові тонкощі.

• TF (Trap Flag) – прапорець трасування (покрокового режиму).

При його встановленні після виконання кожної команди викликається

внутрішнє переривання типу 1 (INT I).

• SF (Sign Flag) – прапорець знака. Вказує на одиничне значення

старшого біта результату — ознаку від’ємного числа.

• ZF (Zero Flag) – прапорець нульового результату.

• AF (Auxiliary Flag) – прапорець додаткового переносу (позики) у

тетраді для десяткової арифметики.

• PF (Parity Flag) – прапорець паритету, встановлюється при пар-

ному числі одиниць результату.

• CF (Cany Flag) – прапорець переносу (позики) старшого біта в

арифметичних операціях. Цей прапорець може бути програмно встанов-

лений чи скинутий спеціальними інструкціями (STC, CLC, CMC); завдя-

ки цій властивості його широко використовують для сигналізації умови

завершення процедур (наприклад, сигналізації про помилки).

Регістри сегментів містять 16-бітні покажчики (в реальному ре-

жимі) чи селектори дескрипторів (у захищеному режимі) сегментів CS

(Code Segment – сегмент кодів команд), SS (Stack Segment – сегмент сте-

ка), DS (Data Segment – сегмент даних), ES, FS і GS – додаткові сегменти

даних. Сегментних регістрів FS і GS у 16-розрядних процесорах не було.

Вміст сегментних регістрів не може бути модифікованим (збільшеним

Page 81: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

81

чи зменшеним), вони допускають лише завантаження і збереження вміс-

ту.

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

до пам’яті. Для багатьох типів звертань можливе застосування альтерна-

тивних сегментних регістрів, що вводиться префіксами команд CS:, SS:,

DS:, ES: FS; чи GS:. З кожним із шести сегментних регістрів зв’язані

програмно-недоступні сховані регістри дескрипторів (їх ще називають

Segment Descriptor Cache – кеш сегментних регістрів), завантажуються

автоматично при завантаженні відповідних сегментних регістрів.

У захищеному режимі в регістри дескрипторів з таблиці дескрип-

торів завантажуються 32-бітова базова адреса, 32-бітовий ліміт (розмір

сегмента) і атрибути сегментів. За вмістом цих схованих регістрів при

кожному звертанні до пам’яті виконуються обчислення лінійної адреси і

перевірка захисту; причому саме ці регістри задають властивості сегмен-

тів як у захищеному, так і в реальному режимах. Образ цих 96-бітових

регістрів доступний у режимі SMM і внутрішньосхемної емуляції (ICE),

формати специфічні для кожної моделі (покоління) процесорів. У реаль-

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

(розмір сегмента) фіксований – 64 кбайт, атрибути не використовуються,

а як базова адреса заноситься значення сегментного регістра, зрушене на

4 біт уліво. В захищеному режимі ліміт може задаватися в межах 1 байт

– 4 Гбайти. Позаштатним переключенням із захищеного в реальний ре-

жим можна домогтися і нестандартного розміру сегментів.

Крім регістрів загального призначення, необхідним для викорис-

тання прикладними програмами, процесори мають ряд регістрів систем-

ного призначення. Цих регістрів у процесорах 8086/88 не було, а в про-

цесорі 80286 була присутня лише частина з них і не в повному обсязі.

Керуючі регістри (Control Registers) CR0, CR1, CR2, CR3 зберіга-

ють ознаки стану процесора.

Регістр СR0 містить у собі біти регістра MSW процесора 80286. Для

забезпечення програмної сумісності команди LMSW і SMSW стосують-

ся тільки цих молодших чотирьох бітів.

Призначення бітів регістра СR0:

РЕ (Protection Enable) – дозвіл захисту. Встановлення цього пра-

порця інструкцією LMSW чи LOAD СR0 переводить процесор у захи-

щений режим, скидання прапорця (повернення в реальний режим) мож-

ливе тільки за інструкцією LOAD СR0. Скидання біта РЕ є частиною

Page 82: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

82

досить довгої послідовності інструкцій, що підготовляють коректне пе-

реключення в реальний режим.

МР (Monitor Processor Extension) – моніторинг співпроцесора.

Дозволяє викликати виключення #NM за кожною командою WAIT при

TS = 1. При виконанні програм для процесорів 286/287 і 386/387 на про-

цесорах 486DX і старше біт МР повинен бути встановлений.

ЕМ (Processor Extension Emulated) – емуляція співпроцесора.

Встановлення цього прапорця викликає появу виключення #NM при ко-

жній команді, що відноситься до співпроцесора, який дозволяє прозоро

здійснювати його програмну емуляцію.

TS (Task Switch) – переключення задач. При встановленні цього

прапорця наступна команда, що відноситься до співпроцесора, викликає

виключення #NM, що дозволяє програмно визначити, чи відноситься

контекст співпроцесора до поточної задачі. Біт скидається інструкцією

CLTS.

Поєднання МР = 0, ЕМ = 0, TS = 0, встановлене за апаратним ски-

данням, забезпечує повну сумісність з 8086/88 (виключення #NM не ви-

конується). Поєднання МР = 1, ЕМ = 0 використовується при наявності

співпроцесора, а МР = 0, ЕМ = 1 при його програмній емуляції.

EТ (Extension Type) – індикатор підтримки інструкцій мате-

матичного співпроцесора. Використовується в процесорах 486+, для

486SX – ЕT = 0, для інших процесорів – ЕT = 1.

NE (Numeric Error) – дозвіл стандартного (для Intel, але не для PC)

механізму повідомлення про помилку FPU через генерацію виключення

(486+).

WP (Write Protect) – дозвіл захисту сторінок пам’яті.

AM (Alignment Mask) – дозвіл контролю вирівнювання (контроль

вирівнювання виконується тільки на рівні привілеїв 3 при AM = 1 і пра-

порця AC = 1).

NW (Not Writethrough) – заборона наскрізного запису кеша і циклів

анулювання.

CD (Cache Disable) – заборона заповнення кеша (влучення в рані-

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

PG (Paging Enable) – включення механізму сторінкової переадреса-

ції пам’яті.

Регістр CR1 не використовується.

Регістр CR2 (Page Fault Linear Address) зберігає 32-бітову лінійну

адресу, за якою була отримана остання відмова сторінки пам’яті.

Page 83: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

83

Регістр CR3 (Page Directory Base Register) у старших 20 бітах збе-

рігає фізичну базову адресу таблиці каталогу сторінок. З молодших 12

бітів у процесорах 486+ використовуються такі:

PCD (Page-Level Cache Disable) – заборона кешування сторінки

(одне з джерел апаратного сигналу PCD для керуваня зовнішнім кешем).

PWT (Page-Level Writes Trough) – кешування сторінки з наскріз-

ним записом (одне з джерел апаратного сигналу PWT для керування

зовнішнім кешем).

Регістр CR4 (є присутнім у процесорах Pentium і старше) містить

біти дозволу архітектурних розширень.

Призначення бітів регістра CR4:

VME (Virtual-8086 Mode Extensions) – дозвіл на використання вір-

туального прапорця переривань у режимі V86, що дозволяє підвищити

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

машин.

PVI (Protected-Mode Virtual Interrupts) – дозвіл на використання

віртуального прапорця переривань у захищеному режимі.

TSD (Time Stamp Disable) – перетворення інструкції RDTSC (чи-

тання лічильника міток реального часу) на привілейовану.

DE (Debugging Extensions) – розширення налагодження (дозвіл то-

чок зупину на інструкціях звертання до заданих портів вводу-виводу).

PSE (Page Size Extension) – розширення розміру сторінки (4 кбайт

і 4 Мбайт).

РАЕ (Physical Addres Extension) – розширення фізичної адреси

(сторінки 4 кбайт і 2 Мбайт, 36-бітова адресація).

MCE (Machine-Check Enable) – дозвіл машинного контролю (ви-

роблення виключення #МС за машинною помилкою, Р5+).

PGE (Paging Global Extensions) – дозвіл глобальності в сторінковій

переадресації. При PGE = 1 за командою MOV CR3 у TLB очищаються

тільки входження із невстановленим бітом глобальності G (Р6+).

РСЕ (Performance-monitoring Counter Enable) – дозвіл звертання

до лічильників подій (інструкція RDPMC) на будь-якому рівні привілеїв.

Системні адресні регістри призначені для посилань на сегменти і

таблиці в захищеному режимі.

Регістри GDTR (Global Descriptor Table Register) і IDTR (Interrupt

Descriptor Table Register) програмно завантажуються 6-байтовими опе-

рандами, що включають 32-бітову лінійну базову адресу і 16-бітовий

ліміт глобальної таблиці дескрипторів і таблиці дескрипторів перери-

Page 84: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

84

вань. У регістр задачі TR (Task Register) і регістр селектора локальної

таблиці дескрипторів LDTR (Local Descriptor Table Register) завантажу-

ються 16-бітові селектори дескрипторів сегмента стану задачі TSS і ло-

кальної таблиці дескрипторів LDT. Це завантаження викликає автомати-

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

базової адреси і ліміту, а також полів атрибутів у зв’язані з ними неви-

димі регістри дескрипторів.

Регістри налагодження (Debug Register) призначені для задання і

керування налагодженими точками зупину.

Регістри GDTR (Global Descriptor Table Register) і IDTR (Interrupt

Descriptor Table Register) програмно завантажуються 6-байтовими опе-

рандами, що включають 32-бітову лінійну базову адресу і 16-бітовий

ліміт глобальної таблиці дескрипторів і таблиці дескрипторів перери-

вань. У регістр задачі TR (Task Register) і регістр селектора локальної

таблиці дескрипторів LDTR (Local Descriptor Table Register) завантажу-

ються 16-бітові селектори дескрипторів сегмента стану задачі TSS і ло-

кальної таблиці дескрипторів LDT. Це завантаження викликає автомати-

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

базової адреси і ліміту, а також полів атрибутів у зв’язані з ними неви-

димі регістри дескрипторів.

Регістри DR0...DR3 (Linear Breakpoint Address 0...3) зберігають

32-бітові лінійні адреси точок зупину.

Регістри DR4, DR5 у 80386 і 486 не використовуються, звертання

до них еквівалентне звертанню до регістрів DR6, DR7. У процесорі

Pentium при включеному розширенні налагодження звертання до цих

регістрів викликає виключення неприпустимого коду операції (#UD).

Регістр DR6 (Breakpoint Status) відбиває стан контрольної точки.

Регістр DR7 (Breakpoint Control) керує встановленням контроль-

них точок.

Склад регістрів тестування (Test Register) варіюється залежно від

типу процесора. Процесори 80386 мали тільки два регістри, призначені

для тестування кеша сторінкової переадресації – TR6 і ТR7, для процесо-

ра 486 склад регістрів розширений: TR3 – регістр даних внутрішнього

кеша TR4 – тестовий регістр стану кеша, TR5 – керуючий регістр тесту-

вання кеша, TR6 (Test Control) – керуючий регістр для тесту кешування

сторінок, TR7 (Test Status) – регістр даних для тесту кешування сторінок.

Page 85: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

85

У процесорах Pentium і старше тестові регістри входять до групи

модельно-специфічних регістрів MSR. Для цих процесорів звертання до

регістрів TRx викликає виключення #UD неприпустимого коду операції.

Модельно-специфічні регістри MSR (Model-Specific Registers)

призначені для керування розширеннями налагодження, моніторингом

продуктивності, машинним контролем, кешуванням областей фізичної

пам’яті й інших функцій. Їх призначення прив’язується до мікроархітек-

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

доступ привілейований у регістрі ЕСХ, що дозволяє необмежено (до 4

млрд) збільшувати число цих регістрів. У табл. 3.1 наведено призначен-

ня регістрів 32-розрядних процесорів.

Таблиця 3.1

Призначення регістрів 32-розрядних процесорів Режим Реальний Захищений Віртуального 8086

Регістри Заванта-

ження

Збережен-

ня

Заванта-

ження

Збережен-

ня

Заванта-

ження

Збережен-

ня

Загального

призначення Так Так Так Так Так Так

Сегментів Так Так Так Так Так Так

Прапорців Так Так Так Так IOPL1 IOPL1

Керуючі Так Так PL = 0 PL = 0 Немає Так

GDTR, IDTR Так Так PL = 0 Так Немає Так

LDTR, TR Немає Немає PL = 0 Так Немає Немає

Налагодження Так Так PL = 0 PL = 0 Немає Немає

Тестування Так Так PL = 0 PL = 0 Немає Немає

MSR PL = 0 PL = 0 PL = 0 PL = 0 PL = 0 PL = 0 1PUSHF і POPF чуттєві до рівнів привілеїв

3.3. Організація пам’яті МП PENTIUM

Пам’ять для 32-розрядних процесорів 80x86 підрозділяється на

байти (8 бітів), слова (16 бітів), подвійні слова (32 біти). Слова запису-

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

є адреса його молодшого байта. Подвійні слова записуються в чотирьох

суміжних байтах, знов-таки починаючи з молодшого байта, адреса якого

і є адресою подвійного слова.

Більш великими одиницями є сторінки і сегменти.

Page 86: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

86

Пам’ять може логічно організовуватись у вигляді одного чи безлічі

сегментів змінної довжини (у реальному режимі – фіксованої). Сегменти

можуть вивантажуватись на диск і в міру необхідності з нього підкачува-

тись у фізичну пам’ять. Крім сегментації, у захищеному режимі можливе

розбиття (Paging) логічної пам’яті на сторінки розміром 4 кбайт, кожна з

яких може відображатись на будь-яку область фізичної пам’яті.

Починаючи з 5-го покоління, з’явилася можливість збільшення ро-

зміру сторінки до 4 Мбайт. Сегментація і розбивка на сторінки можуть

застосовуватись в будь-яких поєднаннях. Сегментація є засобом орга-

нізації логічної пам’яті, використовуваним на прикладному рівні.

Розбивання на сторінки застосовується на системному рівні для ке-

рування фізичною пам’яттю.

Стосовно пам’яті розрізняють три адресних простори: логічний,

лінійний і фізичний.

Основним режимом роботи 32-розрядних процесорів вважається

захищений режим, у якому працюють всі механізми перетворення адре-

сних просторів (рис. 3.4).

14 Індекс дескриптора лог. або віртуальної адреси

32 Лінійна адреса

Фізична

пам’ять

Блок сторінкової

переадресації (необов’язковий)

Блок

сегментації

INDEX

BASE DISPLACEMENT х

SCALE

1, 2, 4, 8

Обчислення ефективної адреси

+ 32 Ефективна адреса

32 Фізична

адреса

Селектор

(Сегмент. Рг)

Рис. 3.4. Формування адреси пам'яті 32-розрядних процесорів

у захищеному режимі

Page 87: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

87

Логічна адреса, також названа віртуальною, складається з селекто-

ра сегмента (у реальному режимі – просто адреси сегмента) і ефективної

адреси, названої також зміщенням.

Ефективна адреса формується підсумовуванням компонентів

BASE, INDEX, DISPLACEMENT із врахуванням масштабу SALE. Оскі-

льки кожна задача може мати до 16 К селекторів, зміщення, обмежене

розміром сегмента, може досягати 4 Гбайт. Увесь логічний адресний

простір для кожної задачі може досягати 64 Тбайт.

Блок сегментації транслює логічний адресний простір у 32-бітовий

простір лінійних адрес.

Лінійна адреса утворюється додаванням базової адреси сегмента

до ефективної адреси.

Базова адреса сегмента в реальному режимі утворюється множен-

ням вмісту використовуваного сегментного регістра на 16 (як і в 8086).

У захищеному режимі базова адреса завантажується з дескриптора, що

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

сегментний регістр.

32-бітова фізична адреса пам’яті утворюється після перетворення

лінійної адреси блоком сторінкової переадресації. Вона виводиться на

зовнішню шину адреси процесора. В найпростішому випадку (при відк-

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

лінійною.

Включений блок сторінкової переадресації здійснює трансляцію

лінійної адреси на фізичну сторінками розміром 4 кбайт (для старших

поколінь процесорів також можливі сторінки розміром 2 чи 4 Мбайт).

Блок забезпечує розширення розрядності фізичної адреси процесорів

шостого покоління до 36 біт. Блок переадресації може включатися тіль-

ки в захищеному режимі.

Для звертання до пам’яті процесор (разом із зовнішньою схемою)

формує шинні сигнали MEMWR# (Memory Write) і MEMRD# (Memory

Read) для операцій запису і читання відповідно. Шина адреси розрядніс-

тю 32 біт дозволяє адресувати 4 Гбайт фізичної пам’яті, але в реальному

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

У реальному режимі адресації пам’яті забезпечується сумісність із

процесором 8086, що своєю 16-розрядною адресною шиною охоплює

простір фізичної пам’яті в 1 Мбайт. Для сумісності з 80286 32-розрядні

процесори повторюють його помилку, пов’язану з переносом, що вини-

кає при додаванні адреси сегмента з ефективною адресою. При обчис-

Page 88: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

88

ленні фізичної адреси можливе виникнення переносу, що викликає появу

одиниці на лінії А20 шини адреси. Максимальне значення адреси в реа-

льному режимі 10FFEF досягається при Seg = FFFFh і ЕA = FFFFh. Для

забезпечення повної програмної сумісності з 8086 у PC використовуєть-

ся вентиль Gate A20, який примусово скидає біт А20 системної шини

адреси. Вентиль у PC керується через програмно-керуємий біт контро-

лера клавіатури 8042 чи більш швидким способом (Gate A20 Fast

Control), обумовленим чіпсетом системної плати.

У реальному режимі розмір сегмента фіксований – як і в 8086, він

складає 64 кбайти (FFFFh). Спроба використання ефективної адреси, що

виходить за межі сегмента, при 32-бітовій адресації викликає виключен-

ня #GP. При 16-бітовій адресації при обчисленні ефективної адреси мо-

жливий перенос у розряд А16 ігнорується і сегмент “звертається в кіль-

це” (як і в 8086). Засоби контролю стежать і за переходом через межу

сегмента під час звертання за “прикордонною” адресою. При спробі ад-

ресації до слова, що має зміщення FFFFh, чи подвійного слова зі змі-

щенням FFFDh-FFFFh (їх старші байти виходять за межі сегмента), чи

виконання інструкції, хоча б один байт якої не вміщається в даному сег-

менті, процесор здійснює виключення #GP. При спробі виконання ін-

струкції співпроцесора (ESCAPE) з операндом пам’яті, що не вміщаєть-

ся в сегменті, здійснюється виключення 9 – Processor Extension Segment

Overrrun Interrupt (тільки для 80386).

Схема розподілу першого мегабайта пам’яті комп’ютера наведена в

табл. 3.2.

Найнижчі елементи пам’яті (адреси від 00000 до 003FF) включають

таблицю векторів переривань, що складається з 32-розрядних адрес. Ці

адреси, що називають векторами переривань, використовуються проце-

сором, коли виникають програмні або апаратні переривання. Вище над

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

BIOS, в яке включені підпрограми керування клавіатурою, консоллю,

принтером і календарем. Підпрограми BIOS завантажуються з прихова-

ного системного файла io.sys на завантажувальному диску MS-DOS. Яд-

ром MS-DOS є підпрограми (сервісні), які завантажуються з системного

файла msdos.sys.

Опис даних, які використовуються BIOS, наведені в табл. 3.3.

Page 89: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

89

Таблиця 3.3

Дані, що використовуються в BIOS

Зміщення (се-

гмент 0400)

Опис

0000 – 0007 Адреси портів СОМ 1 – COM4

0008 – 000F Адрес портів LPT1 – LPT4

0010 – 0011 Список встановленого устаткування

0012 Прапорець ініціалізації

0013 – 0014 Розмір пам’яті в кбайтах

0015 – 0016 Пам’ять для каналу введення – виведення

0017 – 0018 Прапорці стану клавіатури

0019 Зберігання натиснутих клавіш

001A – 001B Покажчик буфера клавіатури (початок)

001C – 001D Покажчик буфера клавіатури (кінець)

001E – 003D Буфери клавіатури

001E – 0048 Дані про дискети

0049 Поточний відеорежим

004A – 004B Кількість колонок на екрані

004C – 004D Довжини буфера регенерації (у байтах)

004E – 004F Початкове зміщення буфера регенерації

0050 – 005F Позиції курсора, відеосторінки 1– 8

0060 Остання лінія курсора

Таблиця 3.2

Схема розподілу першого мегабайта пам’яті 00000 Таблиця векторів переривання

640 кбайт

00400 Область параметрів DOS

Ядро DOS, драйвера приладів і т. д.

Програмне забезпечення BIOS

Ядро DOS, драйвера пристроїв і т. д.

Резидентна частина COMMAND.COM

(Доступна пам’ять для транзитних програм)

9FFFF Транзитна частина COMMAND.COM

A0000 Буфер для графічних зображень

B0000 Буфер для текстових даних MDA

B8000 Буфер для текстових даних з кольором

C0000 Зарезервовано

F0000 FFFFF

ROM BIOS

Page 90: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

90

Закінчення таблиці 3.3

0061 Початкова лінія курсора

0062 Поточний номер відеосторінки

0063 – 0064 Базова адреса активного дисплея

0065 Режим CRT (MDA, CGA)

0066 Регістри для CGA

0067 – 006B Дані про касету

006C – 0070 Простір даних таймера

Вище над ядром MS-DOS розташовуються буфери файлів і заван-

тажувані драйвери (з файла config.sys). Резидентна частина командного

процесора MS-DOS завантажується з файла, званого command.com. Ко-

мандний процесор інтерпретує команди, що вводяться для MS-DOS, і

завантажує виконувані програми, розташовані на диску.

Процедура початкового завантаження

Коли операційна система комп’ютера починає проводити початкове

завантаження (booted), відбувається наступне.

процесор робить перехід на програму ініціалізації в ROM BIOS.

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

вважається стартовим. Завантажувальний сектор містить програми, що

починають виконуватися відразу ж після того, як вводяться в пам’ять. Ці

програми послідовно прочитують io.sys і msdos.sys. Останньою програ-

мою, що переписується в пам’ять з диска, буде командний процесор з

файла command.com.

резидентна частина командного процесора залишається в

пам’яті протягом усього часу, поки працює комп’ютер. Вона видає пові-

домлення про критичні помилки і викликає підпрограми обробки

натиснення клавіш <Ctrl+Break>. Програма ініціалізації прочитує файл

autoexec.bat, необхідний для MS-DOS. Тимчасова частина завантажуєть-

ся у верхню пам’ять для інтерпретації команд, що вводяться з клавіату-

ри. Нарешті, все керування бере на себе командний процесор.

Далі DOS переглядає файл config.sys. Нижче наведено вміст файла

config.sys для роботи з Windows:

Рядок Твердження 1 DOS=HIGH

2 LASTDRIVE=G:

3 DEVICEHIGH /L:l, 14016 =MTMCDAI.SYS /D:MTMIDE01

4 DEVICEHIGH /L:1,12048 =SETVER.EXE

Page 91: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

91

у першому рядку записана команда завантаження DOS у верхні

ділянки пам’яті, щоб звільнити якомога більше основної пам’яті;

у рядку 2 вказується, що останнім символом для позначення ди-

сків буде символ G. Таким способом у системі можна ввести позначення

для семи дисків: А, В, C, D, Е, F, H, G;

у рядку 3 вказується, як завантажити драйвер для дисковода CD-

ROM (mtmcdai.sys), щоб до нього був доступ з командного рядка DOS.

Слово DEVICEHIGH говорить про те, що драйвер повинен бути заван-

тажений у верхню пам’ять;

у рядку 4 вказується на необхідність завантаження програми

setver.ехе, яка повідомляє версію завантаженої MS-DOS прикладним

програмам.

Файл autoexec.bat. Після виконання команд в config.sys операційна

система переглядає і виконує кожну команду у файлі autoexec.bat, що

знаходиться в кореневому каталозі на диску. Наприклад, це можуть бути

наступні команди:

Рядок Команда 1 @ЕСНО OFF

2 PROMPT $p$g

3 SETTEMP=C:\TMP

4 SET WINTEMP=C:\TMP

5 PATH C:\WINDOWS; C:\WINDOWS\COMMAND

6 LH /L:l.36224 MSCDEX.EXE /DrMTMIDEOl /M:10

у рядку 1 відключається повторення команд (луна) на екрані,

коли виконується цей файл;

у рядку 2 проводиться настройка виду команд і повідомляється,

що після позначення каталогу повинен слідувати символ (>). Наприклад,

якщо поточним каталогом є WINDOWS, то запрошення ввести команду

виглядатиме так: С: \WINDOWS;

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

для зберігання тимчасових файлів, створюваних прикладними програ-

мами;

у рядку 4 ідентифікується каталог, що використовуватиметься

для зберігання тимчасових файлів, створюваних операційним середови-

щем Windows;

рядку 5 указуються шляхи, за якими операційна система шука-

тиме необхідні програми, якщо їх немає в поточному каталозі. Напри-

клад, якщо поточним є кореневий каталог диска С і буде введена коман-

да MEM, операційна система шукатиме програму з ім’ям mem.com або

Page 92: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

92

mem.exe у поточному каталозі (С:\). Якщо програма не буде знайдена, то

операційна система продовжить пошук в каталозі С:\WINDOWS. Якщо і

там не буде виявлений відповідний файл, то наступним каталогом для

пошуку буде С: \WINDOWS\COMMAND. Після знаходження необхідно-

го файла mem.exe він буде виконаний;

у рядку 6 проводиться завантаження програми mscdex.exe для

роботи з дисководом CD-ROM з командного рядка.

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

дисплея, вона викликає підпрограму з ROM BIOS, яка заносить символ в

певне місце у відеопам’яті. У кольоровому текстовому режимі початок

відеопам’яті знаходиться за адресою 8000. У режимі кольорової графіки

карта пам’яті починатиметься з адреси А0000. Розробники додатку для

DOS прагнуть безпосередньо записувати текст і графіку у відеопам’ять і

не використовувати вбудовані підпрограми DOS, тому що такий спосіб

підвищує швидкість роботи програм. У додатках для Windows такий

спосіб мало підходить через конфлікти з системою, яка самостійно зай-

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

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

зв’язку із зовнішніми пристроями. Для них в пам’яті BIOS виділено про-

стір від 0040:0000 до 0040:0007, що включає список адрес активних пор-

тів. Звичайно система має два послідовні порти, тому адреси будуть

встановлені, як показано табл. 2.2. Якщо досліджувати системні устано-

вки, можна побачити, що в Windows порт СОМ1 дійсно використовує

адреси 03F8 – 03FF, а COM2 – 02F8 – 02FF.

3.4. Способи адресації МП PENTIUM

Система команд 32-розрядних процесорів передбачає 11 режимів

адресації. При цьому тільки в двох випадках операнди не зв’язані з

пам’яттю. Це операнд, що береться з кожного 8-, 16- чи 32-бітового регі-

стра процесора, і безпосередній операнд (8, 16 чи 32 біт), що міститься в

самій команді.

Безпосередня адресація. Регістр сегмента не використовується.

Наприклад, MOV EAX, 12345678; завантаження в ЕАХ const = 1234567816.

Регістрова адресація. Наприклад, MOV EAX, ECX.

Інші дев’ять режимів так чи інакше звертаються до пам’яті.

При звертанні до пам’яті ефективна адреса обчислюється з викори-

станням наступних компонентів:

Page 93: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

93

зміщення (Displacement чи Disp) – 8-, 16- чи 32-бітове число,

включене в команду;

база (Base) – вміст базового регістра. Звичайно використовується

для вказання на початок деякого масиву;

індекс (Index) – вміст індексного регістра. Звичайно використову-

ється для вибору елемента масиву;

масштаб (Scale) – множник (1, 2, 4 чи 8), зазначений у коді ін-

струкції. Цей елемент використовується для вказання розміру елемента

масиву, доступний тільки при 32-бітовій адресації.

Ефективна адреса обчислюється за формулою

ЕА = Base + Index Scale + Disp.

Окремі складові в цій формулі можуть бути відсутніми.

Пряма адресація (Direct Mode). Адреса EA = Disp.

Наприклад, MOV EAX, [0100]

Непряма регістрова адресація (Register Indirect Mode).

Адреса EA = Base.

Наприклад, MOV EAX, [EBX]

Базова адресація (Baset Mode). Адреса EA = Base + Disp.

Наприклад, MOV EAX, [ЕSI + ЕBX]

Індексна адресація (Index Mode). Адреса EA = Index + Disp.

Наприклад, MOV ЕDX, [ЕDI]

Масштабована індексна адресація (Scaled Index Mode).

Адреса EA = Scale Index + Disp1.

Наприклад, MOV ECX, [EDI*4 + EAX]

Базово-індексна адресація (Based Index Mode).

Адреса EA = Base + Index.

Наприклад, MOV EAX, [ЕBX]ALPHA[ЕSI]

Масштабована базово-індексна адресація (Based Scaled Index

Mode).

Адреса EA = Base + Scale Index.

Наприклад, MOV ECX, [EBX + 4*ESI]

Базово-індексна адресація зі зміщенням (Based Index Mode with

Displacement). Адреса EA = Base + Index + Disp.

Наприклад, MOV EAX, [EBX + ESI + 00ABCDF]

Масштабована базово-індексна адресація зі зміщенням (Based

Scaled Index Mode with Displacement). Адреса EA = Base + Scale Index

+ Disp.

Наприклад, MOV ECX, [EBX +36] + [8*ESI]

Page 94: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

94

Масштабування індексу можливо тільки при 32-розрядній адреса-

ції.

Процесор може працювати з 32- чи 16-бітовою адресацією. 16-

бітова адресація працює так само, як і в процесорах 8086 і 80286, при

цьому як компоненти адреси використовуються молодші 16 бітів відпо-

відних регістрів. При 32-бітовій адресації використовуються розширені

32-розрядні регістри і застосовуються додаткові режими з масштабуван-

ням індексу. Розходження 16- і 32-бітових режимів адресації наведені в

табл. 3.4.

Таблиця 3.4

Відмінності режимів адресації

Компонент 16-бітова адресація 32-бітова адресація Базовий регістр BX або BP Будь-який 32-бітовий регістр зага-

льного призначення

Індексний регістр SI або DI Будь-який 32-бітовий регістр зага-

льного призначення, окрім ESP

Масштаб Ні (завжди 1) 1, 2, 4 або 8

Зміщення 0, 8 або 16 бітів 0, 8 або 32 біти

У реальному режимі за замовчуванням використовується 16-бітова

адресація, але за допомогою префікса зміни розрядності адреси

(Address Length Prefix) для поточної інструкції можна переключитися на

32-бітову. При цьому з’являються додаткові можливості адресації (мас-

штабування), але значення ефективної обчислювальної адреси, однаково

не може подолати 64-кілобайтовий бар’єр – при спробі звернутися за

такою ефективною адресою генерується виключення #GP (General

Protection Fault).

У захищеному режимі адресація за замовчуванням визначається

бітом D дескриптора використовуваного кодового сегмента: при D = 0

– 16 бітів, при D = 1 – 32 біти. Префікс розрядності адреси переключає

розрядність для поточної інструкції на протилежну.

При звертаннях до пам’яті використання сегментних регістрів за

замовчуванням визначається типом звертання (табл. 3.5).

Для більшості типів звертання на час поточної інструкції при необ-

хідності можливе використання альтернативного сегментного регістра,

на що вказує префікс заміни сегмента (CS:, DS:, ES:, SS:, FS: чи GS:)

перед кодом інструкції.

Page 95: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

95

Таблиця 3.5

Використання сегментних регістрів при звертанні до пам’яті

Як і процесор 8086, 32-розрядні процесори дозволяють адресувати

до 64 К однобайтових чи 32 К двобайтових регістрів у просторі, окре-

мому від пам’яті. Додатково є можливість звертання до 32-бітових пор-

тів.

При операціях введення-виведення лінії А[16:31] не використову-

ються. Адреса пристрою задається або в команді (тільки молодший байт,

старший – нульовий), або береться з регістра DX (повна 16-бітова адре-

са). Команди введення-виведення викликають шинні цикли з активними

сигналами IORD#, IOWR#. Рядкові команди забезпечують блокове вве-

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

ндартним контролером DMA. В адресному просторі введення-виведення

область 0F8-0FF зарезервована для використання співпроцесором (при

звертанні до співпроцесора процесор 80386 виставляє одиницю на най-

старшій лінії шини адреси, що використовується для спрощення дешиф-

рування адрес).

У захищеному режимі інструкції введення–виведення є привілейо-

ваними. Це означає, що вони можуть заповнюватися задачами тільки з

визначеним рівнем привілеїв, обумовленим полем IOPL регістра чи

прапорців бітової карти дозволу введення-виведення (I/O Permission

Bitmap), що зберігається в сегменті стану задачі. Несанкціонована спро-

ба виконання цих інструкцій викликає виключення 13 (#GP) – порушен-

ня захисту (повідомлення “General Protection Error”).

Тип звертання до пам’яті Сегментний регістр

за замовчуванням альтернативний

Вибірка команди CS

Стекові операції SS

Стрічка-приймач ES

Будь-які інші посилання на пам’ять,

окрім тих, що використовують в якості

базової адреси BP, EBP або ESP

DS CS, ES, SS, FS,

GS

Посилання на пам`ять, що використо-

вують в якості базового регістра BP, EBP

або ESP

SS CS, ES, SS, FS,

GS

Page 96: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

96

4. БАЗОВІ КОМАНДИ МП ПЛАТФОРМИ х86

4.1. Команди пересилання даних

Команди пересилання даних загального призначення можуть за-

стосовуватись з безліччю операндів, хоча й існують деякі винятки. Ко-

манди пересилання даних загального призначення (крім команди XCHG)

– єдині, що дозволяють як операнд використовувати регістр сегмента.

MOV приймач, джерело Пересилання даних 8086

Команда MOV виконує пересилання байта чи слова з джерела

(правий операнд) у приймач (лівий операнд).

MOV mem/reg1, mem/reg2

MOV ЕDX, ЕCX ; Передати слово з Рг ЕCX у Рг EDX

MOV BХ, [0800] ; Передати байт з комірки пам’яті з адресою 0800

; в Рг ВХ: BX := [0801, 0800]

MOV TEMP, BL ; Передати байт із Рг ВL у масив пам’яті

; з ім’ям TEMP

MOV [DІ], BX ; Передати слово з Рг ВХ у комірку пам’яті,

; адреса якої знаходиться в Рг DІ

MOV DX,[BP][SІ] ; Передати в Рг DX слово з комірки пам’яті,

; адреса якого визначається як сума вмістів Рг BP і Рг SІ

MOV mem/reg, data

MOV [DІ], 8400H ; Занесення операнда 8400 у комірку пам’яті,

; адреса якої знаходиться в Рг DІ

MOV [BP][SІ], 2CH ; Передати число 2С у комірку пам’яті

; за адресою яка знаходиться як сума BP та SI

MOV ЕСХ, 87654321Н ; Передати число 87654321Н в Рг СХ

MOV AC, mem

MOV AL, [0800] ; Передати байт з пам’яті з адресою 0800 у Рг AL

MOV ЕAX, [0800] ; ЕAX := [0803, 0802, 0801, 0800]

MOV mem, AC

Page 97: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

97

MOV BETA, ЕAX ; Передати зміст Рг ЕАХ у пам’ять,

; адреса комірки якої має ім’я BETA

MOV sreg, mem/reg

MOV SS, BP ; Передати слово з Рг ВР у сегментний Рг SS

MOV ES, [DX] ; Передати число з комірки пам’яті,

; адреса якої знаходиться в Рг DX у сегм. Рг ES

MOV mem/reg, sreg

MOV [BX], ES ; Передати слово із сегментного Рг ES

; у комірку пам’яті, адреса якої знаходиться в Рг ВХ

MOV CX, SS ; Передати слово із сегментного Рг SS у Рг СХ

Якщо, наприклад, у сегментний регістр DS необхідно завантажити

F000, то будуть потрібні команди

MOV AX, 0F000H ; Ініціалізація

MOV DS, АХ ; регістра DS на F000

При такій ініціалізації майже завжди як проміжний використову-

ється регістр АХ, тому що команда MOV ac, data коротше ніж загальна

команда MOV mem/reg, data.

При пересиланні в SS забороняються всі переривання до кінця ви-

конання наступної команди (яка найчастіше є командою MOV у ESP).

Форми команди MOV зберігають або завантажують наступні спеці-

альні регістри в(із) регістри(ів) загального призначення:

керуючі регістри CR0, CR2 і CR3;

регістри відладки DR0, DR1, DR2, DR3, DR6 і DR7;

тестові регістри TR3, TR4, TR5, TR6 і TR7.

З цими командами завжди використовуються 32-розрядні операнди

незалежно від атрибута розміру операнда.

Команда MOV не може пересилати дані з пам’яті в пам’ять або із

сегментного регістра в сегментний регістр. Спеціальна форма команди

MOV розроблена для забезпечення пересилання даних між регістрами

AL або EAX і місцем у пам’яті, закодованим за допомогою 32-

розрядного зміщення, заданого в команді. Ця форма команди не дозво-

ляє виходити за межі сегмента і забороняє використання індексних ре-

гістрів або масштабування. Кодування даної форми команди на один

байт коротше, ніж кодування команди MOV загального призначення.

Аналогічне кодування виконується для переміщення 8, 16 або 32 розря-

дів безпосередньо в один з регістрів загального призначення.

MOVSX приймач, джерело Пересилання з розширенням знаку 80386

Page 98: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

98

Команда MOVSX копіює вміст джерела (регістр або змінна розмі-

ром у байт або слово) в приймач (16- або 32- бітовий регістр) і розши-

рює знак аналогічно командам CBW/CWDE.

MOVZX приймач, джерело Пересилання з розширенням нулями 80386

Команда MOVZX копіює вміст джерела (регістр або змінна розмі-

ром у байт або слово) в приймач (16- або 32- бітовий регістр) і розши-

рює нулями, тобто команда movzx ах, bl

еквівалентна парі команд mov al, bl

mov ah,0

CMOVcc прм, прд Умовне пересилання даних Р6

Команди CMOVcc копіюють вміст джерела в приймач, якщо задо-

вольняється та або інша умова (табл. 4.1). Джерелом може бути регістр

загального призначення або змінна, а приймачем – тільки регістр. Вимо-

га, яка повинна виконуватися, – просто рівність нулю або одиниці тих

або інших прапорців із регістра FLAGS. Якщо використовувати команди

CMOVcc відразу після СМР (порівняння) з тими ж операндами, умови

набувають особливого сенсу, наприклад: cmp ах,bх ; Порівняти ах і bx cmov ах,bх ; якщо ах < bх, то скопіювати bх в ах

Слова “вище” і “нижче” в табл. 4.1 відносяться до порівняння чисел

без знаку, слова “більше” і “менше” враховують знак.

Таблиця 4.1

Різновиди команди CMOVcc

Код команди Реальна умова Умова для СМР CMOVA CMOVNBE CF = 0 та ZF = 0 Якщо вище

Якщо не нижче і не дорівнює CMOVAE CMOVNB CMOVNC

CF = 0 Якщо вище або дорівнює Якщо не нижче Якщо немає перенесення

CMOVB CMOVNAE CMOVC

CF = 1 Якщо нижче Якщо не вище і не дорівнює Якщо перенесення

Page 99: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

99

Закінчення табл. 4.1 CMOVBE CMOVNA CF = 1 або ZF = 1 Якщо нижче або дорівнює

Якщо не вище CMOVE CMOVZ ZF = 1 Якщо рівно

Якщо нуль CMOVG CMOVNLE ZF = 0 та SF = OF Якщо більше

Якщо не менше і не дорівнює CMOVGE CMOVNL SF = OF Якщо більше або дорівнює

Якщо не менше CMOVL CMOVNGE SF <>OF Якщо менше

Якщо не більше і не дорівнює CMOVLE CMOVNG ZF = 1 або SF <> OF Якщо менше або дорівнює

Якщо не більше CMOVNE CMOVNZ ZF = 0 Якщо не дорівнює

Якщо не нуль CMOVNO OF = 0 Якщо немає переповнювання

CMOVO OF = 1 Якщо є переповнювання CMOVNP CMOVPO PF = 0 Якщо немає парності

Якщо непарне CMOVP CMOVPE PF = 1 Якщо є парність

Якщо парне CMOVNS SF = 0 Якщо немає знаку CMOVS SF = 1 Якщо є знак

XCHG операнд1, операнд 2 Обмін операндів між собою 8086

Команда XCHG змінює байт чи слово, які адресуються операнда-

ми. Регістри сегментів не можуть бути операндами команди XCHG.

XCHG reg, mem/reg

XCHG AL, SEMA ; Обмін байтами пам’ять – регістр

XCHG AL, ВL ; Обмін байтами регістр – регістр

XCHG АХ, СХ ; Обмін словами регістр – акумулятор

BSWAP регістр32 Обмін байтів в регістрі 80486

Команда BSWAP виконує обертання порядку байтів у 32-бітовому

регістрі. Біти 0 – 7 (молодший байт молодшого слова) міняються місця-

ми з бітами 24 – 31 (старший байт старшого слова), а біти 8 – 15 (стар-

ший байт молодшого слова) – з бітами 16 – 23 (молодший байт старшого

слова). mov eax,12345678h bswap eax ; Тепер в еах знаходиться 78563412h.

Щоб виконати обертання порядку байтів у 16-бітовому регістрі, слід

Page 100: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

100

використовувати команду XCHG: xchg al, ah ; Обертання порядку байтів АХ.

У процесорах Intel команду BSWАP можна використовувати і для

звертання порядку байтів в 16-бітових регістрах, але в деяких сумісних

процесорах інших фірм цей варіант не реалізований.

Команди роботи зі стеком. Команда PUSH (помістити) декреме-

нтує покажчик стека (регістр ESP), потім копіює операнд-джерело у ве-

ршину стека. Команда PUSH часто використовується для розміщення в

стеку параметрів перед викликом процедури. Усередині процедури вона

може бути використана для резервування простору в стеку під тимчасові

змінні. Команда PUSH працює з операндами, розміщеними в пам’яті,

безпосередніми операндами і з регістровими операндами (включаючи

регістри сегмента). Команда PUSH зменшує ESP на розмір джерела у

байтах (2 або 4) та зберігає зміст джерела у памяті за адресою SS:[ESP].

PUSH джерело Переслати дані у стек 8086

Команда PUSH зменшує покажчик стека на 2, якщо атрибут розмі-

ру операнда команди дорівнює 16 чи 8 бітам; у протилежному випадку

вона зменшує покажчик стека на 4. Потім команда PUSH поміщає опе-

ранд у нову вершину стека , на яку вказує покажчик стека.

Якщо регістр SP або ESP дорівнює 1, процесор переходить у режим

закриття через недостатній розмір пам’яті стека.

PUSH mem/(s)reg

PUSH CX ; Завантажити в стек слово з РГ СХ

PUSH [BX] ; Завантажити в стек слово, адреса якого знах. в Рг ВХ

PUSH SІ ; Включення в стек регістра

PUSH ES ; Включення в стек сегментного регістра

PUSH [DІ] ; Включення в стек слова з пам’яті

POP джерело Зчитати дані зі стека 8086

Команда POP (відновити (дані) зі стека ) передає слово або подвій-

не слово з вершини стека (на яку вказує регістр ESP) операнда призна-

чення і потім збільшує значення регістра ESP, щоб той указував на нову

вершину стека. POP переміщає інформацію зі стека в регістр загального

призначення, регістр сегмента або в пам’ять. Для передачі подвійного

слова зі стека в регістр загального призначення використовується спеці-

альна форма команди POP.

Команда POP заміняє вміст операнда пам’яті, регістра або сегмент-

Page 101: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

101

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

помогою SS:SP (при атрибуті розміру адреси 16 бітів) або SS:ESP (при

атрибуті розміру адреси 32 біти). Покажчик стека SP одержує збільшен-

ня на 2 при розмірі операнда 16 біт або 4 при розмірі операнда 32 біт.

Після цього покажчик установлюється на нову вершину стека.

Команда POP CS не є командою процесора. Витяг зі стека в регістр

CS здійснюється командою RET.

Команда POP SS забороняє всі переривання, включаючи і немаско-

вані переривання, до кінця виконання наступної команди. Це дозволяє

послідовне виконання команд POP SS і POP ЕSР без загрози мати під

час переривання невірний стан стека.

POP mem/(s)reg

POP ALPHA ; Витяг зі стека в пам’ять

POP DS ; Витяг зі стека в сегментний регістр

POP DX ; Витяг зі стека в регістр

PUSHA PUSHAD

Переслати дані у стек усі регістри загального призначення

80186 80386

PUSHA\РUSHАD (помістити регістри) зберігає вміст восьми регіс-

трів загального призначення в стеку. Ця команда спрощує виклики про-

цедур шляхом скорочення числа команд, необхідних для збереження

вмісту регістрів загального призначення. Результат виконання команди

PUSHA протилежний дії команди POPA.

Команда PUSHA зменшує покажчик стека (SP) на 16, що відповідає

восьми значенням, які розташовуються у стеку розміром у слово та в

такій послідовності: AX, CX, DX, BX, SP, BP, SI, DI.

Команда PUSHAD декрементує покажчик стека (ESP) на 32, що ві-

дповідає восьми значенням розміром у подвійне слово та розташовує

регістри у такій послідовності: EAX, ECX, EDX, EBX, ESP, EBP, ESI,

EDI.

POPA POPAD

Зчитати дані зі стека усі регістри загального призначення

80186 80386

POPA/POPAD – витяг зі стека всіх регістрів загального призначен-

ня у наступному порядку: DI, SI, BP, BX, DX, CX і AX. Команди

POPA/POPAD виконують дії, які зворотні діям PUSHA/PUSHAD.

Команда POPA витягає зі стека вісім 16-бітових регістрів загально-

го призначення. Однак значення SP замість завантаження регістра SP

знищується. Команда POPA реверсує дію команди PUSHA, відновлю-

Page 102: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

102

ючи значення регістрів загального призначення, які вони мали перед

виконанням команди PUSHA.

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

ІN пересилає байт (чи слово) зі вступного порту в регістр AL (чи АХ).

Порт вказується або байтом даних (доступ до портів від нуля до двохсот

п’ятидесяти п’яти), або номером порту в регістрі DX, що допускає звер-

тання до 210 портів вводу.

IN приймач, джерело Зчитати дані з порту 8086

ІN ac, port

ІN ac, DX

ІN AX, 40H ; Ввід слова з 40-го порту

ІN AL, DX ; Ввід байта з порту, адреса якого знаходиться в Рг DX

OUT приймач, джерело Записати дані в порт 8086

Команда OUT працює подібно ІN, але передача інформації здійс-

нюється з акумулятора в порт виводу.

OUT port, ac

OUT DX, ac

OUT 80H, AL ; Вивід байта з Рг AL через порт 80H

OUT DX, AX ; Вивід слова з Рг АХ через порт,

; адреса якого зазначена у Рг DX

CWD Конвертація слова в подвійне слово 8086

CDQ Конвертація подвійного слова в збільшене учетверо 80386

Команда CWD перетворює слово в АХ в подвійне слово, молодша

половина якого (біти 0 – 15) залишається в АХ, а старша (біти 16 – 31)

розташовується в DX.

Команда CDQ виконує аналогічну дію по відношенню до подвійно-

го слова в ЕАХ, розширюючи його до збільшеного учетверо слова в

EDX:EAX. Ці команди лише встановлюють всі біти регістра DX або EDX в

значення, що дорівнює величині старшого біта регістра АХ або ЕАХ,

зберігаючи таким чином його знак.

CBW

CWDE

Конвертація байта в слово

Конвертація слова в подвійне слово

8086

80386

Команда CBW розширює байт, що знаходиться в регістрі AL, до

Page 103: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

103

слова в АХ. Команда CWDE розширює слово в АХ до подвійного слова

в ЕАХ. Команди CWDE і CWD відрізняються тим, що CWDE розміщує

свій результат в ЕАХ, тоді як CWD, що виконує таку саму дію, розташо-

вує результат в парі регістрів DX:AX. Так само як і в командах

CWD/CDQ, розширення виконується шляхом установлення кожного біта

старшої половини результату рівним старшому біту початкового байта

або слова, тобто mov al,0F5h ; AL = 0F5h = 245 = –11. cbw ; Тепер АХ = 0FFF5h = 65 525 = – 11.

XLAT адреса

XLATВ

Трансляція у відповідності з таблицею 8086

Команда XLAT здійснює пошук у таблиці і заміну операнда на від-

повідний байт із таблиці. Вміст регістра AL заміняється вмістом комірки

пам’яті ES:BX (ES:EBX), адреса якої визначається як зміщення, що збе-

рігалося в Рг AL відносно Рг ВХ (EBX). Обраний таким способом одно-

байтовий операнд пересилається в регістр AL.

За аргумент для XLAT можна вказати ім’я таблиці, але ця інформа-

ція процесором не використовується. Якщо ж вона не потрібна, то мож-

на використати форму XLATВ, наприклад:

mov al, 0Ch

mov bx, offset table

xlatb

А якщо у сегменті даних, на який вказує ES, було:

tabl db “0123456789ABCDEF”

то в AL розміщується не число ОСh, а ASCII– код літери С.

Команди пересилання типу адреса – об’єкт. Розглянуті команди

відрізняються від інших команд передачі тим, що при їх виконанні в ад-

ресуємий регістр передаються не дані, а адреси. Основне застосування

команд – це ініціалізація регістрів перед виконанням ланцюгових ко-

манд.

LEA приймач, джерело Обчислення ефективної адреси 8086

LEA (LDS) ( LES) reg, mem

Команда LEA (завантаження виконавчої адреси) передає зміщення,

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

покажчик чи індексний регістр, який адресується лівим операндом.

LEA BX, [BX] [SІ]

Page 104: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

104

Команду LEA часто використовують для виконання арифметичних

обчислень, наприклад множення

lea bx,[ebx + ebx*4] ; BX = EBX 5

або додавання

lea ebx,[eax + 12] ; EBX = EAX + 12

Ці команди не змінюють прапорці.

LDS прм, джерело Завантажити адресу, використовуючи DS 8086

LES прм, джерело Завантажити адресу, використовуючи ES 8086

LFS прм, джерело Завантажити адресу, використовуючи FS 80386

LGS прм, джерело Завантажити адресу, використовуючи GS 80386

LSS прм, джерело Завантажити адресу, використовуючи SS 8086

LDS SІ, [DІ]

LES BP, ALPHA

Другий операнд (джерело) для всіх цих команд – змінна в пам’яті

розміром в 32 або 48 біт (залежно від розрядності операндів). Перші 16

або 32 біти з цієї змінної завантажуються в регістр загального призна-

чення, вказаний як перший операнд, а наступні 16 бітів – у відповідний

сегментний регістр (DS для LDS, ES для LES і т. д.). У захищеному ре-

жимі значення, що завантажується в сегментний регістр, завжди повинно

бути правильним селектором сегмента (у реальному режимі будь-яке

число може використовуватися як селектор).

Команди пересилання бітів умов. Існує чотири команди переси-

лання бітів умов.

LAHF Завантажити регістр АН значеннями бітів умов 8086

Команда LAHF (завантажити регістр АН значеннями бітів умов)

передає біти умов SF, ZF, AF, PF і CF у регістр АН.

SAHF Завантажити біти умов з регістра АН 8086

Команда SAHF (завантажити біти умов з регістра АН) передає біти

умов з регістра АН в однорозрядні регістри SF, ZF, AF, PF і SF.

PUSHF PUSHFD

Завантажити FLACS у стек Завантажити ЕFLACS у стек

8086 80386

Page 105: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

105

Команда PUSHF (засилання бітів умов у стек) зменшує покажчик

стека SP на два і пересилає всі біти умов у два байти стека, що знахо-

дяться за адресою, зазначеною в регістрі SP.

PUSHF ; Включення в стек прапорців

POPF POPFD

Завантажити FLACS зі стека Завантажити ЕFLACS зі стека

8086 80386

Команда POPF (витягання бітів умов ІP стека) пересилає біти умов

зі стека, що знаходиться за адресою, зазначеною в регістрі SP, у регістр

бітів умов і збільшує регістр SP на два:

POPF ; Витягання зі стека в регістр прапорців

STC Встановити прапорець переносу CF 8086

CLC Зкинути прапорець переносу CF 8086

CMC Інвертувати прапорець переносу CF 8086

STD Встановити прапорець напряму DF 8086

CLD Зкинути прапорець напряму DF 8086

CLI Заборона переривання 8086

Команда CLI скидає прапорець IF в 0. Після виконання цієї коман-

ди процесор ігнорує всі переривання від зовнішніх пристроїв (окрім

NMI). У захищеному режимі ця команда, так само як і всі інші команди,

що модифікують прапорець IF (POPF або IRET), виконується, тільки

якщо програмі дані відповідні привілеї (CPL ≤ IOPL).

STI Дозволити переривання 8086

Команда STI встановлює прапорець IF в 1, відміняючи тим самим

дію команди CLI.

SALC Встановити AL відповідно до CF 8086

Команда SALC встановлює AL в 0FFh, якщо прапорець CF = 1, і

скидає в 00h, якщо CF = 0. Це недокументована команда з кодом 0D6h.

Page 106: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

106

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

МП виконує чотири основні математичні дії (з різноманітними мо-

дифікаціями) з урахуванням знака і без нього. Для чисел зі знаком

прийняте стандартне представлення в додатковому коді. При виконанні

арифметичних дій встановлюються чи скидаються шість бітів умов: CF,

AF, ZF, SF, PF, OF.

Команди додавання ADD приймач, джерело Додавання 8086

ADС приймач, джерело Додавання з переносом 8086

Команда ADD здійснює додавання операндів і запам’ятовує ре-

зультат за адресою, що задається першим операндом.

ADD mem/reg1, mem/reg2

ADD [0080], СL ; [0080] := [0080] + CL, пам’ять – регістр

ADD CX, DX ; CX := CX + DX, регістр – регістр

ADD DІ, ALPHA ; DI := DI +[ALPHA], регістр – пам’ять

ADD mem/reg, data

ADD AL, 02H ; AL := AL + 0216, регістр – константа

ADD BETA, 0FFH ; Пам’ять– константа

Команда ADC здійснює додавання операндів і вмісту біта CF, ре-

зультат запам’ятовується за адресою першого операнда.

ADC mem/reg1, mem/reg2

ADС CX, DX ; СX := CX + DX + C, регістр – регістр

ADС DІ, ALPHA ; Регістр – пам’ять

ADC mem/reg, data

ADC ЕAX, 7777H ; ЕAX = ЕAX + 00007777H

ІNС приймач Додавання одиниці (інкремент) 8086

Команда ІNC збільшує на "1" вміст адресного елемента і розміщає

результат за тією ж адресою.

ІNC mem/reg

ІNC BL ; Регістр (8 бітів)

ІNC CX ; Регістр (16 бітів)

ІNC GAMMA[DІ] ; Комірка пам’яті

XADD приймач, джерело Обміняти між собою та додати 80486

Page 107: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

107

При виконанні команди XADD джерелом є завжди регістр, а прий-

мач може бути як регістром, так і змінною.

ААА ACSII– корекція після додавання 8086

Команда ААА корегує суму двох неупакованих двійково-

десяткових чисел в AL. Якщо корекція приводить до десяткового пере-

несення, АН збільшується на 1. Цю команду краще використовувати від-

разу після команди складання двох таких чисел. Наприклад, якщо при

складанні 05 і 06 в АХ опиниться число 000Bh, то команда ААА скоре-

гує його в 0l0lh (неупаковане десяткове 11). Прапорці CF і OF встанов-

люються в 1, якщо відбулося перенесення з AL в АН, інакше вони дорів-

нюють нулю. Значення прапорців OF, SF ZF і PF не визначені.

DAA BCDI– корекція після додавання 8086

Команда DAA здійснює корекцію числа в регістрі AL, отриманого

в результаті додавання двох упакованих десяткових операндів. При цьо-

му маємо упаковану десяткову суму.

Якщо ця команда виконується відразу після ADD (ADC, INC або

XADD) і в регістрі AL знаходиться сума двох упакованих двійково-

десяткових чисел, то в AL записується упаковане двійково-десяткове

число, яке повинне було стати результатом складання. Наприклад, якщо

AL містить число 19h, послідовність команд

inc al

daa призведе до того, що в AL опиниться 20h (а не lAh, як було б після INC).

Команда DAA виконує наступні дії: 1. Якщо молодші чотири біти AL більше 9 або прапорець AF = 1, то

AL збільшується на 6; CF встановлюється, якщо при цьому додаванні

відбулося перенесення, і AF встановлюється в 1. 2. Інакше AF = 0. 3. Якщо тепер старші чотири біти AL більше 9 або прапорець CF =

1, то AL збільшується на 60h і CF встановлюється в 1. 4. Інакше CF = 0. Прапорці AF і CF встановлюються, якщо в ході корекції відбувало-

ся перенесення з першої або другої цифри. SF, ZF і PF встановлюються

відповідно до результату, прапорець OF не визначений. Команди віднімання

SUB приймач, джерело Віднімання 8086

Page 108: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

108

Команда SUB здійснює віднімання другого операнда із першого.

Результат записується за адресою першого операнда

SUB mem/reg1, mem/reg2

SUB CX, BX ; Регістр – регістр

SUB DX, ALEX [SІ] ; Регістр – пам’ять

SUB [BP+2], CL ; Пам’ять – регістр

SUB mem/reg, data

SUB AL, 10Н ; Регістр – константа

SUB [SІ], 0F000H ; Пам’ять – константа

Команда SBB здійснює віднімання із вмісту, що адресується дру-

гому операнду вмісту, що адресується першим операндом із врахуван-

ням вмісту регістра CF.

SВB приймач, джерело Віднімання з позиченням 8086

SВB mem/reg1, mem/reg2

SBB AX, BP ; Регістр – регістр

SBB {BP + 40H], BX ; Регістр – пам’ять

SВB mem/reg, data

SBB [DІ], 30Н ; Пам’ять – константа

DEC Декремент 8086

Команда DEC віднімає одиницю з вмісту адресуємого елемента і

запам’ятовує результат за тією ж адресою.

DEC [BP] ; Пам’ять

DEC AL ; Регістр (8 бітів)

DEC BX ; Регістр (16 бітів)

NEG приймач Зміна знака 8086

Команда NEG здійснює віднімання вмісту адресуємого елемента з

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

додаткового коду).

NEG reg

CMP приймач, джерело Порівняння 8086

Команда СМР (порівняння) здійснює віднімання подібно команді

SUB, установлює біти умов, але не здійснює запам’ятовування результа-

ту.

CMP mem/reg1, mem/reg2

CMP mem/reg, data

Page 109: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

109

CMPXCHG приймач, джерело Порівняти і обміняти між собою 80486

Команда CMPXCHG порівнює значення, що містяться в AL, АХ,

ЕАХ (залежно від розміру операндів), з приймачем (регістром). Якщо

вони рівні, інформація з джерела копіюється в приймач і прапорець ZF

встановлюється в 1, інакше вміст приймача копіюється в AL, АХ, ЕАХ і

прапорець ZF встановлюється в 0. Решта прапорців визначається за ре-

зультатом операції порівняння, як після СМР. Джерело – завжди регістр,

приймач може бути регістром і змінною.

CMPXCHG8B приймач Порівняти і обміняти 8 байт Р5

Команда CMPXCHG8B виконує порівняння вмісту регістрів

EDX:EAX як 64-бітового числа (молодше подвійне слово – в ЕАХ, ста-

рше – в EDX) з приймачем (8-байтова змінна в пам’яті). Якщо вони рів-

ні, вміст регістрів ЕСХ:ЕВХ як 64-бітове число (молодше подвійне сло-

во в ЕВХ, старше – в ЕСХ) поміщається в приймач. Інакше вміст прий-

мача копіюється в EDX:EAX.

AAS ACSII– корекція після віднімання 8086

Команда AAS здійснює корекцію числа в регістрі AL, отриманого в

результаті віднімання двох розпакованих десяткових операндів, і дає в

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

DAS BCD–корекція після віднімання 8086

Команда DAS здійснює корекцію результату віднімання двох упа-

кованих десяткових чисел, і в результаті дає упаковану десяткову різни-

цю.

Якщо ця команда виконується відразу після SUB (SBB або DEC) і в

регістрі AL знаходиться різниця двох упакованих двійково-десяткових

чисел, то в AL записується упаковане двійково–десяткове число, яке по-

винне було бути результатом віднімання. Наприклад, якщо AL містить

число 20h, послідовність команд dec al

das призведе до того, що в регістрі опиниться 19h (а не IFh, як було б після

DEC). DAS виконує наступні дії:

Page 110: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

110

1. Якщо молодші чотири біти AL більше 9 або прапорець AF = 1, то

AL зменшується на 6, CF встановлюється, якщо при цьому відніманні

відбулася позика, і AF встановлюється в 1. 2. Інакше AF = 0. 3. Якщо тепер старші чотири біти AL більше 9 або прапорець CF =

1, то AL зменшується на 60h і CF встановлюється в 1.

4. Інакше CF = 0.

Приклад незвичайного використання цієї команди – найкомпактні-

ший варіант перетворення шістнадцяткової цифри в ASCII-код відповід-

ного символу: сmр al, 10 sbb al,69h das Після SBB числа 0 – 9 перетворюються в 96Н – 9Fh, а числа 0Ah –

0Fh – в 0A1h – 0A6h. Потім DAS віднімає 66h з першої групи чисел,

переводячи їх в 30h – 39h, і 60h з другої групи чисел, переводячи їх в

41h – 46h. Прапорці AF і CF встановлюються, якщо в ході корекції відбувала-

ся позика з першої або другої цифри. SF, ZF і PF встановлюються відпо-

відно до результату, прапорець OF не визначений.

Команди множення

Команда MUL здійснює множення без знака вмісту акумулятора

(AL чи АХ) і вмісту, що адресується операндом, розміщуючи результат

подвійної довжини в акумуляторі і його розширенні (AL і АН для

8-розрядних операндів, АХ і DX для 16-розрядних). Біти умов CF і OF

установлюються, якщо старша половина результату не дорівнює 0.

MUL джерело Множення чисел без знаків 8086

MUL reg

MUL CX ; DX, AX ← CX AX

MUL BL ; Перемножити вміст регістрів AL і BL без знаків

; із запам’ятовуванням результату в Рг AH і AL.

MUL mem

MUL [DІ – 40H] ; Перемножити вміст Рг AX і операнда з пам’яті,

; адреса якого знаходиться в Рг DІ з урахуванням зміщення – 40Н

; (без знака). Результат запам’ятовується в Рг DX і AX.

MUL [0040] ; DX, AX ← [0040] AX, DH = 00

Page 111: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

111

IMUL джерело

IMUL приймач, джерело

IMUL приймач, джерело 1, джерело 2

Множення чисел

без знаків

8086

80386

80186

Команда ІMUL подібна команді MUL, але за нею виконується

множення з урахуванням знака. Біти умов CF і OF установлюються, як-

що старша половина результату не є розширенням для формування знака

молодшої половини.

ІMUL reg

ІMUL СХ ; DX, АХ = AХ СХ зі знаками.

ІMUL mem

ІMUL ALPHA ; DX, АХ = АХ [ALPHA] з урахуванням знаків.

Ця команда має три форми, що розрізняються числом операндів:

1. IMUL джерело: джерело (регістр або змінна) помножується на

AL, АХ або ЕАХ (залежно від розміру операнда), і результат розташову-

ється в АХ DX:AX або EDX:EAX відповідно.

2. IMUL приймач, джерело: джерело (число, регістр або змінна)

помножується на приймач (регістр), і результат заноситься в приймач.

3. IMUL приймач, джерело 1, джерело 2: джерело 1 (регістр або

змінна) помножується на джерело 2 (число), і результат заноситься в

приймач (регістр).

У всіх трьох варіантах вважається, що результат може займати в

два рази більше місця, ніж розмір джерела. У першому випадку приймач

автоматично виявляється дуже великим, але в другому і третьому випад-

ках існує вірогідність переповнювання і втрати старших бітів результату.

Прапорці OF і CF будуть дорівнювати одиниці, якщо це відбулося, і ну-

лю, якщо результат множення помістився цілком в приймачі (у другому і

третьому випадках) або в молодшу половину приймача (у першому ви-

падку).

Значення прапорців SF, ZF, AF і PF після команди IMUL не визна-

чені.

ААМ ACSII– корекція після множення 8086

Команда ААМ корегує результат множення неупакованих двійко-

во-десяткових чисел, який знаходиться в АХ після виконання команди

MUL, перетворюючи одержане в пару неупакованих двійково–

десяткових чисел (у АН і AL). Наприклад:

mov al,5

mov bl,5 ; bl ← 5

Page 112: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

112

mul bl ; AH,AL ← al bl

aam ; АХ містить 0205h.

Команда ААМ встановлює прапорці SF, ZF і PF відповідно до ре-

зультату і залишає OF, AF і CF невизначеними.

Код команди ААМ – D4h 0Ah, де 0Ah – основа системи числення,

по відношенню до якої виконується корекція. Цей байт можна замінити

на будь-яке інше число (окрім нуля), і ААМ перетворить АХ до двох

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

ААМ працює на всіх процесорах (починаючи з 8086), але з’являється в

документації Intel тільки з процесорів Pentium. Фактично дія, яка вико-

нує ААМ, – цілочисельне ділення AL на 0Ah (або будь-яке інше число в

загальному випадку), частка поміщається в АН і залишок – в AL, тому

команду часто використовують для швидкого ділення у високооптимізо-

ваних алгоритмах.

Команди ділення

DІV джерело Цілочисельне ділення чисел без знаків 8086

Команда DІV здійснює ділення без знака вмісту акумулятора і його

розширення (AL і АН для 8-розрядної операції, АХ і DX – для

16-розрядної) на вміст, що адресується операндом, і розміщує частку в

акумуляторі (AL чи АХ) та залишок одинарної довжини в розширенні

акумулятора (АН чи DX). Біти умов не змінюються. Ділення на нуль дає

переривання за вектором 0.

DІV reg/mem/data

DІV 8H ; Поділити вміст Рг АХ на 8Н без врахування знака.

; Результат формується в Рг AL, а залишок – у Рг AH.

DІV [BP + 20H] ; Поділити вміст регістрів DX і AX на число,

; адреса якого знаходиться в Рг BP з урахуванням зміщення + 20 Н.

IDІV джерело Цілочисельне ділення чисел зі знаком 8086

Команда ІDIV працює подібно команді DІV, за винятком того, що

вона здійснює ділення з урахуванням знака.

ІDІV reg/mem

AAD ACSII– корекція перед діленням 8086

Команда AAD здійснює корекцію діленого в регістрі перед ділен-

ням двох розпакованих десяткових операндів, так що в результаті отри-

муємо розпаковану десяткову частку.

Page 113: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

113

Команда AAD виконує корекцію неупакованого двійково-

десяткового числа, що знаходиться в регістрі АХ, тому подальше ділен-

ня привело до десяткового результату. Наприклад, розділимо десяткове

25 на 5: mov ах,0205h ; 25 в неупакованому форматі mov bl,5 aad ; Тепер в АХ знаходиться 19h div bl ; АХ = 0005 Прапорці SF, ZF і PF встановлюються відповідно до результату,

OF, AF і CF не визначені. Команда AAD, як і ААМ, використовується з будь-якою системою

числення: її код – D5h 0Ah, і другий байт можна замінити на будь-яке

інше число. Дія AAD полягає в тому, що вміст регістра АН помножуєть-

ся на другий байт команди (0Ah за умовчанням) і складається з AL, після

чого АН заповнюється нулями, так що AAD можна використовувати для

швидкого множення на будь-яке число.

4.3. Логічні команди

NOT приймач Інверсія 8086

Команда NOT здійснює операцію інвертування вмісту, що адресу-

ється полем операнда, і повертає результат на те ж місце. Біти умов не

змінюються.

NOT reg/mem

Чотири команди зсуву виконуються над вмістом пам’яті чи регіс-

трів SAL, SAR, SHL, SHR, (рис. 4.1).

SAL приймач, лічильник Арифметичний зсув ліворуч 8086

SAR приймач, лічильник Арифметичний зсув праворуч 8086

SHL приймач, лічильник .Логічний зсув ліворуч 8086

SHR приймач, лічильник Логічний зсув праворуч 8086

Ці чотири команди виконують двійкове зрушення приймача (ре-

гістр або змінна) праворуч (у бік молодшого біта) або ліворуч (у бік ста-

ршого біта) на значення лічильника (число або регістр CL, з якого вра-

ховуються тільки молодші 5 біт, що приймають значення від 0 до 31).

Операція зрушення на 1 еквівалентна множенню (зрушення ліворуч) або

Page 114: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

114

діленню (зрушення праворуч) на 2. Так, число – 10b = 210 після зрушення

на 1 ліворуч перетворюється в 0100b = 410.

Команди SAL і SHL виконують одну і ту ж операцію (насправді це

одна і та ж команда) – на кожен крок зрушення старший біт заноситься в

CF, всі біти зрушуються вліво на одну позицію, і молодший біт заповню-

ється нулями.

Команда SHR здійснює протилежну операцію: молодший біт зано-

ситься в CF, всі біти зрушуються на 1 праворуч, старший біт заповню-

ється нулями. Ця команда еквівалентна беззнаковому цілочисельному

діленню на 2.

Команда SAR діє по аналогії з SHR, тільки старший біт не заповню-

ється нулями, а зберігає попереднє значення. Тому, наприклад, число

11111100b = – 410 перейде в 11111110b = – 210. SAR, таким чином, екві-

валентна знаковому діленню на 2, але на відміну від IDIV, округлення

відбувається не у бік нуля, а у бік негативної нескінченності. Так, якщо

розділити – 9 на 4 за допомогою IDIV вийде – 2 (і залишок – 1), а якщо

виконати арифметичне зрушення праворуч числа – 9 на 2, результатом

буде – 3. Зрушення більше 1 еквівалентні відповідним зрушенням на 1,

виконаним послідовно.

Зрушення на 1 змінюють значення прапорця OF: SAL/SHL встанов-

люють його в 1, якщо після зрушення старший біт змінився (тобто стар-

ші два біти початкового числа не були однаковими), і в 0, якщо старший

біт залишився тим же. SAR встановлює OF в 0, а SHR – в значення ста-

Рис. 4.1. Формати команд зсуву

CF ← RCL CF → RCR

CF → ROR

CF → SAR

SHR

CF ← ROL

CF ← SAL/

SHL

0

7, 15, 31

CF → 0

0

0 0

Page 115: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

115

ршого біта початкового числа. Для зсувів на декілька бітів значення OF

не визначене. Прапорці SF, ZF, PF встановлюються всіма зсувами відпо-

відно до результату, прапорець AF не визначений (крім випадку, коли

лічильник зсувів дорівнює нулю: нічого не відбувається і прапорці не

змінюються).

У процесорах 8086 як другий операнд можна було задавати лише

число 1 і при використанні CL враховувати всі біти, а не тільки молодші

5, але вже починаючи з 80186 ці команди прийняли свій остаточний ви-

гляд. Можливий зсув на один біт і на змінне число бітів, які зазначені в

регістрі CL. Біт CF стає рівним останньому біту, що зсувається; біт OF

визначається тільки для зсуву на один розряд і встановлюється в тому

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

значення біта знака. Біти PF, SF, ZF встановлюються відповідно до зна-

чень результату.

SHL (SHR, SAL, SAR) mem/reg, const

SHL DL, 1 ; Логічний зсув ліворуч Рг DL на 1

SАL AX, CL ; Арифметичний зсув вправо на число,

; що знаходиться в Рг CL

ROL приймач, лічильник Арифметичний зсув ліворуч 8086

ROR приймач, лічильник Арифметичний зсув праворуч 8086

SHL приймач, лічильник .Логічний зсув ліворуч 8086

SHR приймач, лічильник Логічний зсув праворуч 8086

Чотири команди циклічного зсуву з використанням біта CF вико-

нуються над вмістом пам’яті чи регістрів: ROL, ROR, RCL, RCR. Мож-

ливі циклічні зсуви на один біт і змінне число бітів, зазначене в регістрі

CL. Біт CF стає рівним останньому біту, що зсувається; біт OF визнача-

ється тільки для зсувів на один розряд і встановлюється в тому випадку,

якщо біт знака результату операції відрізняється від первісного значення

біта знака.

Існують чотири логічні команди над двома операндами. При всіх

цих операціях біти CF і OF скидаються, а біти SF, PF і ZF відбивають

результат виконання операції.

ROL (ROR, RCL, RCR) mem/reg, count

Команда AND здійснює розрядами логічне множення операндів і

розміщує результат за адресою, що задається першим операндом.

AND приймач, джерело Логічне І 8086

Page 116: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

116

AND прм, прд прм := (прм) (прд)

and al,0000111b ; заповнення нулями старших чотирьох бітів в al

OR приймач, джерело Логічне АБО 8086

Команда OR виконує розрядами логічне додавання операндів і ро-

зміщує результат за першою адресою.

OR прм, прд прм := (прм) (прд)

ХOR приймач, джерело Логічне виключне АБО 8086

Команда XOR виконує розрядами логічне додавання за модулем

два двох операндів і розміщує результат за першою адресою.

XOR прм, прд прм := (прм) (прд)

хor ах, ах ; заповнення нулями ах

TEST приймач, джерело Логічне порівняння 8086

Команда TEST здійснює те ж, що і команда AND. Вона встановлює

біти умов, але не формує результат.

TEST прм, прд (прм) (прд)

Команда обчислює результат дії побітового логічного І над прий-

мачем (регістр або змінна) і джерелом (число, регістр або змінна; джере-

ло і приймач не можуть бути змінними одночасно) і встановлює прапор-

ці SF, ZF і PF відповідно до одержаного показника, не зберігаючи ре-

зультату (прапорці OF і CF заповнення нулями, значення AF не визначе-

не). TEST, так само як і СМР, використовується в основному в поєднанні

з командами умовного переходу (Jcc), умовної пересилки даних

(CMOVcc) і умовного установлення байтів (SETcc).

4.4. Команди обробки бітів та байтів

BT база, зміщення Перевірка біта 80386

Команда ВТ прочитує в прапорець CF значення біта з бітового ряд-

ка, визначеного першим операндом – бітовою базою (регістр або змін-

на), зі зсувом, вказаним в другому операнді – бітовому зсуві (число або

регістр). Коли перший операнд – регістр, то бітовою базою вважається

біт 0 в названому регістрі і зсув не може перевищувати 15 або 31 (залеж-

но від розміру регістра); якщо воно перевищує ці межі, як зсув викорис-

товуватиметься залишок від ділення на 16 або 32 відповідно. Якщо пер-

ший операнд – змінна, то як бітова база потрібен біт 0 вказаного байта в

Page 117: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

117

пам’яті, а зсув може приймати значення від 0 до 31, якщо воно встанов-

лене безпосередньо (старші біти процесором ігноруються), і від – 231 до

231 – 1, якщо воно вказане в регістрі.

Не зважаючи на, те що ця команда прочитує єдиний біт з пам’яті, а

процесор – ціле подвійне слово за адресою База + (4 х (Зміщення/ 32))

або слово за адресою База + (2 х (Зміщення /16)), залежно від розряднос-

ті адреси, все одно не слід користуватися ВТ поблизу від недоступних

для читання областей пам’яті. Після виконання команди ВТ прапорець CF дорівнює значенню лі-

ченого біта, прапорці OF, SF, ZF, AF і PF не визначені.

BTS база, зміщення

BTR база, зміщення

BTC база, зміщення

Перевірка та встановлення біта

Перевірка та скидання біта

Перевірка та інвертування біта

80386

80386

80386

Ці три команди відповідно встановлюють в 1 (BTS), скидають в 0

(ВТК) і інвертують (ВТС) значення біта, який знаходиться в бітовому

рядку з початком, визначеним в базі (регістр або змінна), і зсувом, вка-

заним в другому операнді (число від 0 до 31 або регістр). Якщо бітова

база – регістр, то зсув не може перевищувати 15 або 31 залежно від роз-

рядності цього регістра. Якщо бітова база – змінна в пам’яті, то зсув мо-

же приймати значення від – 231 до 231 – 1 (за умови, що воно вказане в

регістрі). Після виконання команд BTS, ВТК і ВТС прапорець CF дорівнює

значенню ліченого біта до його зміни в результаті дії команди, прапорці

OF, SF, ZF, AF і PF не визначені.

ВSР приймач, джерело

BSR приймач, джерело

Прямий пошук біта

Зворотний пошук біта

80386

80386

BSF сканує джерело (регістр або змінна), починаючи з наймолод-

шого біта, і записує в приймач (регістр) номер першого біта, що зустрів-

ся, рівного 1. Команда BSR сканує джерело, починаючи з найстаршого

біта, і повертає номер першого ненульового біта, що зустрівся, рахуючи

від нуля. Тобто, якщо джерело дорівнює 0000 0000 0000 0010b, то BSF

поверне 1, а BSR – 14.

Якщо джерело дорівнює нулю, значення приймача не визначене і

прапорець ZF встановлюється в 1, інакше ZF завжди скидається. Прапо-

рці CF, OF, SF, AF і PF не визначені.

Page 118: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

118

SETcc приймач Установка байта за умовою 80386

Це набір команд, що встановлюють приймач (8-бітовий регістр або

змінна розміром в 1 байт) в 1 або 0, якщо задовольняється або не задо-

вольняється певна умова. Фактично у кожному випадку перевіряється

стан тих або інших прапорців, але, коли команда з набору SETcc викори-

стовується відразу після СМР, умови набувають формулювань, відповід-

них відносинам між операндами СМР (табл. 4.2). Тобто, якщо операнди

СМР були нерівні, то команда SETNE, що виконана відразу після СМР,

встановить значення свого операнда в 1.

Слова “вище” і “нижче” в таблиці відносяться до порівняння чисел

без знака, слова “більше” і “менше” враховують знак.

Таблиця 4.2 Команди SETcc

Код команди Реальна умова Умова для CMP

SETA

SETNBE CF = 0 та ZF = 0

Якщо вище

Якщо не нижче і не дорівнює

SETAE

SETNB

SETNC

CF = 0

Якщо вище або дорівнює

Якщо не нижче

Якщо немає перенесення

SETB

SETNAE

SETC

CF = 1

Якщо нижче

Якщо не вище і не дорівнює

Якщо перенесення

SETBE

SETNA CF = 1 або ZF = 1

Якщо нижче або дорівнює

Якщо не вище

SETE

SETZ ZF = 1

Якщо дорівнює

Якщо нуль

SETG

SETNLE ZF = 0 и SF = OF

Якщо більше

Якщо не менше і не дорівнює

SETGE

SETNL SF = OF

Якщо більше або дорівнює

Якщо не менше

SETL

SETNGE SF < > OF

Якщо менше

Якщо не більше та не дорівнює

SETLE

SETNG ZF = 1 або SF < > OF

Якщо менше або дорівнює

Якщо не більше

SETNE

SETNZ ZF = 0

Якщо не дорівнює

Якщо не нуль

Page 119: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

119

Закінчення табл. 4.2

SETNO OF = 0 Якщо немає переповнювання

SETO OF = 1 Якщо є переповнювання

SETNP

SETPO PF = 0

Якщо немає парності

Якщо непарне

SETP

SETPE PF = 1

Якщо є парність

Якщо парне

SETNS SF = 0 Якщо немає знаку

SETS SF = 1 Якщо є знак

4.5. Команди передачі керування

JMP операнд Безумовний перехід 8086

JMP передає керування в іншу точку програми, не зберігаючи інфо-

рмацію для повернення. Операндом може бути безпосередня адреса для

переходу (в програмах використовують ім’я мітки, встановленої перед

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

містить адресу.

Залежно від типу переходу розрізняють:

перехід типу short (короткий перехід) – якщо адреса переходу

знаходиться в межах – 128...+ 127 байт від команди JMP;

перехід типу near (ближній перехід) – якщо адреса переходу

знаходиться в тому ж сегменті пам’яті, що і команда JMP;

перехід типу far (дальній перехід) – якщо адреса переходу зна-

ходиться в іншому сегменті. Дальній перехід може виконуватися і в той

же самий сегмент за умови, що в сегментній частині операнда вказано

число, що збігається з поточним значенням CS;

перехід з перемиканням завдання – передача керування іншому

завданню в багатозадачному середовищі.

При виконанні переходів типу short і near команда JMP фактично

перетворює значення регістра EIP (або IP), змінюючи тим самим зсув

наступної виконуваної команди щодо початку сегмента коду. Якщо опе-

ранд –регістр або змінна в пам’яті, то його показник просто копіюється в

EIP, неначебто це була команда MOV. Якщо операнд для JMP – безпосе-

редньо вказане число, то його значення додається до вмісту EIP, приво-

дячи до відносного переходу. У асемблерних програмах як операнд зви-

чайно указують імена міток, але на рівні виконуваного коду асемблер

Page 120: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

120

обчислює і записує саме відносні зсуви.

Виконуючи далекий перехід в реальному, віртуальному і захище-

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

JMP завантажує: нове значення в EIP і новий селектор сегмента коду в

CS, використовуючи старші 16 біт операнда як нове значення для CS і

молодші 16 або 32 біт як значення IP або EIP.

Jcc мітка Умовний перехід 8086

Це набір команд, що виконують перехід (типу short або near), якщо

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

стан тих або інших прапорців. Але, коли команда з набору Jcc викорис-

товується відразу після СМР, умови набувають формулювань, відповід-

них взаємодіям між операндами СМР (табл. 4.3).

Таблиця 4.3

Варіанти команди Jcc

Код команди Реальна умова Умова для CMP

JA JBE

CF = 0 та ZF = 0 Якщо вище Якщо не нижче і не дорівнює

JAE JNB JNC

CF = 0 Якщо вище або дорівнює Якщо не нижче Якщо немає перенесення

JB JNAE JC

CF = 1 Якщо нижче Якщо не вище і не дорівнює Якщо перенесення

JBE JNA

CF = 1 або ZF = 1 Якщо нижче або дорівнює Якщо не вище

JE JZ

ZF = 1 Якщо дорівнює Якщо нуль

JG JNLE

ZF = 0 та SF = OF Якщо більше Якщо не менше і не дорівнює

JGE JNL

SF = OF Якщо більше або дорівнює Якщо не менше

JL JNGE

SF < > OF Якщо менше Якщо не більше і не дорівнює

JLE JNG

ZF = 1 або SF < > OF

Якщо менше або дорівнює Якщо не більше

JNE JNZ

ZF = 0 Якщо не дорівнює Якщо не нуль

JNO OF = 0 Якщо немає переповнювання

Page 121: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

121

Закінчення табл. 4.3

JO OF=1 Якщо є переповнювання

JNP JPO

PF = 0 Якщо немає парності Якщо непарне

JP JPE

PF = 1 Якщо є парність Якщо парне

JNS SF = 0 Якщо немає знака

JS SF =1 Якщо є знак

Слова “вище” і “нижче” в табл. 4.3 належать до порівняння чисел

без знака; слова “більше” і “менше” враховують знак.

Команди Jcc не підтримують далеких переходів, тому, якщо потріб-

но виконати умовний перехід на далеку мітку, необхідно використати

команду з набору Jcc зі зворотною умовою і далекий JMP, як, наприклад:

cmp ах,0

jne 1оса1_1

jmp far_label ; Перехід, якщо АХ = 0.

local_1:

JCXZ мітка

JECXZ мітка

Перехід, якщо СХ = 0

Перехід, якщо ЕСХ = 0

8086

80386

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

СХ або EGX (для JCXZ і JECXZ відповідно) дорівнює нулю. Так само як

і команди із серії Jcc, JCXZ і JECXZ не можуть виконувати далеких пе-

реходів. Перевірка рівності СХ нулю, наприклад, може бути потрібно на

початку циклу, організованого командою LOOPNE. Якщо в нього увійти

з СХ = 0, то він буде виконаний 65 535 разів.

LOOP мітка Умовний перехід 8086

Команда LOOP зменшує регістр ЕСХ на 1 і виконує перехід типу

short на мітку (яка не може бути далі відстані – 128...+ 127 байт від ко-

манди LOOP), якщо ЕСХ не дорівнює нулю. Ця команда використову-

ється для організації циклів, в яких регістр ЕСХ (або СХ при 16-бітовій

адресації) виконує роль лічильника. Так, в наступному фрагменті коман-

да ADD виконується 10 разів:

mov cx,0Ah

loop_start:

add ах,cx

Page 122: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

122

loop loop_start

Команда LOOP повністю еквівалентна парі команд:

dec ecx

jnz мітка

Але LOOP коротше за ці дві команди на один байт і не змінює зна-

чення прапорців.

LOOPE мітка

LOOPZ мітка

LOOPNE мітка

LOOPNZ мітка

Цикл, поки дорівнює

Цикл, поки нуль

Цикл, поки не дорівнює

Цикл, поки не нуль

8086

8086

8086

8086

Всі перераховані команди зменшують регістр ЕСХ на один, після

чого виконують перехід типу short, якщо ЕСХ не дорівнює нулю і якщо

виконується умова. Для команд LOOРЕ і LOOPZ умовою є рівність оди-

ниці прапорця ZF; для команд LOOPNE і LOOPNZ – рівність прапорця

ZF нулю. Самі команди LOOPcc не змінюють значень прапорців, тому

ZF повинен бути встановлений (або скинутий) попередньою командою.

CALL операнд Виклик процедури 8086

Команда CALL зберігає поточну адресу в стеку і передає керування

за адресою, вказаною в операнді. Операндом може бути безпосереднє

значення адреси (мітка в асемблерних програмах), регістр або змінна,

що містить адресу переходу. Якщо за адресу переходу вказано тільки

зсув, вважається, що адреса розташована в тому ж сегменті, що і коман-

да CALL. При цьому, так само як й у випадку з командою JMP, викону-

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

EIP (IP при 16-бітовій адресації), відповідне наступній за CALL команді,

в стек і завантажує в EIP нове значення, здійснюючи тим самим переда-

чу керування. Якщо операнд CALL – регістр або змінна, то його значен-

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

програмі, то асемблер указує її відносний зсув.

Щоб виконати далекий CALL в реальному режимі, режимі V86 або

в захищеному режимі при переході в сегмент з тими ж привілеями, про-

цесор поміщає в стек значення регістрів CS і EIP (IP при 16– бітовій ад-

ресації) і здійснює далекий перехід аналогічно команді JMP.

RET число RETN число

Повернення з процедури 8086

Page 123: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

123

RETF число

Команда RETN прочитує зі стека слово (або подвійне слово, зале-

жно від режиму адресації) і завантажує його в IP (або EIP), виконуючи

тим самим дії, зворотні ближньому виклику процедури командою CALL.

Команда RETF завантажує зі стека IP (EIP) і CS, повертаючись з далекої

процедури. Якщо в програмі вказана команда RET, асемблер замінить її

на RETN або RETF залежно від того, як була описана процедура, яку ця

команда завершує. Операнд для RET необов’язковий, але, якщо він при-

сутній, після зчитування адреси повернення зі стека буде видалена вка-

зана кількість байтів. Це потрібне, якщо при виклику процедури їй пере-

давалися параметри через стек.

INT число Виклик переривання 8086

Команда INT аналогічно команді CALL поміщає в стек вміст регіс-

трів ЕFLAGS, CS і EIP, після чого передає керування програмі, яка

зветься обробником переривань з вказаним як операнд номером (число

від 0 до 0FFh). У реальному режимі адреси обробників переривань про-

читуються з таблиці, що починається в пам’яті за адресою 0000:0000h.

Адреса кожного обробника займає 4 байт. Тому, наприклад, обробник

переривання 10h знаходиться в пам’яті за адресою 0000:0040h. У захи-

щеному режимі адреси обробників переривань знаходяться в таблиці

IDT і недоступні для прямого читання або запису, тому для установлен-

ня власного обробника програма повинна звертатися до операційної сис-

теми. У DOS виклики переривань використовуються для виконання бі-

льшості системних функцій – роботи з файлами, введенням/виведенням і

т.д.

Наприклад, наступний фрагмент коду завершує виконання програ-

ми і повертає керування DOS:

mov ах,4C01h

int 21h

IRET

IRETD

Повернення з обробника переривання 8086

Команда IRET завантажує зі стека значення IP, CS і FLAGS, а

IRETD – EIP, CS і EFLAGS відповідно. Єдина відмінність IRET від

RETF полягає в тому, що значення регістра прапорців відновлюється,

через що багатьом обробникам переривань доводиться змінювати вели-

чину EFLAGS, що знаходиться в стеку, щоб, наприклад, повернути пра-

Page 124: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

124

порець CF, встановлений у разі помилки.

INT3 Виклик переривання 3 8086

Розмір команди INT3 – один байт (код 0CCh), що робить її зручною

для доведення програм відладчиками, що працюють в реальному режи-

мі. Вони записують цей байт замість першого байта команди, перед

якою потрібна точка зупинки, і перевизначають адресу обробника пере-

ривання 3 на відповідну процедуру усередині налвгоджувача.

INTО Виклик переривання 4 при переповнюванні 8086

Команда INTO – ще одна спеціальна форма команди INT. Вона ви-

кликає обробник переривання 4, якщо прапорець OF встановлений в 1.

BOUND індекс, межі Перевірка виходу за межі масиву 80186

Команда BOUND перевіряє, чи не виходить значення першого опе-

ранда (регістр), узяте як число зі знаком, за межі, вказані в другому опе-

ранді (змінна). Межі – два слова або подвійних слова (залежно від роз-

рядності операндів), що розглядаються як цілі зі знаком і розташовані в

пам’яті підряд. Перша межа вважається нижньою, друга – верхньої. Як-

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

ривання 5 (або виключення #BR), причому адреса повернення вказує не

на наступну команду, а на BOUND. Тому обробник повинен виправити

значення індексу або меж, перш ніж виконувати команду IRET.

ENTER розмір, рівень Вхід у процедуру 80186

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

вкладеності (обидва операнди – числа; рівень вкладеності може прийма-

ти значення тільки від 0 до 31) з метою виклику процедури, що викорис-

товує динамічний розподіл пам’яті в стеку для своїх локальних змінних.

Так, команда

enter 2048,3

поміщає в стек покажчики на стековий кадр поточної процедури і тієї, з

якої викликалася поточна, створює стековий кадр розміром 2 Кбайт для

процедури, що викликається, і поміщає на ЕВР адресу початку кадра.

Нехай процедура MAIN має рівень вкладеності 0, процедура

PROCA запускається з MAIN і має рівень вкладеності 1, і PROCB запус-

кається з PROCA з рівнем вкладеності 2. Тоді стек при вході в процеду-

ру MAIN має вигляд, наведений на рис. 4.2.

Page 125: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

125

Тепер процедура MAIN може визначати свої локальні змінні в

пам’яті, використовуючи поточне значення ЕВР.

На першому рівні вкладеності процедура PROCA, як наведено на

рис. 4.3, може створювати свої локальні змінні, застосовуючи поточне

значення ЕВР, і дістане доступ до локальних змінних процедури MAIN,

використовуючи значення ЕВР для MAIN, поміщене в стек командою

ENTER.

Процедура PROCB на другому рівні вкладеності (рис. 4.4) дістає

доступ як до локальних змінних процедури PROCA, застосовуючи зна-

чення ЕВР для PROCA, так і до локальних змінних процедури MAIN,

використовуючи значення ЕВР для MAIN.

LEAVE Вихід із процедури 80186

Команда LEAVE виконує дії, протилежні команді ENTER. Фактич-

но LEAVE тільки копіює вміст ЕВР в ESP, тим самим викидаючи зі сте-

старий ЕВР

ЕВР для MAIN

локальні

змінні

для MAIN

ЕВР для MAIN

ЕВР для MAIN

ЕВР для PROCA

локальні

змінні

для PROCA

Рис. 4.3. Стековий кадр

процедури першого рівня

(PROCA)

ЕВР

ЕSP

старий ЕВР

ЕВР для MAIN

локальні

змінні

для MAIN

Рис. 4.2. Стековий

кадр процедури ну-

льового рівня (MAIN)

ЕВР

ЕSP

старий ЕВР

ЕВР для MAIN

локальні

змінні

для MAIN

ЕВР для MAIN

ЕВР для MAIN

ЕВР для PROCA

локальні

змінні

для PROCA

ЕВР для PROCA

ЕВР для MAIN

ЕВР для PROCA

ЕВР для PROCВ

локальні

змінні

для PROCВA

Рис. 4.4. Стековий кадр

процедури другого рівня

(PROCВ)

ЕВР

ЕSP

Page 126: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

126

ка весь кадр, створений останньою виконаною командою ENTER, і про-

читує зі стека ЕВР для попередньої процедури, що одночасно відновлює

і значення, яке мав ESP до виклику останньої команди ENTER.

4.6. Рядкові операції

Всі команди для роботи з рядками вважають, що рядок–джерело

знаходиться за адресою DS:SI (або DS:ESI), тобто в сегменті пам’яті,

вказаному в DS зі зсувом в SI, а рядок–приймач – відповідно в ES:DI

(або ES:EDI). Крім того, всі рядкові команди працюють тільки з одним

елементом рядка (байтом, словом або подвійним словом) за один раз.

Для того щоб команда виконувалася над всім рядком, необхідний один з

префіксів повторення операцій.

REP

REPE

REPNE

REPZ

REPNZ

Повторювати

Повторювати, поки дорівнює

Повторювати, поки не дорівнює

Повторювати, поки нуль

Повторювати, поки не нуль

8086

Всі перераховані команди є префіксами для операцій над рядками.

Будь- який з префіксів виконує наступну за ним команду рядкової обро-

бки стільки разів, скільки вказане в регістрі ЕСХ (або СХ, залежно від

розрядності адреси), зменшуючи його при кожному виконанні команди

на 1. Крім того, REPZ і REPE припиняють повторення команди, якщо

прапорець ZF = 0, а REPNZ і REPNE припиняють повторення, якщо пра-

порець ZF = 1. Префікс REP звичайно використовується з командами

INS, OUTS, MOVS, LODS, STOS, а префікси REPE, REPNE, REPZ і

REPNZ – з командами CMPS і SCAS. Поведінка префіксів в інших випа-

дках не визначена.

MOVS приймач, джерело

MOVSB приймач, джерело

MOVSW приймач, джерело

MOVSD приймач, джерело

Копіювання рядка

Копіювання рядка байтів

Копіювання рядка слів

Копіювання рядка подвійних слів

8086

8086

8086

80386

Ці команди копіює один байт (MOVSB), слово (MOVSW) або по-

двійне слово (MOVSD) з пам’яті за адресою DS:ESI (або DS:SI, залежно

від розрядності адреси) у пам’ять за адресою ES:EDI (або ES:DI). При

використанні форми запису MOVS асемблер сам визначає за типом вка-

Page 127: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

127

заних операндів, яку з трьох форм цієї команди (MOVSB, MOVSW або

MOVSD) вибрати. Використовуючи MOVS з операндами, дозволяється

замінити регістр DS іншим за допомогою префікса заміни сегмента (ES:,

GS:, FS:, CS:, SS:), регістр ES замінити не можна. Після виконання ко-

манди регістри ESI (або SI) і EDI (або DI) збільшуються на 1, 2 або 4

(якщо копіюються байти, слова або подвійні слова), коли прапорець DF

= 0, і зменшуються, коли DF = 1. Команда MOVS з префіксом REP вико-

нує копіювання рядка завдовжки в ЕСХ (або СХ) байтів, слів або по-

двійних слів.

CMPS приймач, джерело

CMPSB приймач, джерело

CMPSW приймач, джерело

CMPSD приймач, джерело

Порівняння рядків

Порівняння рядків байтів

Порівняння рядків слів

Порівняння рядків подвійних слів

8086

8086

8086

80386

Команда CMPS порівнює один байт (CMPSB), слово (CMPSW) або

подвійне слово (CMPSD) з пам’яті за адресою DS:ESI (або DS:SI, залеж-

но від розрядності адреси) з байтом, словом або подвійним словом за

адресою ES:EDI (або ES:DI) і встановлює прапорці аналогічно команді

СМР. При використанні форми запису CMPS асемблер сам визначає за

типом вказаних операндів (прийнято указувати імена порівнюваних ряд-

ків, але можна використовувати будь–які два операнди відповідного ти-

па), яку з трьох форм цієї команди (CMPSB, CMPSW або CMPSD) виб-

рати. Застосовуючи CMPS з операндами, можна замінити регістр DS

іншим, скориставшись префіксом заміни сегмента (ES:, GS:, FS:, CS:,

SS:), регістр ES замінити не можна. Після виконання команди регістри

ESI (або SI) і EDI (або DI) збільшуються на 1, 2 або 4 (якщо порівню-

ються байти, слова або подвійні слова), коли прапорець DF = 0, і змен-

шуються, коли DF = 1. Команда CMPS з префіксами REPNE/REPNZ або

REPE/REPZ виконує порівняння рядка завдовжки в ЕСХ або СХ) байтів,

слів або подвійних слів. У першому випадку порівняння триває до пер-

шого збігу в рядках, а в другому – до першого несбігання.

SCAS приймач

SCASB приймач

SCASW приймач

SCASD приймач

Сканування рядка

Сканування рядка байтів

Сканування рядка слів

Сканування рядка подвійних слів

8086

8086

8086

80386

Page 128: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

128

Команда SCAS порівнює вміст регістра AL (SCASB), AX (SCASW)

або ЕАХ (SCASD) з байтом, словом або подвійним словом з пам’яті за

адресою ES:EDI (або ES:DI, залежно від розрядності адреси) і встанов-

лює прапорці аналогічно команді СМР. При використанні форми запису

SCAS асемблер сам визначає за типом вказаного операнда (прийнято

казувати ім’я сканованого рядка, але можна використовувати будь-який

операнд відповідного типа), яку з трьох форм цієї команди (SCASB,

SCASW або SCASD) вибрати. Після виконання команди регістр EDI (або

DI) збільшується на 1, 2 або 4 (якщо скануються байти, слова або по-

двійні слова), коли прапорець DF = 0, і зменшується, коли DF = 1. Ко-

манда SCAS з префіксами REPNE/REPNZ або REPE/REPZ виконує ска-

нування рядка завдовжки в ЕСХ (або СХ) байтів, слів або подвійних

слів. У першому випадку сканування триває до першого елемента рядка,

що збігається з вмістом акумулятора, а в другому – до першого відмін-

ного.

LODS джерело

LODSB джерело

LODSW джерело

LODSD джерело

Читання з рядка

Читання байта з рядка

Читання слова з рядка

Читання подвійного слова з рядка

8086

8086

8086

80386

Команда LODS копіює один байт (LODSB), слово (LODSW) або

подвійне слово (LODSD) з пам’яті за адресою DS:ESI (або DS:SI, залеж-

но від розрядності адреси) у регістр AL, АХ або ЕАХ відповідно. При

використанні форми запису LODS асемблер сам визначає за типом вка-

заного операнда, яку з трьох форм цієї команди (LODSB, LODSW або

LODSD) вибрати. Застосовуючи LODS з операндом, можна замінити

регістр DS на іншій за допомогою префікса заміни сегмента (ES:, GS:,

FS:, CS:, SS:). Після виконання команди регістр ESI (або SI) збільшуєть-

ся на 1, 2 або 4 (якщо прочитується байт, слово або подвійне слово), ко-

ли прапорець DF = 0, і зменшується, коли DF = 1. Команда LODS з пре-

фіксом REP виконає копіювання рядка завдовжки в ЕСХ (або СХ), і в

акумуляторі опиниться останній елемент рядка. Насправді LODS вико-

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

STOS. Тому LODS прочитує число, інші команди виконують над ним

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

пам’яті.

STOS приймач Запис в рядок 8086

Page 129: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

129

STOSB приймач

STOSW приймач

STOSD приймач

Запис байта в рядок

Запис слова в рядок

Запис подвійного слова в рядок

8086

8086

80386

Команда STOS копіює регістр AL (STOSB), AX (STOSW) або ЕАХ

(STOSD) в пам’ять за адресою ES:EDI (або ES:DI, залежно від розрядно-

сті адреси). При використанні форми запису STOS асемблер сам визна-

чає за типом вказаного операнда (прийнято вказувати ім’я рядка, але

можна використовувати будь-який операнд відповідного типу), яку з

трьох форм цієї команди (STOSB, STOSW або STOSD) вибрати. Після

виконання команди регістр EDI (або DI) збільшується на 1, 2 або 4 (якщо

копіюється байт, слово або подвійне слово), коли прапорець DF = 0, і

зменшується, коли DF = 1. Команда STOS з префіксом REP заповнить

рядок завдовжки в ЕСХ (або СХ) числом, що знаходиться в акумуляторі.

INS джерело, DX

INSB джерело, DX

INSW джерело, DX

INSD джерело, DX

Читання рядка з порту

Читання рядка байтів з порту

Читання рядка слів з порту

Читання рядка подвійних слів з порту

80186

80186

80186

80386

Команда INS прочитує з порту введення-виведення, номер якого

вказаний в регістрі DX, байт (INSB), слово (INSW) або подвійне слово

(INSD) в пам’ять за адресою ES:EDI (або ES:DI, залежно від розрядності

адреси). При використанні форми запису INS асемблер визначає за ти-

пом вказаного операнда, яку з трьох форм цієї команди (INSB, INSW або

INSD) використати. Після виконання команди регістр EDI (або DI) збі-

льшується на 1, 2 або 4 (якщо прочитується байт, слово або подвійне

слово), коли прапорець DF = 0, і зменшується, коли DF = 1. Команда INS

з префіксом REP прочитує блок даних з порту завдовжки в ЕСХ (або

СХ) байтів, слів або подвійних слів.

OUTS DX, приймач

OUTSB DX, приймач

OUTSW DX, приймач

OUTSD DX, приймач

Запис рядка в порт

Запис рядка байтів в порт

Запис рядка слів в порт

Запис рядка подвійних слів в порт

80186

80186

80186

80386

Комада OUTS записує в порт введення-виведення, номер якого вка-

заний в регістрі DX, байт (OUTSB), слово (OUTSW) або подвійне слово

(OUTSD) з пам’яті за адресою DS:ESI (або DS:SI, залежно від розрядно-

сті адреси). При використанні форми запису OUTS асемблер визначає за

типом вказаного операнда, яку з трьох форм цієї команди (OUTSB,

Page 130: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

130

OUTSW або OUTSD) використовується. Застосовуючи OUTS з операн-

дами, також можна замінити регістр DS іншим за допомогою префікса

заміни сегмента (ES:, GS:, FS:, CS:, SS:). Після виконання команди ре-

гістр ESI (або SI) збільшується на 1, 2 або 4 (якщо прочитується байт,

слово або подвійне слово), коли прапорець DF = 0, і зменшується, коли

DF = 1. Команда OUTS з префіксом REP записує блок даних розміром в

ЕСХ (або СХ) байтів, слів або подвійних слів у вказаний порт. Всі про-

цесори до Pentium не перевіряли готовність порту прийняти нові дані в

ході виконання команди REP OUTS. Тому, якщо порт не встигав оброб-

ляти інформацію з тією швидкістю, з якою її постачала ця команда, час-

тина даних втрачалася.

4.7. Інші команди

NOP Операції відсутня 8086

Команда NOP – однобайтова команда (код 90h), яка не виконує ні-

чого, тільки займає місце і час. Код цієї команди фактично відповідає

XCHG AL,AL. Багато команд дозволяється записати так, що вони не

приводитимуть ні до яких дій, наприклад: mov ах, ах ; 2 байт

xchg ах, ах ; 2 байт

lea bx,[bx+0] ; 3 байт (8Dh, 5Fh, 00h, але багато асемблерів

; зустрівши таку команду, реально використовують

; коротшу lea bx,[bx] з кодом 8Dh 1Fh).

shl eax,0 ; 4 байт.

shrd eax,eax,0 ; 5 байт.

LOCK Префікс блокування шини даних 8086

На весь час виконання команди, забезпеченої таким префіксом, бу-

де заблокована шина даних, і якщо в системі присутній інший процесор,

він не зможе звертатися до пам’яті, поки не закінчиться виконання ко-

манди з префіксом LOCK. Команда XCHG завжди виконується автома-

тично з блокуванням доступу до пам’яті, навіть якщо префікс LOCK не

вказаний. Цей префікс можна використовувати тільки з командами ADD,

ADC, AND, BTC, ВТК, BTS, CMPXCHG, DEC, INC, NEC, NOT, OR,

SBB, SUB, XOR, XADD і XCHG.

UD2 Невизначена операція P6

Page 131: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

131

Ця команда завжди викликає помилку “невизначена операція” (ви-

ключення #UD). Вперше вона описана як така для Pentium Pro, але у всіх

попередніх процесорах UD2 (код 0Fh 0Bh) не була визначена і, природ-

но, призводила до такої ж помилки. Команда призначена для тестування

програмного забезпечення, зокрема операційних систем, які повинні

вміти коректно обробляти таку помилку. Назва команди походить від

команди UD (код 0Fh 0FFh), яка була визначена AMD для процесорів

AMD K5.

CPUID Ідентифікація процесора 80486

Команда CPUID повідомляє інформацію про виробника, тип і мо-

дифікацію процесора і про наявність різних розширень. Команда CPUID

підтримується Intel, починаючи з процесорів Intel 80486DX/SX/DX2 SL,

UMC U5S, Cyrix Ml, AMD, 80486DX4. Спробуйте встановити прапорець

ID в 1 (біт 21 в регістрі EFLAGS). Якщо це виходить, значить команда

CPUID підтримується. Результат роботи CPUID залежить від значення регістра ЕАХ. Як-

що ЕАХ = 0, CPUID повертає в ЕАХ максимальне значення, з яким її

можна викликати (2 для Р6, 1 для Р5), а регістри EBX:ECX:EDX містять

12-байтовий рядок – ідентифікатор виробника (табл. 4.4).

Таблиця 4.4

Рядки виробників в CPUID Виробник Рядок в EBX:ECX:EDX Intel Genuinelntel UMC UMC UMC UMC Cyrix Cyrixlnstead AMD AuthenticAMD NexGen NexGenDriven

Centaur Technology CentaurHalls

Наприклад, для процесорів Intel регістр ЕВХ містить Genu

(756E6547h), ЕСХ – inel (49656E69h), а EDX – ntel (6C65746Eh). Якщо ЕАХ = 1, CPUID повертає в ЕАХ інформацію про версію

процесора, а в EDX – відомості про підтримувані розширення. Багато

понять в цьому описі відносяться до роботи процесора в захищеному

режимі і розглядаються нижче. Інформація про версію процесора:

Page 132: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

132

біти 3 – 0 – модифікація; біти 7 – 4 – модель; біти 11 – 8 – сімейство (3 для 386, 4 для 486, 5 для Pentium, 6 для

Pentium Pro); біти 13 – 12 – тип (0 – OEM, 1 – Overdrive, 2 – Dual); біти 31 – 14 – зарезервовані і рівні нулю.

Підтримувані розширення (регістр EDX): біт 0: FPU – процесор містить FPU і може виконувати весь набір

команд 80387; біт 1: VME – процесор підтримує вдосконалений режим V86 (пра-

порці VIF і VIP в EFLAGS, біти VME і PVI в CR0); біт 2: DE – процесор підтримує точки зупинки по введен-

ню/виведенню, біт DE в CR0; біт 3: PSE – процесор підтримує сторінки до 4 Мб, біт PSE в CR4,

модифіковані біти в елементах списків сторінок (PDE) і таблиць сторі-

нок (РОТІ); біт 4: TSC – процесор підтримує команду RDTSC і біт TSC в CR4; біт 5: MSR – процесор підтримує команди RDMSR і WRMSR і ма-

шинно– специфічні регістри, сумісні з Pentium; біт 6: РАЕ – процесор підтримує фізичні адреси більше 32 біт, до-

датковий рівень в таблицях трансляції сторінок, сторінки по 2 Мбайт і

біт РАЕ в CR4. Число бітів для фізичних адрес залежить від моделі про-

цесора. Так, Pentium Pro підтримує 36 біт; біт 6: РТЕ (тільки для Cyrix); біт 7: МСЕ – процесор підтримує біт МСЕ в CR4; біт 8: СХ8 – процесор підтримує команду CMPXCHG8B; біт 9: APIC – процесор містить вбудований контролер переривань

(APIC), який активізований і доступний; біт 9: PGE (тільки для AMD); біт 10: зарезервований; біт 11: SEP – процесор підтримує швидкі системні виклики, коман-

ди SYSENTER і SYSEXIT (Pentium II);

біт 12: MTRR – процесор підтримує машинно-специфічні регістри

MTRR;

біт 13: PGE – процесор підтримує біт PGE в CR4 і глобальні прапо-

рці у PTDE і РТЕ, які вказують елементи TLB, що належать відразу де-

кільком завданням;

Page 133: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

133

біт 14: МСА – процесор підтримує машинно-специфічний регістр

MCG_CAP;

біт 15: CMOV – процесор підтримує команди CMOVcc і (якщо біт

0 EDX встановлений) FCMOVcc (Pentium Pro); біт 16: PAT – процесор підтримує таблицю атрибутів сторінок;

біти 17 – 22: зарезервовані; біт 23: ММХ – процесор підтримує набір команд ММХ;

біт 24: FXSR – процесор підтримує команди швидкого читан-

ня/запису (ММХ2); біт 25: SSE – процесор підтримує розширення SSE (Pentium III);

біти 31 – 26: зарезервовані. Якщо ЕАХ = 2, то команда CPUID на процесорах сімейства Р6 по-

вертає в регістри ЕАХ, ЕВХ, ЕСХ і EDX інформацію про кеш і TLB.

Наймолодший байт ЕАХ (регістр AL) визначає, скільки разів треба ви-

кликати CPUID з ЕАХ = 2, щоб одержати інформацію про всі кеші (1 для

Pentium Pro і Pentium II). Найстарший біт (біт 31) кожного регістра вка-

зує, чи містить цей регістр правильну інформацію (біт 31 = 0) або він

зарезервований (біт 31 = 1). У першому випадку регістр містить інфор-

мацію в однобайтових дескрипторах з наступними значеннями:

00h – порожній дескриптор;

0lh – TLB команд, 4-кілобайтові сторінки, 4-стороння асоціатив-

ність, 32 елементи;

02h – TLB команд, 4-мегабайтові сторінки, 4-стороння асоціатив-

ність, 4 елементи;

03h – TLB даних, 4-кілобайтові сторінки, 4-стороння асоціатив-

ність, 64 елементи;

04h – TLB даних, 4-мегабайтниє сторінки, 4-стороння асоціатив-

ність, 8 елементів; 06h – кеш команд, 8 Кбайт, 4-стороння асоціативність, 32 байт в ря-

дку;

08h – кеш команд, 16 Кбайт, 4-стороння асоціативність, 32 байт в

рядку;

0Ah – кеш даних, 8 Кбайт, 2-стороння асоціативність, 32 байт в ря-

дку;

0Сh – кеш даних, 16 Кбайт, 2-стороння асоціативність, 32 байт в

рядку;

41h – уніфікований кеш, 128 Кбайт, 4-стороння асоціативність,

32 байт в рядку;

Page 134: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

134

42h – уніфікований кеш, 256 Кбайт, 4-сторонняя асоціативність, 32

байт в рядку;

43h – уніфікований кеш, 512 Кбайт, 4-сторонняя асоціативність,

32 байт в рядку;

44h – уніфікований кеш, 1 Мбайт, 4-сторонняя асоціативність, 32

байт в рядку.

Сумісні з Intel процесори AMD і Cyrix підтримують виклик “роз-

ширених функцій” CPUID зі значеннями ЕАХ, в яких найсамий старший

біт завжди встановлений в 1. ЕАХ = 80000000h: повертає в ЕАХ максимальний номер розшире-

ної функції CPUID, підтримуваної даним процесором. ЕАХ = 8000000lh: повертає в ЕАХ 051Xh для AMD K5 (X – номер

модифікації) або 061Xh для AMD К6. У EDX ця функція повертає інфо-

рмацію про підтримувані розширення (вказані тільки прапорці, що відрі-

зняються від CPUID з ЕАХ = 1): біт 5: MSR – процесор підтримує машинно-специфічні регістри,

сумісні з К5; біт 10: процесор підтримує команди SYSCALL і SYSRET; біт 16: процесор підтримує команди FCMOVcc; біт 24: процесор підтримує ММХ з розширеннями від Cyrix; біт 25: процесор підтримує набір команд AMD 3D. ЕАХ = 80000002h, 80000003h і 80000004h – послідовний виклик

CPUID з цими значеннями в ЕАХ повертає в EAX:EBX:ECX:EDX послі-

довно чотири 16-байтові частини рядка – імені процесора. Наприклад:

AMD K5(tm) Processor. ЕАХ = 80000005Н – команда повертає інформацію про TLB в регіс-

трі ЕВХ (старше слово – TLB даних, молодше слово – TLB команд,

старший байт – асоціативність, молодший байт – число елементів), про

кеш даних в регістрі ЕСХ і про кеш команд в регістрі EDX (біти 31 – 24

– розмір в кілобайтах, біти 23 – 16 – асоціативність, біти 15 – 8 – число

ліній на тег, біти 7 – 0 – кількість байтів на лінію).

4.8. Числа з рухомою крапкою

У процесорах Intel всі операції з рухомою крапкою виконує спеціа-

льний пристрій – FPU (Floating Point Unit), з власними регістрами і влас-

ним набором команд, який спочатку постачався у вигляді співпроцесора

Page 135: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

135

(8087, 80287, 80387, 80487), а починаючи з 80486DX – вбудовується в

основний процесор.

4.8.1. Типи даних FPU

Числовий процесор може виконувати операції з сьома різними ти-

пами даних, наведених в табл. 4.5 – три цілих двійкових, один цілий де-

сятковий і три типу даних з плаваючою комою.

Таблиця 4.5

Типи даних FPU

Тип даних

Біт

Кількість

значущих

цифр

Межі

Ціле слово 16 4 – 32768 – 32767

Коротке ціле 32 9 – 2*109 – 2*109

Довге ціле 64 18 – 9*1018 – 9*1018

Упаковане десяткове 80 18 – 99..99 – +99..99 (18 цифр)

Коротке дійсне 32 7 1,18*10– 38 – 3,40*1038

Довге дійсне 64 15 – 16 2,23*10– 308 – 1,79*10308

Розширене дійсне 80 19 3,37*10– 4932 – 1,18*104932

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

Двійковий запис числа з плаваючою комою аналогічний десятковим,

тільки позиції праворуч від крапки відповідають не діленню на 10 у від-

повідному ступені, а діленню на 2.

При записі дійсних чисел завжди виконують нормалізацію – пом-

ножують число на такий ступінь двійки, щоб перед десятковою крапкою

була одиниця.

При використанні цього алгоритму перша цифра мантиси завжди

дорівнює 1, тому її можна не писати, збільшуючи тим самим точність

подання числа додатково на 1 біт. Крім того, значення експоненти збері-

гають не у вигляді цілого із знаком, а у вигляді суми з деяким числом

так, щоб зберігати завжди тільки позитивне число і щоб було легко порі-

внювати дійсні числа – в більшості випадків досить порівняти експонен-

ту.

В процесорах Intel використовують наступні дійсні формати чисел:

Page 136: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

136

– коротке дійсне: біт 31 – знак мантиси, біти 30 – 23 – 8-бітова

експонента + 127, біти 22 – 0 – 23-бітова мантиса без першої цифри; довге дійсне: біт 63 – знак мантиси, біти 62 – 52 – 11-бітова екс-

понента + 1024, біти 51 – 0 – 52-бітова мантиса без першої цифри; розширене дійсне: біт 79 – знак мантиси, біти 78 – 64 – 15-бітова

експонента + 16 383, біти 63 – 0 – 64-бітова мантиса з першою цифрою

(тобто біт 63 дорівнює 1). FPU виконує всі обчислення в 80-бітовому розширеному форматі, а

32- і 64-бітові числа використовуються для обміну даними з основним

процесором і пам’яттю.

Окрім звичайних чисел, формат IEEE передбачає декілька спе-

ціальних випадків і над якими також можна виконувати деякі операції:

позитивний нуль: всі біти числа скинуті в нуль; негативний нуль: знаковий біт – 1, вся решта бітів – нулі; позитивна нескінченність: знаковий біт – 0, всі біти мантиси –

0, всі біти експоненти – 1; негативна нескінченність: знаковий біт – 1, всі біти мантиси – 0,

всі біти експоненти – 1; денормалізовані числа: всі біти експоненти – 0 (використову-

ються для роботи з дуже малими числами – до 10–16445 для розширеної

точності); невизначеність: знаковий біт – 1, перший біт мантиси (перші два

для 80-бітових чисел) – 1, а інші – 0, всі біти експоненти – 1; не– число типу SNAN (сигнальне): всі біти експоненти – 1, пер-

ший біт мантиси – 0 (для 80-бітових чисел перші два біти мантиси – 10),

а серед решти біт є одиниці; не– число типу QNAN (тихе): всі біти експоненти – 1, перший

біт мантиси (перші два для 80-бітових чисел) – 1, серед решти бітів є

одиниці. Невизначеність – один з варіантів QNAN; непідтримуване число: вся решта ситуацій.

Решта форматів даних FPU також допускає невизначеність – оди-

ниця в старшому біті і нулі в інших для цілих чисел, і старші 16 біт –

одиниці для упакованих десяткових чисел.

Page 137: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

137

4.8.2. Регістри FPU

FPU надає вісім регістрів для зберігання даних і п’ять допоміжних

регістрів.

Регістри даних (R0 – R7) не адресуються за іменами, як регістри ос-

новного процесора. Натомість ці вісім регістрів розглядаються як стек,

вершина якого називається ST, а глибші елементи – ST(1), ST(2) і так

далі – до ST(7). Якщо, наприклад, в якийсь момент часу регістр R5 нази-

вається ST (рис. 4.5), то після запису в цей стек числа його буде записано

в регістр R4, який стане називатися ST, R5 стане називатися ST(1) і т.д.

До регістрів R0 – R7 не можна звертатися безпосередньо, за імена-

ми, але якщо процесор підтримує розширення ММХ, то мантиси, що

знаходяться в цих регістрах, стають доступні як ММ0 – ММ7.

Регістр станів SR містить слово стану FPU:

біт 15: В – зайнятість FPU – цей прапорець існує для сумісності з

8087, і його значення завжди співпадає з ES;

біт 14: С3 – умовний прапорець 3;

біти 13 – 11: ТОР – число від 0 до 7, що показує, який з регістрів

даних R0 – R7 зараз є вершиною стека;

біт 10: С2 – умовний прапорець 2;

біт 9: С1 – умовний прапорець 1;

біт 8: С0 – умовний прапорець 0;

біт 7: ES – загальний прапорець помилки – дорівнює 1, якщо відбу-

лося хоча б одне немасковане виключення;

R0

R1

R2

R3

R4

R5

R6

R7

FIP

FDP

CR

SR

TW

Рис. 4.5. Регістри FPU

ST(3)

ST(2)

ST(5)

ST(6)

ST(7)

ST

ST(1)

ST(2)

TOP = 5

0 79

0 15

0 47

Page 138: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

138

біт 6: SF – помилка стека. Якщо С1 = 1, відбулося переповнювання

(команда намагалася писати в непорожню позицію в стеку); якщо С1 = 0,

відбулося антипереповнювання (команда намагалася рахувати число з

порожньої позиції в стеку);

біт 5: РЕ – прапорець неточного результату – результат не може бу-

ти представлений точно;

біт 4: UE – прапорець антипереповнювання – результат дуже незна-

чний;

біт 3: ОЕ – прапорець переповнювання – результат дуже великий;

біт 2: ZE – прапорець ділення на нуль – виконано ділення на нуль;

біт 1: DE – прапорець денормалізованого операнда – виконана опе-

рація над денормалізованим числом;

біт 0: IE – прапорець неприпустимої операції – відбулася помилка

стека (SF = 1) або виконана неприпустима операція.

Біти С0 – С3 відображають результат виконання попередньої ко-

манди і використовуються для умовних переходів; команди

fstsw ах

sahf

копіюють їх значення в регістр FLAGS так, що прапорець С0 перехо-

дить в CF, С2 – в PF, а С3 – в ZF (прапорець С2 втрачається).

Біти 0 – 5 відображають різні помилкові ситуації, які можуть вини-

кати при виконанні команд FPU. Вони розглянуті в описі керуючих ре-

гістрів.

Регістр керування CR:

біти 15 – 13 – зарезервовані;

біт 12: IC – керування нескінченністю (підтримується для суміснос-

ті з 8087 і 80287 – незалежно від значення цього біта + > – );

біти 11 – 10: RC – керування округленням;

біти 9 – 8: PC – керування точністю;

біти 7 – 6: зарезервовані;

біт 5: РМ – маска неточного результату;

біт 4: UM – маска антипереповнювання;

біт 3: ОМ – маска переповнювання;

біт 2: ZM – маска ділення на нуль;

біт 1: DM – маска денормалізованого операнда;

біт 0: IM – маска недійсної операції.

Page 139: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

139

Біти RC визначають спосіб округлення результатів команд FPU до

заданої точності (табл. 4.6).

Таблиця 4.6

Способи округлення

Значення RC Способи округлення

0 До найближчого числа

1 До негативної нескінченності

2 До позитивної нескінченності

3 До нуля

Біти PC визначають точність результатів команд FADD, FSUB,

FSUBR, FMUL, FDIV, FDIVR і FSQRT (табл. 4.7).

Таблиця 4.7

Точність результатів

Значення RC Способи округлення

0 Одинарна точність (32-бітові числа)

1 Зарезервовано

2 Подвійна точність (64-бітові числа)

3 Розширена точність (80-бітові числа)

Біти 0 – 5 регістра CR маскують відповідні виключення – якщо мас-

куючий біт встановлений, виключення не відбувається, а результат ко-

манди, що викликала його, визначається правилами для кожного виклю-

чення спеціально.

Регістр тегов TW містить 8 пар бітів, даних, що описують зміст ко-

жного регістра, – біти 15 – 14 описують регістр R7, 13 – 12 – R6 і т.д.

Якщо пара біт (тег) дорівнює 11, відповідний регістр – порожній. 00

означає, що регістр містить число, 01 – нуль, 10 – нечисло, нескінчен-

ність, денормалізоване число, непідтримуване число.

Регістри FIP і FDP містять адресу останньої виконаної команди (ок-

рім FINIT, FCLEX, FLDCW, FSTCW, FSTSW, FSTSWAX, FSTENV,

FLDENV, FSAVE, FRSTOR і FWAIT) і адресу її операнда відповідно і

використовуються в обробниках виключень для аналізу команди, що

викликала його.

Page 140: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

140

4.8.3. Виключення FPU

При виконанні команд FPU можуть виникати шість типів особливих

ситуацій, званих виключеннями. При виникненні виключення відповід-

ний прапорець у регістрі SR встановлюється в 1 і, якщо маска цього ви-

ключення в регістрі CR не встановлена, викликається звичайне перери-

вання INT 10h (якщо біт NE в регістрі центрального процесора CR0

встановлений в 1) або IRQ13 (INT 75h), обробник якого може прочитати

регістр SR, щоб визначити тип виключення (і FIP, і FDP) і команду, яка

його викликала, а потім спробувати виправити ситуацію. Якщо біт маски

виключення, що настало, в регістрі CR встановлений в 1, виконуються

наступні дії за умовчанням:

неточний результат: результат округляється відповідно до біт

RC (насправді це виключення відбувається дуже часто, наприклад дріб

1/6 не може бути подано точно десятковим дійсним числом будь-якої

точності і округляється). При цьому прапорець С1 показує, в який бік

відбулося округлення: 0 – вниз, 1 – вгору; антипереповнювання: результат дуже малий, щоб бути поданим

звичайним числом, – він перетвориться в денормалізоване число; переповнювання: результат перетвориться в нескінченність від-

повідного знака; ділення на нуль: результат перетвориться в нескінченність відпо-

відного знака (враховується і знак нуля);

денормалізований операнд: обчислення продовжується як зав-

жди; недійсна операція: результат визначається з табл. 4.8.

Таблиця 4.8

Результати операцій, що приводять до виключень

Операція Результат

Помилка стека Невизначеність

Операція з непідтримуваним числом Невизначеність

Операція з SNAN QNAN

Порівняння числа з NAN C0 = C2 = C3 = 1

Складання нескінченності з одним знаком або

віднімання – з різним знаками

Невизначеність

Page 141: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

141

Закінчення табл. 4.8

Множення нуля на нескінченність Невизначеність

Ділення нескінченності на нескінченність або

0/0

Невизначеність

Команди FPREM і FPREM1, якщо дільник – 0,

або ділене – нескінченність

Невизначеність

і C2 = 0

Тригонометрична операція над нескінченністю Невизначеність

і C2 = 0

Корінь або логарифм, якщо x < 0, log(x+1), якщо

x < – 1

Невизначеність

FBSTP, якщо регістр-джерело порожній, містить

NAN, нескінченність або перевищує 18 десят-

кових знаків

Десяткова неви-

значеність

FXCH, якщо один із операндів пустий Невизначеність

4.8.4. Команди пересилання даних FPU

FLD джерело Завантажити дійсне число в стек 8087

Команда FLD поміщає вміст джерела (32- , 640 або 80- бітова

змінна або ST(n)) і зменшує ТОР на 1. Команда FLD ST(0) робить копію

вершини стека.

FST приймач

FSTP приймач

Скопіювати дійсне число зі стека

Зчитати дійсне число зі стека

8087

8087

Копіює ST(0) в приймач (32- або 64- бітову змінну або порожній

ST(n) у разі FST; 32-, 64- або 80-бітову змінну або порожній ST(n) у разі

FSTP). Команда FSTP після цього виштовхує число зі стека (позначає

ST(0) як порожній і збільшує ТОР на один).

FILD джерело Завантажити ціле число в стек 8087

Команда FILD перетворює ціле число зі знаком з джерела (16-, 32-

або 64-бітова змінна) в дійсний формат, розташовує у вершині стека і

зменшує ТОР на 1.

FIST приймач

FISTP приймач

Скопіювати ціле число зі стека 8087

8087

Page 142: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

142

Перетворює число з вершини стека в ціле число зі знаком і записує

його в приймач (16- або 32- бітова змінна для FIST; 16-, 32- або

64- бітова змінна для FISTP). Команда FISTP після цього виштовхує чи-

сло зі стека (позначає ST(0) як порожній і збільшує ТОР на один). Спро-

ба запису дуже великого числа, нескінченності або нечисла приводить до

виключення “неприпустима операція” (і запису цілої невизначеності,

якщо IM = 1).

FBLD джерело Завантажити десяткове число в стек 8087

Перетворює BCD число з джерела (80-бітова змінна в пам’яті), роз-

ташовує у вершині стека і зменшує ТОР на 1.

FBSTP приймач Рахувати десяткове число зі стека 8087

Перетворює число з вершини стека в 80-бітове упаковане десяткове,

записує його в приймач (80-бітова змінна) і виштовхує це число зі стека

(позначає ST(0) як порожній і збільшує ТОР на один). Спроба запису

дуже великого числа, нескінченності або нечисла приводить до виклю-

чення “неприпустима операція” (і запису десяткової невизначеності, як-

що IM = 1).

FXCH приймач Поміняти місцями два регістри стека 8087

Команда FXCH виконує обмін місцями вмісту регістра ST(0) і

джерела (регістр ST(n)). Якщо операнд не вказаний, обмінюється вміст

ST(0) і ST(1).

FCMOVcc приймач, джерело Умовна пересилка даних Р6

Це набір команд, кожна з яких копіює вміст джерела (регістр ST(n))

в приймач (тільки ST(0)), якщо виконується відповідна умова. Реально

кожна умова відповідає тим або іншим значенням прапорців регістра

FLAGS, але після команд

fcom (або інші команди порівняння)

fstsw ах

sahf

у регістр FLAGS завантажуються прапорці С0, С1 і С3, і подальша ко-

манда з набору FCMOVcc набуває сенсу обробки результату поперед-

нього порівняння (табл. 4.9).

Page 143: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

143

Таблиця 4.9

Команди FCMOVcc

FCMOVE

FCMOVNE

FCMOVB

FCMOVBE

FCMOVNB

FCMOVNB

E

FCMOVU

FCMOVNU

ZF = 1

ZF = 0

CF = 1

CF = 1 і ZF = 1

CF = 0

CF = 0 і ZF = 0

PF = 1

PF = 0

Якщо дорівнює

Якщо не дорівнює

Якщо менше

Якщо менше або дорівнює

Якщо не менше

Якщо не менше або дорівнює

Якщо незрівнянні

Якщо порівнянні

4.8.5. Базова арифметика FPU

FADD приймач, джерело Складання дійсних чисел 8087

FADDP приймач, джерело Складання з виштовхуванням зі стека 8087

FIADD джерело Складання цілих чисел 8087

Команда FADD виконує складання джерела і приймача і поміщає

результат в приймач. Команда FADDP після цього виштовхує ST(0) зі

стека (позначає ST(0) як порожній і збільшує ТОР на один). Команди

складання можуть приймати наступні форми:

FADD джерело, коли джерелом є 32- або 64-бітова змінна, а

приймачем – ST(0); FADD ST(0), ST(n), FADD ST(n), ST(0), FADDP ST(n), ST(0), коли

джерело і приймач задані явно у вигляді регістрів FPU; FADD без операндів – еквівалентно FADD ST(0), ST(1); FADDP

без операндів – еквівалентно FADDP ST(1), ST(0); FIADD джерело, коли джерелом є 16- або 32-бітова змінна, що

містить ціле число, а приймачем – ST(0).

FSUB приймач, джерело Віднімання дійсних чисел 8087

FSUBP приймач, джерело Віднімання з виштовхуванням зі стека 8087

FISUB джерело Віднімання цілих чисел 8087

Виконує віднімання джерела з приймача і зберігає результат в

приймачі. Команда FSUBP після цього виштовхує ST(0) зі стека (позна-

чає ST(0) як порожній і збільшує ТОР на один). Команди віднімання

можуть приймати наступні форми:

Page 144: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

144

FSUB джерело, коли джерелом є 32- або 64-бітова змінна, що

містить дійсне число, а приймачем – ST(0); FSUB ST(0), ST(n), FSUB ST(n), ST(0), FSUBP ST(n), ST(0), коли

джерело і приймач задані явно у вигляді регістрів FPU; FSUB без операндів – еквівалентно FSUB ST(0), ST(1); FSUBP

без операндів – еквівалентно FSUBP ST(1), ST(0); FISUB джерело, коли джерелом є 16- або 32-бітова змінна, що

містить ціле число, а приймачем – ST(0).

Якщо один з операндів – нескінченність, то результат – нескінчен-

ність відповідного знака. Якщо обидва операнди – нескінченність одно-

го знака, то результат не визначений (відбувається виключення “непри-

пустима операція”).

FSUBR приймач, джерело Зворотне віднімання дійсних чисел 8087

FSUBRP приймач, джерело Зворотне віднімання з вштовхуванням 8087

FISUBR джерело Зворотне віднімання цілих чисел 8087

Ці команди еквівалентні FSUB/FSUBP/FISUB у всьому, крім того,

що вони виконують віднімання приймача з джерела, а не джерела з

приймача.

FMUL приймач, джерело

FMULP приймач, джерело

FIMUL джерело

Множення дійсних чисел

Множення з виштовхуванням із стека

Множення цілих чисел

8087

8087

8087

Виконує множення джерела і приймача і поміщає результат в прий-

мач. Команда FMULP після цього виштовхує ST(0) із стека (позначає

ST(0) як порожній і збільшує ТОР на один). Так само як і решта команд

базової арифметики, команди множення можуть приймати наступні фо-

рми:

– FMUL джерело, коли джерелом є 32- або 64-бітова змінна, а

приймачем – ST(0);

– FMUL ST(0), ST(n); FMUL ST(n), ST(0); FMULP ST(n), ST(0), коли

джерело і приймач задані явно у вигляді регістрів FPU;

– FMUL без операндів – еквівалентно FMUL ST(0), ST(1); FMULP

без операндів - еквівалентно FMULP ST(1), ST(0);

– FIMUL джерело, коли джерелом є 16- або 32-бітова змінна, що

містить ціле число, а приймачем – ST(0).

Page 145: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

145

FDIV приймач, джерело

FDIVP приймач, джерело

FIDIV джерело

Ділення дійсних чисел

Ділення з виштовхуванням зі стека

Ділення цілих чисел

8087

8087

8087

Виконує ділення приймача на джерело і зберігає результат у прий-

мачі. Команда FDIVP після цього виштовхує ST(0) зі стека (позначає

ST(0) як порожній і збільшує ТОР на один). Команди можуть приймати

наступні форми:

FDIV джерело, коли джерелом є 32- або 64-бітова змінна, що

містить дійсне число, а приймачем – ST(0); FDIV ST(0), ST(n); FDIV ST(n), ST(0); FDIVP ST(n), ST(0), коли

джерело і приймач задані явно у вигляді регістрів FPU; FDIV без операндів – еквівалентно FDIV ST(0), ST(1); FDIVP

без операндів – еквівалентно FDIVP ST(1),ST(0); FIDIV джерело, коли джерелом є 16- або 32-бітова змінна, що

містить ціле число, а приймачем – ST(0).

-яке чис-

ло) результат – нескінченність, при діленні нуля на нескінченність (так

само як і на будь-яке число) результат – нуль. При діленні на нуль нор-

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

рець ZM = 1, як результат записується нескінченність відповідного знака.

FDIVR приймач, джерело

FDIVRP приймач, джерело

FIDIVR джерело

Зворотне ділення дійсних чисел

Зворотне ділення з виштовхуванням

Зворотне ділення цілих чисел

8087

8087

8087

Ці команди еквівалентні FDIV/FDIVP/FIDIV у всьому, крім того,

що вони виконують ділення джерела на приймач, а неприймача на дже-

рело.

FPREM

FPREM1

Знайти частковий залишок від ділення

Знайти частковий залишок в стандарті IEEE

8087

80387

Ці команди виконують ділення ST(0) на ST(1) і поміщають залишок

від ділення в ST(0). Ділення здійснюється за допомогою послідовних

віднімань ST(1) з ST(0), але за один раз виконується не більше 64 таких

віднімань. Якщо ST(0) не став менший ST(1) за цей час, говорять, що в

ST(0) знаходиться частковий залишок від ділення. Якщо був одержаний

точний залишок, прапорець С2 скидається в 0, якщо частковий – вста-

новлюється в 1, тому можна повторювати цю команду до обнулення С2.

Якщо обчислення привело до точного залишку, три молодших біти част-

Page 146: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

146

ки (тобто числа потрібно віднімати) зберігаються в С0, С3, С1 (біти 2, 1,

0 відповідно). Наприклад, використовуючи FPREM1, можна зменшити

аргумент тангенса, обчисливши його залишок від ділення на /4, тоді

буде потрібно молодші три біти частки, щоб визначити, чи не помінявся

при цій операції знак тангенса.

Відмінність між FPREM і FPREM1 полягає в різному визначенні

значення частки. Спочатку ці команди виконують дійсне ділення ST(0)

на ST(1), округляють результат (FPREM1 – до найближчого цілого,

FPREM – до нуля), а потім, якщо частинне 64, обчислюють точний за-

лишок, а якщо більше – частковий.

FABS Знайти абсолютне значення 8087

Якщо ST(0) був негативним числом, – переводить його в позитивне.

FCHS Змінити знак 8087

Змінює знак ST(0), перетворюючи позитивне число на негативне, і

навпаки.

FRNDINT Округляти до цілого 8087

Округляє значення ST(0) до цілого числа відповідно до режиму

округлення, заданого бітами RC.

FSCALE Масштабувати по ступенях двійки 8087

Помножує ST(0) на два в ступені ST(1) і записує результат в ST(0).

Значення ST(1) заздалегідь округляється у бік нуля до цілого числа. Ця

команда виконує дію, зворотну FXTRACT.

FXTRACT Добути експоненту і мантису 8087

Розділяє число в ST(0) на мантису і експоненту, зберігає експоненту

в ST(0) і поміщає мантису в стек, тому після цього ТОР зменшується на

1, мантиса опиняється в ST(0), а експонента – в ST(1).

FSQRT Добути квадратний корінь 8087

Обчислює квадратний корінь з ST(0) і зберігає результат в ST(0).

4.8.6. Команди порівняння FPU

FCOM джерело

FCOMP джерело

Порівняти дійсні числа

Порівняти і виштовхнути зі стека

8087

8087

Page 147: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

147

FCOMPP джерело Порівняти і виштовхнути зі стека два числа 8087

Команди виконують порівняння вмісту регістра ST(0) з джерелом

(32- або 64- бітова змінна або регістр ST(n), якщо операнд не вказаний –

ST(1)) і встановлюють прапорці С0, С2 і С3 відповідно до табл. 4.10.

Таблиця 4.10

Прапорці порівняння FPU

Умова C3 C2 C0 ST(0) > джерело 0 0 0

ST(0) < джерело 0 0 1

ST(0) = джерело 1 0 0

Непорівнянні 1 1 1

Якщо один з операндів – нечисло або непідтримуване число, відбу-

вається виключення “неприпустима операція”, а якщо воно замасковане

(прапорець IM = 1), всі три прапорці встановлюються в 1. Після команд

порівняння за допомогою команд FSTSW і SAHF можна перевести пра-

порці С3, С2 і С0 відповідно ZF, PF і CF, після чого всі умовні команди

(Jcc, CMOVcc, FCMOVcc, SETcc) можуть використовувати результат

порівняння як після команди СМР.

Команда FCOMP після виконання порівняння виштовхує зі стека

вміст ST(0) (позначає його як порожній і збільшує ТОР на 1), а команда

FCOMPP виштовхує зі стека і ST(0), і ST(1).

FUCOM джерело Порівняти дійсні числа без урахування

порядків

80387

FUCOMP джерело Порівняти без урахування порядків і ви-

штовхнути зі стека

80387

FUCOMPP джерело Порівняти без урахування порядків і ви-

штовхнути зі стека два числа

80387

Ці команди аналогічні FCOM/FCOMP/FCOMPP в усьому, крім того,

що в ролі джерела можуть виступати тільки регістри ST(n), і якщо один з

операндів – QNAN (“тихе” нечисло), прапорці С3, С2, С0 встановлю-

ються в 1, але виключення “неприпустима операція” не викликається.

Якщо один з операндів – SNAN або непідтримуване число, ці команди

поводяться так само, як і звичайне порівняння.

FICOM джерело Порівняти цілі числа 8087

Page 148: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

148

FICOMP джерело Порівняти цілі і виштовхнути зі стека 8087

Ці команди порівнюють вміст регістра ST(0) і джерела (16- або 32-

бітова змінна), причому вважається, що джерело містить ціле число. В

іншому дія FICOM/FICOMP повністю еквівалентна FCOM/FCOMP.

FCOMI джерело Порівняти і встановити EFLAGS P6

FCOMIP джерело Порівняти, встановити EFLAGS і виштовхну-

ти

P6

FUCOMI джерело Порівняти без урахування порядків і встано-

вити EFLAGS

P6

FUCOMIP джерело Порівняти без урахування порядків, встано-

вити EFLAGS і виштовхнути із стека

P6

Виконує порівняння регістра ST(0) і джерела (регістр ST(n)) і вста-

новлює прапорці регістра EFLAGS відповідно табл. 4.11.

Таблиця 4.11

Прапорці після команд FCOMI

Умови ZF PF CF

ST(0) > джерело 0 0 0

ST(0) < джерело 0 0 1

ST(0) = джерело 1 0 0

Не порівнянні 1 1 1

Ці команди еквівалентні командам FCOM/FCOMP/FUCOM

/FUCOMP, услід за якими виконуються FSMSW АХ і SAHF, але вони не

змінюють вмісту регістра АХ і виконуються швидше.

FTST Перевірити, чи не містить SP(0) нуль 8087

Порівнює вміст ST(0) з нулем і виставляє прапорці С3, С2 і С0 ана-

логічно іншим командам порівняння.

FXAM Проаналізувати вміст ST(0) 8087

Встановлює прапорці С3, С2 і С0 залежно від типу числа, що знахо-

диться в ST(0), відповідно до правил, наведених у табл. 4.12.

Page 149: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

149

Таблиця 4.12

Результати дії команди FXAM

Тип числа C3 C2 C0 Непідтримуване 0 0 0

Нечисло 0 0 1

Нормальне кінцеве число 0 1 0

Нескінченність 0 1 1

Нуль 1 0 0

Регістр порожній 1 0 1

Денормалізоване число 1 1 0

Прапорець С1 встановлюється рівним знаку числа в ST(0) незалеж-

но від типу числа (насправді він встановлюється, навіть якщо регістр

позначений як порожній).

4.8.7. Трансцендентні операції FPU

FSIN Синус 80387

Обчислює синус числа, що знаходиться в ST(0), і зберігає результат

в цьому ж регістрі. Операнд вважається заданим в радіанах і не може

бути більше 263 або менше – 263 (можна скористатися FPREM з дільни-

ком 2, якщо операнд дуже великий). Якщо операнд виходить за ці межі,

прапорець С2 встановлюється в 1 і значення ST(0) не змінюється.

FCOS Косинус 80387

Обчислює косинус числа, що знаходиться в ST(0), і зберігає резуль-

тат в цьому ж регістрі. Операнд вважається заданим в радіанах і не може

бути більше 263 або менше – 263 (так само, як і у разі синуса, можна

скористатися FPREM з дільником 2, якщо операнд дуже великий). Якщо

операнд виходить за ці межі, прапорець С2 встановлюється в 1 і значен-

ня ST(0) не змінюється.

FSINCOS Синус і косинус 80387

Обчислює синус і косинус числа, що знаходиться в ST(0), поміщає

синус в ST(0) і потім косинус – в стек (отже, синус опиняється в ST(1),

косинус – в ST(0), і ТОР зменшується на 1). Операнд вважається зада-

ним в радіанах і не може бути більше 263 або менше – 263. Якщо опе-

Page 150: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

150

ранд виходить за ці межі, прапорець С2 встановлюється в 1, і значення

ST(0) і стек не змінюються.

FPTAN Тангенс 8087

Обчислює тангенс числа, що знаходиться в регістрі ST(0), замінює

його на обчислене значення і потім поміщає 1 в стек так, що результат

опиняється в ST(1), ST(0) містить 1, а ТОР зменшується на одиницю. Як

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

радіанах і не може бути більше 263 або менше – 263. Якщо операнд ви-

ходить за ці межі, прапорець С2 встановлюється в 1 і значення ST(0) і

стек не змінюються. Одиниця поміщається в стек для того, щоб можна

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

FPTAN.

FPATAN Арктангенс 8087

Обчислює арктангенс числа, що одержують при діленні ST(1) на

ST(0), зберігає результат в ST(1) і виштовхує ST(0) зі стека (позначає

ST(0) як порожній і збільшує TOP на 1). Результат завжди має той же

знак, що і ST(1), і менше за абсолютною величиною. Сенс цієї операції в

тому, що FPATAN обчислює кут між віссю абсцис і лінією, проведеною

з центру координат в точку ST(1), ST(0).

FPATAN може виконуватися над будь-якими операндами (окрім

нечисел), даючи результати для різних нулів і нескінченності, визначені

відповідно до стандарту IEEE (як показано в табл. 4.13).

Таблиця 4.13

Результати роботи команди FPATAN1

– – F – 0 + 0 + F +

– – 3/4 – /2 – /2 – /2 – /2 – /4

– F – Від – до

– /2

– /2 – /2 Від – /2

до – 0

– 0

– 0 – – – – 0 – 0

+ 0 + + + 0 + 0

+ F + + /2 + /2 + 0

+ + 3/4 + /2 + /2 + /2 + /2 + /4

ST(0) ST(1)

Page 151: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

151

F2XMI Обчислення 2х – 1 8087

Підносить 2 до ступеня, що дорівнює ST(0), і віднімає 1. Результат

зберігається в ST(0). Значення ST(0) повинне лежати в межах від – 1 до

+1, інакше результат не визначений.

FYL2X Обчислення у log2(x) 8087

Обчислює ST(1) log2(ST(0)), поміщає результат в ST(1) і виштов-

хує ST(0) зі стека так, що після цієї операції результат опиняється в

ST(0). Первинне значення ST(0) повинне бути позитивним. Якщо регістр

ST(0) містив нуль, результат (якщо ZM = 1) буде рівний нескінченності

із знаком, зворотним ST(1).

FYL2XP1 Обчислення у log2(x+1) 8087

Обчислює ST(1) log2(ST(0)+1), поміщає результат в ST(1) і ви-

штовхує ST(0) зі стека так, що після цієї операції результат опиняється в

ST(0). Первинне значення ST(0) повинне бути в межах від – (1 – 2/2) до

(1 + 2/2), інакше результат не визначений. Команда FYL2XP1 дає вели-

ку точність для ST(0), що ближче до нуля, ніж FYL2X для суми того ж

ST(0) і 1.

4.8.8. Константи FPU

FLD1

FLDZ

FLDPI

FLDL2E

FLDL2T

FLDLN2

FLDLG2

Помістити в стек 1,0

Помістити в стек +0,0

Помістити в стек число

Помістити в стек log2(e)

Помістити в стек log2(10)

Помістити в стек ln(2)

Помістити в стек lg(2)

8087

8087

8087

8087

8087

8087

8087

Всі ці команди поміщають у стек (тобто зменшують ТОР на один і

поміщають в ST(0)) відповідну часто використовувану константу. Почи-

наючи зі співпроцесора 80387, всі константи зберігаються у форматі,

точнішому ніж 80-бітовий формат, використовуваний в регістрах даних,

і при завантаженні в стек відбувається округлювання відповідно до поля

RC.

Page 152: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

152

4.8.9. Команди керування FPU

FINCSTP Збільшити покажчик вершини стека 8087

Поле ТОР регістра стану FPU збільшується на 1. Якщо ТОР дорів-

нюється семи, воно заповняється нулями. Ця команда не еквівалентна

виштовхуванню ST(0) зі стека тому, що регістр даних, який називався

ST(0) і став ST(7), не позначається як порожній.

FDECSTP Зменшити покажчик вершини стека 8087

Поле ТОР регістра стану FPU зменшується на 1. Якщо ТОР дорів-

нювалое нулю, воно встановлюється в 7. Вміст регістрів даних і TW не

змінюється.

FFREE операнд Звільнити регістр даних 8087

Команда відзначає в регістрі TW, що операнд (регістр даних ST(n))

– порожній. Вміст регістра і ТОР не змінюються.

FINIT

FNINIT

Ініціалізувати FPU

Ініціалізувати FPU без очікування

8087

8087

Команди FINIT і FNINIT відновлюють значення за умовчанням в

регістрах CR, SR, TW, а починаючи з 80387 – FIP і FDP регістр, що

управляє, ініціалізувався значенням 037Fh (округлення до найближчого,

64-бітова точність, всі виключення замасковані). Регістр стану заповню-

ється нулями (ТОР = 0, ніякі прапорці виключень не встановлені). Регіс-

три даних ніяк не змінюються, але всі вони визначаються порожніми в

регістрі TW. Регістри FIP і FDP наповнюються нулями. Команда FINIT,

на відміну від FNINIT, перевіряє наявність виключень, що відбулися, і

необроблених і обробляє їх до ініціалізації. Команда FINIT повністю

еквівалентна (і насправді є) WAIT FNINIT.

FCLEX

FNCLEX

Заповнити нулями прапорці виключень

Заповнити нулями прапорці виключень без очікування

8087

Page 153: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

153

Команди заповнюють нулями прапорці виключень (РЕ, UE, OF, ZE,

DE, IE), а також прапорці ES, SF і В в регістрі стану FPU. Команда

FCLEX, на відміну від FNCLEX, перевіряє наявність виключень, що від-

булися, і необроблених і обробляє їх до виконання.

FSTCW приймач

FNSTCW приймач

Зберегти регістр CR

Зберегти регістр CR без очікування

8087

8087

Команди копіюють вміст CR в приймач (16-бітова змінна). Команда

FSTCW, на відміну від FNSTCW, перевіряє наявність виключень, що

відбулися, і необроблені та їх обробляє. Команда FSTCW повністю екві-

валентна WAIT FNSTCW.

FLDCW джерело Завантажити регістр CR 8087

Копіює вміст джерела (16-бітова змінна) в регістр CR. Якщо один

або декілька прапорців виключень встановлені в регістрі SR і замаскова-

ні в CR, а команда FLDCW ці маски видалила, виключення будуть обро-

блені перед початком виконання наступної команди FPU (окрім команд

без очікування). Щоб цього не відбувалося, звичайно перед FLDCW ви-

конують команду FCLEX.

FSTENV приймач

FNSTENV приймач

Зберегти допоміжні регістри

Зберегти допоміжні регістри без очікування

8087

8087

Зберігає всі допоміжні регістри FPU в приймачі (14 або 28 байт в

пам’яті, залежно від розрядності операндів) і маскує всі виключення.

Зберігає вміст регістрів CR, SR, TW, FIP, FDP і останню команду у фор-

маті, залежному від поточної розрядності операндів і адресу (7 подвій-

них слів для 32-бітових операндів і 7 слів для 16-бітових операндів). Пе-

рше слово (або молодша половина першого подвійного слова в 32-

бітовому випадку) завжди містить CR, друге слово – SR, третє слово –

TW, четверте – FIP.

З коду останньої виконаної FPU-команди зберігаються перші два

байти без префіксів і без перших п’яти бітів, які однакові для всіх ко-

манд FPU, тобто всього 11 біт. Команда FSTENV, на відміну від

FNSTENV, перевіряє наявність виключень, що відбулися, і необробле-

Page 154: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

154

них і обробляє їх до виконання. Команда FSTENV повністю еквівалент-

на WAIT FNSTENV.

FLDENV джерело Завантажити допоміжні регістри 8087

Команда завантажує всі допоміжні регістри FPU (регістри CR, SR,

TW, FIP, FDP) з джерела (область пам’яті в 14 або 28 байт залежно від

розрядності операндів), збережені раніше командою FSTENV/

/FNSTENV. Якщо в завантажуваному SW встановлені декілька (або

один) прапорців виключень, які одночасно не замасковані прапорцями

CR, ці виключення будуть виконані перед наступною командою FPU

(окрім команд без очікування).

FSAVE приймач

FNSAVE приймач

Зберегти стан FPU

Зберегти стан FPU без очікування

8087

8087

Зберігає стан FPU (регістри даних і допоміжні регістри) в приймач

(область пам’яті розміром 94 або 108 байт залежно від розрядності опе-

рандів) і ініціалізував FPU аналогічно командам FINIT/FNINIT. Команда

FSAVE, на відміну від FNSAVE, перевіряє наявність виключень, що від-

булися, і необроблених і обробляє їх до виконання. Команда FSAVE по-

вністю еквівалентна (і насправді є) WAIT FNSAVE. Ця команда звичай-

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

або програмами, які повинні передавати процедурам, що викликаються,

чистий FPU.

FXSAVE приймач Швидке збереження стану FPU PII

Команда FXSAVE зберігає весь поточний стан FPU, включаючи всі

регістри в приймач (512-байтную область пам’яті з адресою, кратною

16), не перевіряючи на необроблені виключення, аналогічно команді

FNSAVE. Крім того, на відміну від FSAVE/FNSAVE, ця команда не пе-

реініціалізує FPU після збереження стану. Ця команда несумісна з

FSAVE/FRSTOR.

FRSTOR джерело Відновити стан FPU 8087

Page 155: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

155

Команда FRSTOR завантажує стан FPU (допоміжні регістри і регі-

стри даних) з джерела (область в пам’яті розміром 94 або 108 байт зале-

жно від розрядності операндів).

FXRSTOR джерело Швидке відновлення стану FPU PII

Команда FXRSTOR відновлює весь поточний стан FPU, включаю-

чи всі регістри з джерела (512-байтової області пам’яті з адресою, крат-

ною 16), яке було заповнене командою FXSAVE.

FSTSW приймач

FNSTSW приймач

Зберегти регістр SR

Зберегти регістр SR без очікування

80287

80287

Зберігає поточне значення регістра SR в приймач (регістр АХ або

16-бітова змінна). Команда FSTSW АХ звичайно використовується після

команд порівняння і FPREM/FPREM1/FXAM, щоб виконувати умовні

переходи.

WAIT

FWAIT

Очікування готовності FPU 8087

Процесор перевіряє, чи присутні необроблені і немасковані виклю-

чення FPU, і обробляє їх. Цю команду можна вказувати в критичних си-

туаціях після команд FPU, щоб переконатися, що можливі виключення

будуть оброблені. WAIT і FWAIT – різні назви для однієї і тієї ж коман-

ди.

FNOP Відсутність операції 8087

Команда FNOP займає місце і час, але не виконує ніякої дії. Заста-

рілі команди FPU – FENI (вирішити виключення, 8087), FDISI (заборо-

нити виключення, 8087) і FSETPM (80287) виконуються як FNOP – всі-

ма більш старшими процесорами.

Page 156: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

156

5. ДИРЕКТИВИ І ОПЕРАНДИ АСЕМБЛЕРУ

5.1. Директиви асемблеру

Директиви призначені для керування процесом асемблювання і фо-

рмування лістингу. Вони діють тільки в процесі асемблювання програми

і не переводяться в машинні коди. Мова асемблеру містить такі основні

директиви:

початку і кінця сегмента SEGMENT та ENDS;

початку і кінця процедури PROC та ENDP;

визначення пам’яті та призначення сегментів ASSUME;

початку ORG;

визначення даних DB, DW, DD, DQ, DT;

символьних констант: = , EQU, TEXTEQU;

завершення програми END;

відзначення LABEL.

Директиви початку і кінця сегмента SEGMENT та ENDS при-

значені для опису сегментів, які використовує програма. Директиви по-

чатку і кінця сегмента використовуються разом. Наприклад:

Назва Мнемокод Операнд

DATASG SEGMENT {<параметри>}

. . . ; Інші команди або директиви сегмента

DATASG ENDS

Обидві директиви SEGMENT і ENDS повинні мати однакові назви.

Директива SEGMENT може містити три типи параметрів:

вирівнювання;

об’єднання;

класу.

Параметр вирівнювання визначає початкову адресу або межу сегме-

нта, наприклад:

BYTE = ххххх (з різної адреси),

WORD = xxxxe (парна межа – з парної адреси),

Page 157: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

157

DWORD = xxxxe (парна межа – з адреси, кратної 4),

PARA = xxxx0 (межа за замовчуванням – з адреси, кратної 16),

PAGE = xxx00 (з адреси, кратної 256),

де х – будь-яка шістнадцяткова цифра; е – парна шістнадцяткова цифра.

Якщо немає параметра вирівнювання за замовчуванням, береться пара-

метр PARA, який вказує на те, що сегмент розташовується на початку

параграфа, а початкова адреса сегмента є кратною 16. Параграфом на-

зивається область пам’яті розміром 16 байт, початкова адреса якої крат-

на 16, тобто має праворуч чотири нульових розряди.

Параметр об’єднання вказує на спосіб обробки сегмента при ком-

понуванні декількох програмних модулів:

NONE: значення за замовчуванням. Сегмент має бути логічно відо-

кремленим від інших сегментів, хоча фізично він може розташовуватися

поряд. Передбачається, що сегмент має власну базову адресу;

PUBLIC: усі PUBLIC – сегменти з однаковими назвою та класом

завантажуються у суміжні області і мають одну базову адресу;

STACK: призначення аналогічне параметру PUBLIC. У будь-якій

програмі має бути визначений принаймні один сегмент STACK. Якщо

визначено більше одного стека, то вказівник стека SP (Stack Pointer)

встановлюється на початок першого стека;

COMMON: для сегментів COMMON з однаковими назвами та кла-

сами встановлюється одна спільна базова адреса. Під час виконання

програми здійснюється накладання другого сегмента на перший. Розмір

загальної області визначається найдовшим сегментом;

АТ – параграф, слід визначати заздалегідь. Цей параметр забезпечує

визначення міток та змінних за фіксованими адресами у фіксованих обла-

стях пам’яті;

‘Клас’: цей параметр може мати будь-яку правильну назву, яка роз-

міщується в одинарних лапках. Параметр використовується для обробки

сегментів, які мають однакові назви та класи. Типовими є класи

‘STACK’ та ‘CODE’, наприклад:

Назва Мнемокод Операнд

STACKSG SEGMENT PARA STACK ‘STACK’

У випадку, якщо програма не повинна об’єднуватися з іншими про-

грамами, параметр об’єднання не вказується.

Директиви початку і кінця процедури PROC та ENDP використо-

вуються для визначення підпрограм у сегменті кодів і мають такий фор-

мат:

Page 158: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

158

<Назва> PROC {<тип процедури>}.

Можливі два типи процедур:

– NEAR – процедура знаходиться в тому самому сегменті, що і

команди, які її викликають;

– FAR – процедура знаходиться за межами сегмента.

За замовчуванням береться тип процедури NEAR.

Сегмент кодів може містити декілька процедур. Описання сегмента

кодів, що містить тільки одну процедуру, має такий вигляд:

Назва Мнемокод Операнд

Ім’я сегмента SEGMENT PARA

Ім’я_процедури PROC FAR

RET

Ім’я_процедури ENDP

Ім’я сегмента ENDS

Ім’я процедури має бути обов’язково і збігатися з іменем у директиві

ENDP, яка визначає кінець процедури.

Директива призначення сегментів ASSUME використовується для

встановлення відповідності між сегментами та сегментними регістрами і

має такий формат:

ASSUME <сегментний регістр>:<ім’я>{,}{...}.

Наприклад, запис SS:ім_стек вказує, що ім’я стека визначається вміс-

том регістра SS. Одна директива ASSUME може призначати до чотирьох

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

Мнемокод Операнд(и)

ASSUME SS-ім_стек, DS-ім_дані, СS: ім_код, ES:ім._додаткові

дані

Для скасування будь-якого призначеного раніше в директиві

ASSUME сегментного регістра треба використовувати слово NOTHING:

Мнемокод Операнд(и)

ASSUME ES: NOTHING.

Якщо програма не використовує якийсь сегмент, то відповідний

йому операнд можна відпустити або вказати слово NOTHING.

За допомогою директиви .MODEL можна вибрати одну із стандар-

тних моделей пам’яті для програм на мові асемблеру. Модель пам’яті

(memory model) визначає, яким чином треба комбінувати використовува-

ні сегменти. Кожна модель має свої обмеження за максимальним розмі-

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

Page 159: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

159

гнучкістю і розмірами програми. Модель пам’яті, яка обмежує розміри

всіх даних одним сегментом в 64 Кбайт, гарантує, що всі виклики будуть

тільки ближніми (near), і відповідно, буде потрібно тільки 16-розрядні

значення. Таким чином, доступ до даних буде швидшим, оскільки 16-

розрядна адреса може бути завантажена значно швидше, ніж 32-

розрядна адреса “сегмент-зсув”. Також і модель пам’яті, яка розміщує

підпрограми в різних сегментах, вимагає для їх виклику використання

двох регістрів: CS і в IР. Для різних моделей пам’яті потрібне різне число байтів для команд

і даних. Наприклад, коли довжина сегмента коду обмежена об’ємом в

64 Кбайт, то немає необхідності в командах використовувати великі чис-

ла.

Моделі пам’яті задаються директивою .MODEL .model модель, мова, модифікатор

де модель – одне з наступних слів: tiny – коди і дані разом повинні займати не більше 64 Кбайт; small – code ≤ 64 Кбайт, data ≤ 64 Кбайт. Один сегмент коду, один

сегмент даних; medium – data ≤ 64 Кбайт, код будь-якого розміру. Багато сегментів

коду, один сегмент даних; compact – code ≤ 64 Кбайт, дані будь-якого розміру. Один сегмент

коду, багато сегментів даних; large – code > 64 Кбайт, data > 64 Кбайт. Багато сегментів коду і

даних; Huge – то же саме, що і модель large, за винятком того, що окремі

змінні, такі як масив, можуть бути більше 64 Кбайт; flat – немає сегментів. 32-розрядна адресація використовується як

для коду, так і для даних. Тільки захищений режим. При використанні всіх моделей пам’яті, окрім tiny, створюються

виконувані програми типу .ехе. При використанні моделі пам’яті tiny

створюються програми .com. Всі моделі, виключаючи flat, розраховані

на використання в реальному режимі процесора. Модель flat може вико-

ристовуватися тільки для роботи в захищеному режимі. Наприклад,

Windows NT працює в захищеному режимі. Компілятор Microsoft Visual

C++ використовує для створення консольних додатків Windows 95 плос-

ку (flat) модель пам’яті.

Мова – необов’язковий операнд, що приймає значення C, PASCAL,

BASIC, FORTRAN, SYSCALL і STDCALL. Якщо він вказаний, мається

Page 160: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

160

на увазі, що процедури розраховані на виклик з програм на відповідній

мові високого рівня, отже, якщо вказана мова C, всі імена асемблерних

процедур, оголошених як PUBLIC, будуть змінені так, щоб починатися з

символу підкреслення, як це прийнято в C.

Модифікатор – необов’язковий операнд, що приймає значення

NEARSTACK (за умовчанням) або FARSTACK. У другому випадку сег-

мент стека не об’єднуватиметься в одну групу з сегментами даних.

Після того, як модель пам’яті встановлена, набувають чинності

спрощені директиви визначення сегментів, об’єднуючі дії директив

SEGMENT і ASSUME. Крім того, сегменти, оголошені спрощеними ди-

рективами, не потрібно закривати директивою ENDS – вони закривають-

ся автоматично, як тільки асемблер виявляє нову директиву визначення

сегмента або кінець програми.

Директива .CODE описує основний сегмент коду

.code ім’я_сегмента

еквівалентно

_TEXT segment word public ‘CODE’ для моделей TINY, SMALL і COMPACT і

name_TEXT segment word public ‘CODE’ для моделей MEDIUM, HUGE і LARGE (name – ім’я модуля, в якому

описаний даний сегмент). У цих моделях директива .CODE також допус-

кає необов’язковий операнд – ім’я визначуваного сегмента, але всі сег-

менти коду, описані так в одному і тому ж модулі, об’єднуються в один

сегмент з ім’ям NAME_TEXT. STACK розмір – директива .STACK описує сегмент стека і еквіва-

лентна директиві STACK segment para public ‘stack’

Необов’язковий параметр указує розмір стека. За умовчанням він

дорівнює 1 Кбайт.

.DATA – описує звичайний сегмент даних і відповідає директиві

_DATA segment word public ‘DATA’

.DATA –описує звичайний сегмент даних і відповідає директиві

_DATA segment word public ‘DATA’

.DATA? – описує сегмент неініціалізованих даних:

_BSS segment word public ‘BSS’

Цей сегмент звичайно не включається в програму, а розташовується

за кінцем пам’яті, тому всі описані в ньому змінні на момент заванта-

ження програми мають невизначені значення.

Page 161: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

161

.CONST – описує сегмент незмінних даних:

CONST segment word public ‘CONST’

У деяких операційних системах цей сегмент буде завантажений так,

що спроба запису в нього може призвести до помилки.

.fardata ім’я_сегмента – сегмент далеких даних:

ім’я_сегмента segment para private ‘FARDATA’

Доступ до даних, описаних в цьому сегменті, зажадає завантаження

сегментного регістра. Якщо операнд не вказаний, то як ім’я сегмента

використовується FARDATA.

.FARDATA? ім’я_сегмента – сегмент далеких неініціалізованих да-

них:

ім’я_сегмента segment para private ‘FARBSS’ Як і у випадку з FARDATA, доступ до даних з цього сегмента зажа-

дає завантаження сегментного регістра. Якщо ім’я сегмента не вказане,

використовується FAR_BSS.

У всіх моделях пам’яті сегменти, подані директивами .DATA,

.DATA?, .CONST, .FARDATA і .FARDATA?, а також сегмент, описаний

директивою .STACK, якщо не був вказаний модифікатор FARSTACK, і

сегмент .CODE у моделі TINY автоматично об’єднуються в групу з

ім’ям FLAT – для моделі пам’яті FLAT або DGROUP – для всієї решти

моделей. При цьому сегментний регістр DS (і SS, якщо не було

FARSTACK, і CS в моделі TINY) настроюється на всю цю групу, начеб-

то була виконана команда ASSUME. Директива ORG використовується для зміни вмісту програмного

лічильника без команд умовного чи безумовного переходу. Найчастіше цю

директиву використовують для встановлення початкової адреси програми.

Наприклад, директива ORG 100H встановлює програмний лічильник на

зміщення 100Н відносно початку сегмента кодів. Операнд зі знаком дола-

ра "$" має поточне значення програмного лічильника. Наприклад, дире-

ктива

ORG $ + 10h

збільшує адресу, завантажену в програмний лічильник, на 10h.

Директиви визначення даних використовуються для визначення

вмісту та резервування комірок пам’яті.

Директива має формат

[ <ім’я> ] Dn [кількість повторень ] <вираз>,

Page 162: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

162

де мнемокод Dn =

вказує на довжину даних: DB – байт; DW – слово (два байти); DD –

подвійне слово; DQ – чотири слова; DT – десять байтів. Якщо у форматі

наявне ім’я, то далі в програмі воно може використовуватися для позна-

чення комірки пам’яті.

<Вираз> у форматі директиви містить одну або кілька констант для

задання початкових значень вмісту комірок пам’яті або знак “?” – для

невизначеного значення вмісту. Наприклад, директива

ALPHA DB 34

означає, що комірка пам’яті з іменем ALPHA містить число 34. У ході

виконання програми вміст комірки може бути змінений. Директива

BETA DW?

визначає, що комірка з іменем BETA має розрядність 16, але вміст ко-

мірки є невизначеним. Директива може містити декілька констант, роз-

ділених комами і обмежених лише довжиною рядка. Наприклад, вираз

ARRAY DB 01, 02, 11, 12, 21, 22

визначає 6 констант у вигляді послідовності суміжних байтів.

Посилання на комірку з іменем ARRAY вказує на першу константу

(01), з іменем ARRAY + 1 – на другу (02), з іменем ARRAY + 2 – на третю

(11) і т.д. Запис MOV AL, ARRA + 4 завантажує у регістр AL значення

21.

Одна директива може визначити декілька комірок пам’яті. У цьому

разі директива має вигляд

{ <ім’я> } Dn {кількість повторень} DUP <вираз>

Наприклад, директива, що визначає 5 байт, які містять число 21, за-

писується таким чином:

DB 5 DUP(2l)

Директиви символьних констант: = , EQU, TEXTEQU

Директива знака рівності створює константу, присвоюючи імені чи-

слове значення ім’я = вираз На відміну від директив DB і DW, директива знака рівності не роз-

поділяє пам’ять. Під час трансляції програми всі відповідні імена будуть

замінені виразами. В результаті обчислення виразу повинне вийти 32-

DB

DW

DD

DQ

DT

Page 163: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

163

розрядне число зі знаком або без нього (для процесорів 386 і більш ста-

рших моделей), як показано в прикладі: prod = 10 * 5 ; обчислення виразу maxlnt = 7FFFh ; макс. значення 16-розрядного числа зі знаком minlnt = 80000h ; мінімальне значення 16-розрядного числа зі знаком maxUInt = 0FFFFh ; макс. значення 16-розрядного числа без знака.

Директива EQU присвоює символічне ім’я рядку символів або ци-

фровій константі. Це полегшує читання програм і дозволяє змінити чис-

ленні входження констант в одному місці. Але є одне важливе обмежен-

ня директиви EQU: визначене один раз ім’я не можна перевизначити. Вирази, що включають цілочисельні значення визначають цифрову

константу, але вирази з дійсними числами інтерпретуються як рядок си-

мволів. Рядки символів можуть бути поміщені в кутові дужки (<...>) для

підтвердження того, що це рядок символів. Це виключає неоднознач-

ність при визначенні імен: Приклад Тип значення maxint equ 32767 ; Цифровий maxuint equ 0FFFFh ; Цифровий coun equ 10 * 20 ; Цифровий floatl equ <2,345> ; Рядок символів За допомогою директиви TEXTEQU можна присвоїти рядку симво-

лів ім’я і потім використовувати рядок під цим ім’ям. Синтаксис прис-

воювання: ім’я TEXTEQU <текст> ім’я TEXTEQU макроозначення тексту ім’я TEXTEQU % константний вираз В даному випадку текст (text) представляє послідовність будь-яких

символів, поміщених у кутові дужки. Макроозначення тексту представ-

ляє заздалегідь певний текст, а константний вираз перетворюється в

текст. Макроозначення тексту можуть створюватися в будь-якому місці

програми, а ім’я, визначене за допомогою TEXTEQU, може бути пізніше

перевизначено. Символічне ім’я може бути присвоєне рядку символів і надалі зав-

жди замінюватиметься рядком символів. Наприклад, змінна promptl ви-

значає макроозначення тексту continueMsg: continueMsg textequ <"Do you wish to continue (Y/N)?"> .data promptl db continueMsg

Page 164: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

164

Директива завершення програми END є останньою у програмі і

має такий формат:

END {<стартова адреса>}.

Параметр директиви <стартова адреса> використовується лише при

створенні EXE-файлів.

Директива відзначення LABEL призначена для встановлення від-

повідності між іменем і типом змінних. Вона має такий формат:

<ім’я> LABEL {<тип>}.

Як тип можна використовувати слова BYTE, WORD, DWORD, що ви-

значають довжину даних: байт, слово або подвійне слово. Дирек-

тива LABEL перевизначає параметри процедур NEAR або FAR. Напри-

клад, директива

TOS LABEL WORD

присвоює комірці пам’яті ім’я TOS і зазначає, що її вміст є словом.

Приклади:

1. Записати в байт пам’яті десяткове число 23 і присвоїти цьому

байту ім’я а:

а db 23.

2. Зарезервувати 1 байт пам’яті:

db ?

3. Записати в слово пам’яті шістнадцяткове число 1234:

dw 1234h.

5.2. Операнди команд асемблеру

Операнди команд асемблеру можуть визначатися безпосередньо в

команді, знаходитися в регістрах або в основній пам’яті.

Прикладом команди, в якій безпосередньо записані дані є

mov ah, 3 ; записати в ah константу 3.

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

повідних командах указуються імена регістрів (якщо використовувані

регістри особливо не обмовляються для даної команди). Наприклад, у

наведеному вище прикладі аh – ім’я регістра акумулятора.

Адресація операндів, які розташовуються в основній пам’яті, може

бути прямою і непрямою.

При використовуванні прямої адресації в команді вказується симво-

лічне ім’я поля пам’яті, наприклад:

inc OPND

Page 165: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

165

Тут OPND – символічне ім’я поля пам’яті, визначеного оператором

асемблеру OPND dw ?

При трансляції програми асемблер замінить символічне ім’я на ад-

ресу вказаного поля пам’яті (зміщення щодо початку сегмента) і занесе

цю адресу на місце індексного зміщення. Адресація в цьому випадку

виконується за схемою: BР + <індексне зміщення, але вміст регістра ВР

при обчисленні адреси не використовується (окремий випадок).

На відміну від прямої адреси непряма адреса визначає не місцепо-

ложення даних в основній пам’яті, а місцеположення компонентів адре-

си цих даних. В цьому випадку в команді вказуються один або два регіс-

три відповідно до допустимих схем адресації і індексне зміщення, яке

може задаватися числом або символічним ім’ям. Непряма адреса береть-

ся в квадратні дужки вся або частково, наприклад:

[OPND + SI]

OPND [SI]

OPND + [SI]

[OPND] + [SI]

Наведені вище форми запису непрямої адреси інтерпретуються од-

наково.

При трансляції програми асемблер визначає використовувану схему

адресації і відповідним чином формує машинну команду, при цьому си-

мволічне ім’я замінюється зміщенням щодо початку сегмента так само,

як у разі прямої адресації.

Примітка. При використовуванні непрямої адресації за схемою ВР +

<індексне зміщення>. Останнє не може бути опущене, оскільки окремий

випадок адресації за даною схемою з нульовою довжиною індексного

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

відсутності індексного зміщення в команді слід указувати нульове індек-

сне зміщення, тобто [ВР + 0] .

Наведемо два приклади: [а + bx] і [bр] + [si] + 6.

У першому випадку адреса операнда визначається сумою вмісту ре-

гістра bх і індексного зміщення, заданого символічним ім’ям "а", а в

другому – сумою вмісту регістрів bp, si і індексного зміщення, що дорів-

нює 6.

Довжина операнда може визначатися:

а) кодом команди – в тому випадку, якщо використовувана команда

обробляє дані певної довжини, що спеціально обумовлюється;

Page 166: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

166

б) об’ємом регістрів, використовуваних для зберігання операндів (1

або 2 байт);

в) спеціальними покажчиками byte ptr (1 байт) і word ptr (2 байт), які

використовуються в тих випадках, коли довжину операнда не можна

встановити іншим способом. Наприклад,

mov byte ptr x, 255,

тобто операнд пересилається в полі з ім’ям "х" і має довжину 1 байт.

5.3. Структура програми на мові асемблеру

Структура програми на мові асемблеру виглядає таким чином

(.EXE):

TITLE <ім’я програми>

<ім’я сегмента стека> SEGMENT STACK

DB 3000 DUB (?)

<ім’я сегмента стека> ENDS

<ім’я сегмента даних > SEGMENT

<дані>

<ім’я сегмента даних > ENDS

<ім’я сегмента кодів> SEGMENT

ASSUME CS: <ім’я сегмента кодів DS:<ім’я сегмента даних>

EXTRN <ім’я зовнішньої процедури >:<тип>

PUBLIC <ім’я внутрішньої процедури>

<ім’я основної процедури> PROC FAR

PUSH DS

MOV AX, 0

PUSH AX

MOV AX, <ім’я сегмента даних>

MOV DS, AX

<тіло процедури>

RET

<ім’я основної процедури> ENDP

<ім’я внутрішньої процедури> PROC NEAR

<тіло внутрішньої процедури>

<ім’я внутрішньої процедури> ENDP

<ім’я сегмента кодів> ENDS

END <ім’я основної процедури >

Page 167: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

167

Перший рядок програми – заголовок, що складається зі службового

слова TITLE і імені програми.

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

починається оператором SEGMENT і завершується оператором ENDS:

<ім’я сегмента > SEGMENT ... тіло сегмента ...

<ім’я сегмента > ENDS

Сегмент стека містить спеціальний описувач STACK.

Сегмент кодів, в якому розташовується текст програми,

починається псевдокомандою ASSUME, яка повідомляє асемблеру, який

сегментний регістр повинен використовуватися для адресації кожного

сегмента.

За псевдокомандою ASSUME може слідувати опис

використовуваних програмою зовнішніх підпрограм:

EXTRN <ім’я зовнішньої процедури >:<тип near або far>

PUBLIC <ім’я внутрішньої процедури

Сегмент кодів завжди адресується сегментним регістром CS.

Значення цього регістра операційна система встановлює автоматично.

Значення сегментного регістра DS завантажується програмістом:

MOV AX <ім’я сегмента даних

MOV DS, AX

При необхідності також завантажується регістр ES:

MOV ES, AX

Команди

PUSH DS

MOV AX, 0

PUSH AX

організують можливість повернення керування в MS DOS командою

RET.

У цьому випадку в стек як адреса повернення поміщається адреса

префіксної області програми, перші два байти якої містять команду INT

20H повернення керування операційній системі.

Page 168: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

168

6. СКЛАДАННЯ ТИПОВИХ ОБЧИСЛЮВАЛЬНИХ ПРОЦЕДУР

У МПТ

6.1. Етапи створення програми на мові асемблеру

При вивченні мови Асемблеру під MS-DOS розподілення комірок

пам’яті для збереження кодів команд та чисел для невеличких програм

можна виконувати вручну. При розробці реальних програм на мові Асе-

мблеру цей процес автоматизовано.

Етапи створення програми на мові Асемблеру:

підготовка (або внесення змін) вихідного тексту програми;

асемблування програми (отримання об’єктного коду);

компоновка програми (отримання виконавчого файла програ-

ми);

налагодження програми (виправлення помилок).

Звичайно ці етапи циклічно повторюються, оскільки при виявлені

помилок на всіх етапах доводиться повертатися до першого етапу і вно-

сити зміни в текст програми для виправлення помилок.

Підготовка тексту програми

Текст програми на мові Асемблеру записується в один чи декілька

текстових файлів. Імена файлів і їх розширення можуть бути будь-які,

але прийнято використовувати розширення *.asm. Ці файли є текстови-

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

і зберігати у вигляді звичайних файлів у форматі ASCII.

Асемблювання програми

Підготовлені тексти програми з розширення *.asm є вхідними дани-

ми для програм, які називаються асемблерами (наприклад, програми:

Tasm, Masm, Wasm). Завдання програми асемблера – перетворити текст

програми у форму двійкових команд, які може виконати МП. Після асе-

Page 169: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

169

мблювання отримують файли об’єктних модулів, що мають розширення

*.obj.

Компоновка програми

У випадках, коли текст програми знаходиться в декількох файлах і

спільно використовуються змінні, описані в цих файлах, обов’язково

потрібно включити етап компоновки. Процес об’єднання об’єктних мо-

дулів в один файл здійснюється спеціальною програмою-

компоновником (наприклад програма Tlink). Результатом компоновки є

виконавчі файли, що мають розширення *.com, *.exe.

Схема асемблювання, компоновки і виконання програми наведена

на рис. 6.1.

Налагодження програми

Будь-яка програма потребує налагодження (виправлення помилок).

Сучасні налагоджувальні програми (наприклад програми Debug,

TurboDebugger, Emu8086 v.4.04, OllyDbg) дозволяють у процесі вико-

Рис. 6.1. Схема асемблювання, компоновки і виконання програми

Page 170: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

170

нання програми контролювати значення регістрів загального призначен-

ня чи змінних, змінювати їх. Можна переглядати вміст різних ділянок

пам’яті, можна виконувати програму по крокам.

6.2. Файли .COM і .EXE

Результатом процесу асемблювання-редагування зв’язків є один з

файлів .EXE або .СОМ, головна відмінність між якими пов’язана з фор-

матом запису відповідного об’єктного файла на диску.

Програма, записана у файлі типу .COM, може відразу виконуватися.

DOS може безпосередньо завантажити його в пам’ять з диска. Після

цього DOS передає керування в сегмент пам’яті, відведений для команд,

в точку зі зсувом 100H.

Файл типу .EXE безпосередньо виконаний бути не може. У відпові-

дного об’єктного файла, що зберігається на диску, є заголовок. У ньому

міститься інформація, що генерована редактором зв’язків. Найбільш

важлива її частина відноситься до інформації, пов’язаної з переміщен-

ням. У файлі типу .COM переміщається один сегмент команд, у файлі

типу .EXE можуть бути переміщені багато різних сегментів.

Це обмежує максимальний розмір файла .COM 64 кбайтами, якщо

тільки програма не підвантажує ще і інші сегменти. Файл типу .EXE мо-

же містити ряд сегментів, які динамічно переміщаються в межах про-

грамної області.

У чому полягає переміщуваність? Під час асемблювання програма

розташована в якомусь певному місці пам’яті. Асемблер автоматично

починає кожен сегмент зі зсувом 0. У асемблерних лістингах поряд з

деякими адресами розташовані символи R. Це означає, що дана адреса є

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

зсув, відмінний від 0, то згадана адреса повинна бути змінена. Перемі-

щенням займається редактор зв’язків. Проте перерахунок значень деяких

адрес не може бути виконаний до завантаження програми. В кожному

файлі типу .EXE є інформація про такі адреси.

Файл типу .COM не є переміщуваним. У такого файла відсутня ін-

формація, необхідна для переміщення. Хоча сам сегмент команд можна

модифікувати, початковий зсув завжди повинен бути одним і тим же. У

такій програмі всі зсуви повинні залишатися незміненими.

Крім того, програміст повинен передбачити, щоб при будь-якій

операції з сегментними регістрами (наприклад, запис в сегментний ре-

Page 171: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

171

гістр набутого значення) завжди проводилося звертання до регістра по-

точного сегмента команд. Прикладом правильної програмної послідов-

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

PUSH CS

POP DS

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

наступної послідовності команд (припустимо, що ім’я сегмента команд –

"CODE")

MOV AX,CODE

MOV DS,AX

Для програмного файла типу .COM цей запис буде неправильним. У

момент асемблювання і редагування зв’язків сегментне значення для

сегмента CODE невідомо. Воно визначається тільки при завантаженні

програми. Оскільки файл типу .COM не може надати завантажувачу

переліку всіх сегментних посилань (інформація для переміщення), то в

даному випадку програма виконуватиметься неправильно.

Між описуваними типами файлів є відмінності відносно установки

значень сегментних регістрів і розташування стека. Для файла типу

.COM значення регістрів CS, DS, ES і SS встановлюються DOS, рівними

такими, що вказують на той сегмент, в який вони завантажують програ-

му. Значення регістра SP встановлюється так, щоб він указував на остан-

ній доступний в сегменті елемент пам’яті.

Таким чином, програма займає початок, а стек – кінець сегмента.

У головній мітці файла типу .EXE задаються значення регістрів CS,

IP, SS і SP. Значення регістрів DS і ES DOS встановлює так, щоб вони

вказували на той сегмент, в який завантажується програма. Регістр CS

указує на сегмент, що був ідентифікований як сегмент, який містить ста-

ртову адресу програми.

Якщо у файлі типу .COM програма повинна мати початковий зсув в

сегменті команд рівним 100H, то в програмному файлі типу .EXE почат-

кова адреса може мати інше значення. Як буде показано нижче, значення

цієї адреси може міститися в операторі END:

END START_LOCATION

Це є вказівкою асемблеру-редактору зв’язків, що після завантажен-

ня програми керування слід передати на мітку

START_LOCATION.

В обох типах файлів використовується програмний префікс PSP,

який міститься в перших 100H байтах того сегмента, куди завантажуєть-

Page 172: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

172

ся програма. У цій області пам’яті зберігається спеціальна інформація. В

разі файла типу .EXE регістри DS і ES указують на цю область даних,

тоді як значення регістрів CS і SS встановлюються на відповідних етапах

асемблювання-редагування зв’язків. У разі файла типу .COM всі регістри

вказують на PSP. Це забезпечує обом типам файлів безпосередній доступ

до інформації, що зберігається в порядку програмного сегмента.

Переваги файла типу .COM полягає в тому, що в цьому випадку ре-

гістр CS указує на PSP, а у файлі типу .EXE – ні. Переривання 20H і

27H, пов’язані із завершенням виконання програми і передачею керу-

вання DOS, вимагають, щоб під час переривання регістр указував на

PSP. У разі файла типу .EXE це здійснити складно. Проте наступна пос-

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

управління назад DOS.

PROGRAM PROG FAR

PUSH DS ; запис сегмента з PSP

MOV AX,0

PUSH AX ; запис у стек зсуву 0

...

RET

PROGRAM ENDP

В комірці PSP зі зсувом 0 міститься команда INT 20H. Запис у стек

стану регістра DS і нуля встановлює значення адреси довгого повернен-

ня, яке дорівнює адресі PSP зі зсувом 0. Виконавши команду повернен-

ня, програма перейде до команди INT 20H.

Але до цього моменту в регістрі CS вже зберігатиметься значення

PSP, і команда переривання INT 20H поверне керування DOS.

Для переривання 27H, при якому завершується робота програми і

керування передається DOS зі збереженням програми в пам’яті, анало-

гічного способу реалізації немає. Хоча є методи запису в регістр CS пра-

вильного значення перед перериванням 27H, звичайно простішою є ор-

ганізація програми у вигляді файла типу .COM.

І нарешті, файл типу .COM займає на диску менше місця, ніж файл

типу .EXE з такою ж як у файлі типу .COM програмою. Оскільки у фай-

ла типу .COM відсутній заголовок, то і місця для нього на диску не ви-

магається.

; Програма .СОМ. Виводить повідомлення "Hello World!" і завершується

Page 173: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

173

.model tiny ; модель пам’яті, використовувана СОМ

.code ; початок сегмента коду

org 100h ; початкове значення лічильника – 100h

start: mov ah,9 ; номер функції DOS – в АН

mov dx,offset message ; адреса рядка – в DX

int 21h ; виклик системної функції DOS

ret ; завершення СОМ-програми

message db "Hello World!",0Dh,0Ah,’$’ ; рядок для виведення

end start ; кінець програми

Процес отримання виконуваного .СОМ-файла складається з двох

етапів. Перший етап – компіляція програми в об’єктний файл. Напри-

клад, для того, щоб одержати програму, що відкомпілювалася, з ім’ям

hello-1.obj, необхідно набрати в командному рядку наступну команду:

– для TASM:

tasm hello-1.asm

– для MASM:

ml /c hello-1.asm

– для WASM:

wasm hello-1.asm

Другий етап – отримання виконуваного .СОМ-файла на підставі

файла з obj-розширенням. Для цього можна скористатися асемблером з

одного пакета і компонувальником з іншого, набравши в командному

рядку наступну команду:

– для TLINK:

tlink /t /x hello-1.obj

– для MASM (команда link повинна викликати 16-бітову версію

LINK.EXE):

link hello-1.obj,,NUL,,,

exe2bin hello-1.exe hello-1.com

– для WASM:

wlink file hello-1.obj form DOS COM

ЕХЕ-програми трохи складніші у виконанні, але для них відсутнє

обмеження розміру в 64 кбайт, тому всі достатньо великі програми ви-

користовують саме цей формат.

Page 174: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

174

; Програма .ЕХЕ. Виводить повідомлення "Hello World!" і завершується

.model small ; модель пам’яті, використовувана для ЕХЕ

.stack 100h ; сегмент стека розміром у 256 байт

.code

start: mov ах,@data ; сегментна адреса рядка message

mov ds,ax ; поміщається в DS

mov dx,offset message

mov ah,9

int 21h ; функція DOS "виведення рядка"

mov ах,4C00h

int 21h ; функція DOS "завершити програму"

.data

message db "Hello World!",0Dh,0Ah,’$’

end start

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

ктивою .STACK розміром в 256 байт, сегмент коду, що починається з

директиви .CODE, і сегмент даних, що починається з .DATA. При запус-

ку ЕХE-програми регістр DS вже не містить адреси сегмента з рядком

message (він указує на сегмент, що містить блок даних PSP), а для ви-

клику використовуваної функції DOS цей регістр повинен мати сегмент-

ну адресу рядка.

Компіляція hello-2.asm:

– для TASM:

tasm hello-2.asm

tlink /x hello-2.obj

– для MASM:

ml /с hello-2.asm

link hello-2.obj

– для WASM:

wasm hello-2.asm

wlink file hello-2.obj form DOS

Загальний (спрощений) вигляд програми (вихідного модуля) на мо-

ві Асемблеру

.model Tiny; директива опису моделі пам’яті – визначення механізму

; розподілення пам’яті під дані і команди

Page 175: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

175

.data ; директива початку сегмента ініціалізації даних –

; визначення ділянки пам’яті з даними (сегмента даних)

.code ; початок сегмента кодів

mov ax, @data ; записування початкового сегмента даних у Рг ax

mov ds, ax ; та в регістр ds

; розв’язування задачі

mov ah, 4ch ; занесення коду функції виходу з програми (4Сh) у Рг ah

int 21h ; повернення в програму, з якої викликалася дана програма

end ; директива кінця тексту програми (модуля)

Шаблони для програм

Тип EXE

.MODEL tiny

.STACK 100h

.DATA

.....; дані

.CODE

mov ax,@data

mov ds,ax

..... ; команди програми

mov ah,4ch ; дві команди для повернення

int 21h; в DOS

END

Тип COM

.MODEL tiny

.CODE

ORG 100h

main: ..... ; команди програми

mov ah,4ch ; дві команди для повернення

int 21h; в DOS

..... ; дані

END main

Page 176: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

176

6.3. Програмування в мнемокодах лінійних програм

Приклад 6.1. Написати програму додавання вмісту двох 8-

розрядних комірок пам’яті, що знаходяться в сегменті даних DS зі змі-

щеннями 1000Н і 1001Н. Результат розмістити у комірці пам’яті з адре-

сою DS: 1002H.

У цьому прикладі для простоти не будемо враховувати можливість

виникнення переносу.

Програма має вигляд:

MOV AL, [1000H] ; AL ← DS:[1000H]

; Переслати у 8-розрядний регістр AL вміст комірки

; пам’яті з адресою DS: 1000Н

ADD AL, [1001H] ; AL ← AL + DS:[ 1001H]

; Додати до вмісту AL вміст комірки DS:[1000H]

MOV [1002], AL ; DS:[1002H] ← AL

; Переслати вміст AL у комірку DS:[1002H]

END ; Завершення програми

Відзначимо, що запис MOV AL, [1000H] рівнозначний запису MOV

AL, DS:[1000H], оскільки сегмент DS прийнятий за замовчуванням.

Приклад 6.2. Для МП платформи х86 написати програму

обчислення функції F = Z – Y, де Z знаходиться в АХ, а Y – у комірці

пам’яті [0041]. Результат операції без урахування ознак виконання

операції розташувати в комірках пам’яті, починаючи з [0042].

Програма має вигляд:

MOV CL, [0041] ; (1)

MOV CH, 00 ; (2)

SUB AX, CX ; (3)

MOV [0042], AH ; (4)

MOV [0043], AL ; (5)

У рядку (1) програми виконується читання одного байту пам’яті з

адресою [0041] у молодшу частину СХ, а в рядку (2) – заповнення

нулями старшої частини СХ. Якщо це не зробити, то у регістр CH

запишеться зміст комірки [0042]. Виконання операції віднімання

виконуються в рядку (3). Занесення результату виконання операції

здійснюється в рядках (4) та (5).

Page 177: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

177

Приклад 6.3. Передати число з першої комірки пам’яті нульового

сегмента в другу комірку пам’яті третього сегмента.

Програма має такий вигляд:

MOV AX, 0000H ; Занесення номера сегмента 0000h Рг АХ

MOV DS, AX ; Передача нульового сегмента в Рг DS

MOV BX, [0001] ; Передача в Рг ВХ числа, яке знаходиться

; в комірці пам’яті 0001h

MOV AX, 0003H ; Занесення номера сегмента 0003h Рг АХ

MOV DS, AX ; Передача третього сегмента в Рг DS

MOV [0002], BX ; Передача вмісту Рг ВХ у комірку пам’яті

; з номером 0002h сегмента 0003h

HLT ; Зупинка процесора

Приклад 6.4. Скласти програму для обчислення z = x + y для цілих

чисел x, y з директивами асемблеру.

Оператори мови асемблеру поділяються на команди і директиви.

Директива задає необхідну інформацію транслятору.

.MODEL SMALL ; коди та дані займають <= 64 кбайт

.DATA ; початок сегмента даних

x DW 5

y DW 3

z DW ?

.CODE

begin: MOV AX,@DATA ; встановити адресу сегмента даних

MOV DS,AX ; ініціювати DS для завдання DS: SI

MOV AX,X ; AX ← X

ADD AX,Y ; AX ← X + Y

MOV Z,AX ; Z ← AX

MOV AX,4C00H

INT 21H

END begin

Вікна налагоджувача Emu8086 v.2.57 при налагодженні програми

прикладу 6.4 наведено на рис. 6.2.

Page 178: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

178

Перша директива програми − .MODEL. Директива задає механізм

розподілу пам’яті під дані і команди. Аналогічна моделям пам’яті в мо-

вах високого рівня. Імена моделей пам’яті в С й асемблері однакові

(TINY, SMALL, COMPACT, MEDIUM, LARGE, HUGE).

Директива .DATA визначає початок ділянки програми з даними (се-

гмент даних, який відповідає області опису даних у мовах високого рів-

ня).

Директиви DW задають типи змінних (Define Word), їх значення

(для змінних x, y). Для змінної z початкове значення не визначене (?).

Директива .CODE визначає початок ділянки програми з командами

(кодовий сегмент). Для правильного звертання до змінних із сегмента

даних адреса цього сегмента повинна бути записана у регістр DS (Data

Segment).

Для повернення в програму, з якої викликається програма, викорис-

товується системний виклик (INT 21H). При цьому у регістр AX запису-

ється код функції виходу з програми (4C) і код повернення (00).

Рис. 6.2. Вікна налагоджувача Emu8086 v.2.57 при налагодженні програми

прикладу 6.4

Page 179: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

179

У директиві END задана мітка виконуваної команди програми begin

(адреса точки входу).

Директиви Асемблеру для masm32 дещо зміняться, а програма ма-

тиме такий вигляд:

.386

.MODEL flat,stdcall ; модель пам’яті для ОС Windows

DATA segment ; початок сегмента даних

x DW 5

y DW 3

z DW ?

.CODE ; початок сегмента команд

begin: ; мітка початку основного тіла програми

MOV AX,X

ADD AX,Y

MOV Z,AX

RET ; вихід із ОС Windows

END begin ; закінчення програми

Вікна налагоджувача OllyDbg з відповідною програмою наведені на

рис. 6.3.

Рис. 6.3. Вікна налагоджувача OllyDbg з програмою до прикладу 6.4

Page 180: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

180

Приклад 6.5. Скласти програму для обчислення z = x + y для цілих

чисел x, y з використанням процедури та директив асемблеру masm32.

Програма має такий вигляд:

.386

.model flat,stdcall

option casemap:none ; директива для відмінності прописних та рядкових

літер

.code

start:

mov ax,5

mov bx,3

call AddРr

ret

AddРr proc

add ax,bx

ret

AddРr endp ; кінець процедури

end start ; кінець програми

Команда call записує адресу наступної інструкції у стек, потім пере-

водить процесор до адреси першої інструкції процедури. Ці інструкції

виконуються до тих пір, поки не зустрінеться інструкція ret, яка зчитає зі

стека адресу повернення. Після цього процесор продовжить виконувати

інструкції з цієї адреси.

Приклад 6.6. Керування звуком від таймера. Генерація тону.

include mac.mac ; (0) Об’ява макробібліотеки

; Встановимо режим таймера

mov AL, B6h ; (1) Записати керуюче слово в AL

out 43h, AL ; (2) Виведемо його в регістр команд

; Встановимо частоту каналу 2 таймери

mov AX, 0А97h ; (3) 1193000 Гц/440 = 2712D = А97H Гц

out 42h, AL ; (4) Молодший байт константи в порт

mov AL, AH ; (5) А1 = старший байт константи

out 42h, AL ; (6) Старший байт константи в порт

; Вимкнемо динамік і таймер

in AL, 61h ; (7) Введемо вміст порту 61h

Page 181: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

181

or AL, 3 ; (8) Установимо біти 0 і 1

out 61h, AL ; (9) Виведемо в порт

; Після затримки вимкнемо динамік і таймер

delay 50 ; (10) Підпрограма затримки

and AL, 11111100bh ; (11) Скинемо в AL біти 0 і 1

out 61h, AL ; (12) Виведемо в порт

Приклад 6.7. Передати 10 байтів із однієї області пам’яті,

починаючи з комірки 0000Н, в область пам’яті, починаючи з 1000Н

комірки пам’яті.

Програма має такий вигляд:

MOV CX, 000A ; Завантаження в лічильник числа елементів даних

MOV SI, 0000h ; Завантаження в SI номера першої комірки-

джерела

MOV DI, 1000h ; Завантаження в DI номера першої комірки-

приймача

M1: MOV AL, [SI] ; Пересилка байта в AL із джерела

MOV [DI], AL ; Пересилка в приймач

INC SI ; Інкремент SI: SI = SI + 1

INC DI ; Інкремент DI

DEC CX ; Декремент CX: CX = CX – 1

JNZ M1 ; Перевірка закінчення циклу

HLT ; Зупинка процесора

6.4. Програмування в мнемокодах галузевих і циклічних програм

Асемблер, будучи мовою низького рівня, не містить операторів роз-

галуження, циклів, не підтримує автоматичного формування адрес для

структур даних, не забезпечує автоматичного виконання перетворень

при введенні-виведенні даних. Усі перераховані операції програмуються

“вручну” з використанням наявних команд асемблеру.

Розгалуження програмуються з використанням команд умовної та

безумовної передачі управління.

Одна з команд, звичайно використовуваних для передачі керуван-

ня – команда JMP. Ця команда виконує безумовний перехід, тобто за-

безпечує передачу керування за будь-яких обставин.

Page 182: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

182

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

або команд переходів, або – у випадку лічильних циклів – з використан-

ням команд організації циклів.

Приклад 6.8. Додати два числа. Одне число дорівнює 1С32, а друге

число знаходиться в комірці пам’яті [0020]. Результат операції

додавання зберегти в комірках пам’яті, починаючи з комірки 007А

Алгоритм виконання програми наведено на рис. 6.4.

Програма має такий вигляд:

MOV AX,1C32

ADD AX, [0020h] ; AX ← AX + [0020h]

JC M1 ; Перехід до адреси М1, якщо є переповнення

MOV [007A], 00

JMP M2 ; Безумовний перехід до адреси М2

M1: MOV [007А], 01h ; Занесення 1, якщо є перенос,

; у комірку пам’яті 007Аh

M2: MOV [007B], AX

END ; Завершення програми

Приклад 6.9. Модернізувати програму прикладу 6.1 зі урахуванням

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

програми.

Алгоритм виконання програми наведено на рис. 6.5.

AX ← 1C32 +[0020]

C = 1

[001F] ← 0

Початок

Кінець

Рис. 6.4. Алгоритм виконання

прикладу 6.8

Так Ні

[001F] ← 1

[0020] ← AX

AL ← [1000]

AL ← AL + [1001]

[1002] ← AL

JO = 1

[1002] ← AL

Початок

Кінець

Рис. 6.5. Алгоритм виконання

прикладу 6.9

Так

Ні

Page 183: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

183

Програма має такий вигляд:

MOV AL, [1000H] ; AL ← DS:[1000H]

ADD AL, [1001H] ; AL ← AL + DS:[ 1001H]

MOV [1002], AL ; DS:[1002H] ← AL

JO M1 ; Перехід до адреси М1, якщо є переповнення

JMP M2 ; Безумовний перехід до адреси М2

M1: MOV [1003], 0001h ; Занесення 1, якщо є перенос,

; у комірку пам’яті 1003h

M2: END ; Завершення програми

Приклад 6.10. Передати 5-ть слів (слово – 16 розрядів) із однієї

області пам’яті, починаючи з комірки 0000Н в область пам’яті,

починаючи з 1000Н комірки пам’яті.

Програма має такий вигляд:

MOV CX, 0005 ; Завантаження в лічильник числа елементів даних

MOV SI, 0000h;Завантаження в SI номера першої комірки-джерела

MOV DI, 1000h;Завантаження в DI номера першої комірки-приймача

M1: MOV AX, [SI] ; Пересилка байта в AL із джерела

MOV [DI], AX ; Пересилка в приймач

INC SI ; Інкремент SI: SI = SI + 1

INC SI ; Інкремент SI: SI = SI + 1

INC DI ; Інкремент DI

INC DI ; Інкремент DI

DEC CX ; Декремент CX: CX = CX – 1

JNZ M1 ; Перевірка закінчення циклу

HLT ; Зупинка процесора

Приклад 6.11. Додати два 8-байтових числа. Перше багатобайтове

число знаходиться в комірці пам’яті, починаючи з адреси 0100, а друге –

з 0200.

Програма має такий вигляд:

CLC ; Скидання прапорця CF

MOV CX, 0008h ; Завантаження кількості байтів у лічильник

MOV SI, 0100h;Завантаження в SI номера першої комірки-джерела

MOV DI, 0200h;Завантаження в DI номера першої комірки-

приймача

M1: MOV AL, [SI] ; Завантаження в Рг АL байта з пам’яті,

Page 184: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

184

; адреса якого знаходиться в Рг SI

ADC [DI], AL ;Додавання до вмісту Рг AL байта, який знаходиться

; в пам’яті, адреса якого розміщується в Рг DI

INC SI ; Iнкремент SI: SI = SI + 1

INC DI

DEC CX ; Декремент CX: CX = CX – 1

JNZ M1; Перехід до адреси М1, якщо вміст Рг СХ не дорівнює нулю

HLT ; Зупин процесора

Результат операції розміщується за адресою другого операнда.

Приклад 6.12. Написати програму реалізації прикладу: Nзн – [Nзн],

де Nзн – номер за порядком навчаючого у журналі, [Nзн] – комірка

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

ташування в комірці пам’яті 0001h, а модуля числа – в комірці 0002h.

Як Nзн приймемо число 0002.

MOV AX, 0002

SUB AX, [0002]

JS A1 ; перейти на А1, якщо число негативне

MOV [0001], 0000 ; знак позитивного числа

MOV [0002], AX

JMP A2

A1: MOV [0001], 0001 ; знак негативного числа

SUB [0002], AX

A2: END

Приклад 6.13. Написати програму аналізу двох чисел:

якщо А < В, то записати 1 в Рг СХ;

якщо А = В, то записати 1 в Рг ВХ;

якщо А > В, то записати 1 в Рг DХ.

Алгоритм виконання програми наведено на рис. 6.6.

Програма з використанням 32-розрядних регістрів має такий ви-

гляд:

.386

.MODEL flat,stdcall

DATA segment

A DW 3

B DW 5

Z DW ?

Page 185: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

185

.CODE

begin:

MOV AX, A

SUB AX, B

JS minus

JZ ravno

MOV EDX, 0001h

JMP A1

Ravno: MOV EBX, 0001h

JMP A1

Minus: MOV ECX, 0001h

A1:

END begin

Вікна налагоджувача OllyDbg з відповідною програмою наведені на

рис. 6.7.

Приклад 6.14. Для МП х86 навести алгоритм та програму перемно-

ження двох чисел: числа А – в комірках пам’яті [0040, 0041] і числа В –

в комірці [0042]. Результат розташувати в комірках пам’яті, починаючи з

[0044]. Проаналізувати ознаки виконання операції.

Алгоритм виконання програми наведено на рис. 6.8.

AX ← A

AX ← AX – B

S = 1

DX ← 1

Початок

Закінчення

Рис. 6.6. Алгоритм виконання прикладу 6.13

Так Ні

Z = 1

CX ← 1 BX ← 1

Page 186: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

186

Програма має такий

вигляд:

MOV AL, [0040]

MOV AH, [0041]

MOV CX, [0042]

MOV CH, 00

MUL CX

JS M1

JMP M2

M1: MOV [0044], 01

M2: MOV [0044], 00

MOV [0045], AL

MOV [0046], AH

MOV [0047], DX

Рис. 6.8. Алгоритм виконання прикладу 6.14

Початок

S = 1 Taк Ні

AL := [0040]

Ah := [0041]

DX,AH := AX CX

[0044] ← 01 [0044] ← 00

[0045] ← AX

[0047] ← DX

Кінець

CX := [0042]

CH := 00

Рис. 6.7. Вікна налагоджувача OllyDbg з програмою до прикладу 6.13

Page 187: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

187

Приклад 6.15. Написати програму реалізації прикладу: X + Y +

2Z, де Х = 2345, Y = 2233, Z = 1AC1. Результат виконання операції ро-

змістити в комірках пам’яті, починаючи з 0020h.

Схема виконання прикладу X + Y + 2Z наведена на рис. 6.9.

Граф-схема алгоритму виконання прикладу X + Y + 2Z наведена

на рис. 6.10.

Програма має такий вигляд:

CLC ; Скидання CF

MOV AX, 2345 ;

ADD AX, 2233 ;

JO M1 ; Перехід до адреси М1, якщо є переповнення

Х

Y +

[0023] BX

Z

2

DX AX

+

[0022] [0021]

CF

[0020

]

CF

Рис. 6.9. Схема виконання

прикладу 6.15:

X + Y + 2Z

Рис. 6.10. Алгоритм виконання прикладу 6.15

AX := 2345

OF = 1

Початок

Так

Ні

BX ← 1

AX := АХ + 2233

[0023] ← AX

CX := 2

AX := 1AC1

DX, AX := CX AX

AX := AX + [0023]

[0022] ← AX

BX := BX + DX

[0021] ← BX

OF = 1 Так Ні

[0020] ← 1 [0020] ← 0

Кінець

Page 188: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

188

JMP M2 ; Безумовний перехід до адреси М2

M1: MOV BX, 0001 ;

M2: MOV [0023], AX ;

MOV CX, 0002 ;

MOV AX, 1AC1 ;

MUL CX ; DX, AX ← CX AX

ADD AX, [0023] ;

MOV [0022], AX ;

ADC BX, DX ; Додавання із врахуванням переповнення

JO M3 ; Перехід до адреси М3, якщо є переповнення

JMP M4 ; Безумовний перехід до адреси М4

M3: MOV [0020], 01 ;

M4: MOV [0020], 00 ;

HLT ; Зупин процесора

Приклад 6.16. Написати програму реалізації прикладу X – 2(Z – 1),

де Х = 1234, Z = [0040]. Результат розташувати в комірках пам’яті, по-

чинаючи з 0041h.

Процес виконання креслення алгоритму необхідно починати з ана-

лізу діапазону можливих значень чисел. У наведеному випадку інтерес

являє число Z = 0 та Z ≥ 1. У першому випадку вираз 2(Z – 1) < 0, а у

другому – більше 0.

Граф-схема алгоритму виконання прикладу X – 2(Z – 1) наведена на

рис. 6.11.

Програма на асемблері МП платформи х86 може мати такий вигляд:

0000 B93412 MOV CX, 1234 ; (1) Завантаження в СХ

0003 FF0E4000 DEC [0040] ; (2

0007 7804 JS M1 ; (3) Перевірка знака

0009 B300 MOV BL,00 ; 4) Запам’ятання знака

000B EB02 JMP M2 ; (000F) ;

000D B301 M1: MOV BL, 01 ; (5) Запам’ятання знака

000F B002 M2: MOV AL, 02 ; (6)

0011 8A264000 MOV AH, [0040] ; (7)

0015 F6E4 MUL AH ; (8) AX := AH × AL

0017 80C300 ADD BL, 00 ; (9) Формування прапорців

001A 7404 JZ M3 ; (0020) ; (10) Знак результату в дужках

001C 01C1 ADD CX, AX ; (11)

001E EB02 JMP M4 ; (0022) ;

Page 189: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

189

0020 29C1 M3: SUB CX, AX ; (12)

0022 7202 M4: JC M5 ; (0026) ; (13) Переповнення або зайняття

0024 EB01 JMP M6 ; (0027) ;

0026 42 M5: INC DX ; (14)

0027 88364100 M6: MOV [0041], DH ; (15) Старша частина результату

002B 88164200 MOV [0042], DL ; (16)

002F 882E4300 MOV [0043], CH ; (17)

0033 880E4400 MOV [0044], CL ; (18) Молодша частина результату

0037 F4 HLT ; (END) ; (0) Зупинка

У вершині 8 виконується операція множення AH на AL. Замість цієї

команди можливо виконання команди MUL [0040]. Однак при її викори-

станні треба передбачити, що в цьому випадку буде виконано операцію

DX, AX := [0041, 0040] × AX

Приклад 6.17. Написати програму реалізації прикладу: 2X + 18 –

Z, де Х знаходиться в комірці пам’яті [0040], Z – [0041]. Знак результату

та результат розташувати в комірках пам’яті, починаючи з 0042h.

Граф-схема алгоритму виконання прикладу: 2X + 18 – Z наведена

на рис. 6.12.

Рис. 6.11. Алгоритм виконання прикладу 6.16

Початок

Закінчення

Так

Ні

СX := 1234

SF = 1

[0040] := [0040] – 1

BL := 00 BL := 01

AL := 02

AH := [0040]

AX := AL × AH

BL := BL + 00

Z = 1

AX := CX + AX AX := CX – AX

C = 1

DX := DX + 1

Так

[0041] := DH

[0042] := DL

[0043] := CH

[0044] := CL

Ні

Так

Ні

1

2

3

4 5

6

7

8

9

10

11 12

13

14

15

16

17

18

0

0

M3:

M1:

M2:

M4:

Page 190: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

190

Програма на асемблері МП платформи х86 може мати такий вигляд:

0000 F8 CLC ; (1) CF = 0

0001 A04000 MOV AL, [0040] ; (2) Завантаження Х в АL

0004 B402 MOV AH, 02 ; (3) Завантаження const 02

0006 F6E4 MUL AH ; (4) AX := AL × AH

0008 051800 ADD AX, 0018 ; (5)

000B 7204 JC M1 ; (0011) ; (6)

000D B300 MOV BL, 00 ; (7)

000F EB02 JMP M2; (0013) ; (7) Безумовний перехід на М2

0011 B301 M1: MOV BL, 01 ; (8)

0013 F8 M2: CLC ; (9) CF = 0

0014 8A0E4100 MOV CL, [0041] ; (10) Організація процесу

0016 B500 MOV CH, 00 ; (11) віднімання від Рг змісту

001A 29C8 SUB AX, CX ; (12) комірки пам’яті

001C 7202 JC M3 ; (0020) ; (13)

001E EB05 JMP M4 ; (0025); (13) Безумовний перехід на М4

0020 F8 M3: CLC ; (14) CF = 0

Рис. 6.12. Блок-схема виконання прикладу 6.17

Початок

0

AL := [0040]

AH := 02

2

3

Закінчення

CF := 0 1

AX := [SI] 8

C = 0

6 Так M1:

Ні

AX := 00

7

AX := AL × AH 4

AX := AL + 18 5

CF := 0 9

CH := 00

AX := AX – CX

11

12

CL := [0041] 10

C = 1

BL := BL – 1 15

CF := 0 14

[0042] := 01 18

S = 1

16 Так M5:

Ні

[0042] := 00

17

[0044] := AH

[0045] := AL

20

21

[0043] := BL 19

13 Так M3:

22

M4:

M6:

Page 191: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

191

0021 FECB DEL BL ; (15)

0023 7207 JC M5 ; (002C) ; (16)

0025 C606420000 M4: MOV [0042], 00 ; (17)

002A EB05 JMP M6 ; (0031) ; (17) Безумовний перехід на М6

002C C606420001 M5: MOV [0042], 01 ; (18) Запис знака результату

0031 881E4300 M6: MOV [0043], BL; (19) Старша частина результату

0035 88264400 MOV [0044], AH; (20)

0039 A24500 MOV [0045], AL; (21) Молодша частина результату

003C F4 HLT ; (END) ; (22) Зупин

Приклад 6.18. Написати процедуру додавання чисел від 1 до 10

(1, 2, 3, … , 10), використовуючи ітераційний цикл.

Програма має такий вигляд:

sum proc near

mov ax, 0

mov bx, 1 ; перший доданок

CYCL: cmp bx, 10 ; порівняння двох операндів

jg CONTINUE ; вихід з циклу

add ax, bx ; підсумовування

inc bx ; наступне число

jmp CYCL ; повернення в цикл

CONTINUE: ret ; вихід, сума – у ax

sum endp

Приклад 6.19. Написати процедуру додавання чисел від 1 до 10,

використовуючи рахунковий цикл.

Програма має такий вигляд:

sum proc near

mov ax, 0

mov bx, 1 ; перший доданок

mov cx, 10 ; завантаження лічильника

CYCL: add ax, bx ; підсумовування

inc bx ; наступне число

loop CYCL ; повернення в цикл

ret ; завершення роботи, сума – у ax

sum endp

Page 192: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

192

Масив у внутрішньому уявленні – це послідовність елементів у

пам’яті, наприклад: A dw 10,13,28,0,-1 ; масив з 5 чисел розміром слово.

Програмування обробки виконується з використанням адресного

регістра, в якому зберігається або адреса поточного елемента, або його

зміщення відносно початку масиву. При переході до наступного елемен-

та адреса (чи зміщення) збільшується на довжину елемента.

Приклад 6.20. Написати процедуру, що виконує додавання 10 чи-

сел з розміром у слово.

Другий варіант дозволяє одержувати більш наочний код і тому є

кращим.

У тому випадку, якщо елементи проглядаються непослідовно, адре-

са елемента може бути розрахована за його номером:

Aвикон = Aпочатку + (<номер> – 1) * довжина елемента.

Отримана за формулою адреса записується в один з адресних регіс-

трів (BX, BP, DI, SI) і використовується для доступу до елемента.

Варіант 1 (використовується адреса): Варіант 2 (використовується зсув):

summas proc summas proc

mov ax, 0 mov ax, 0

lea bx, MAS mov bx, 0

mov cx, 10 mov cx, 10

CYCL: add ax, [bx] CYCL: add ax, MAS [bx]

add bx, 2 add bx, 2

loop CYCL loop CYCL

ret ret

summas endp summas endp

Приклад 6.21. Написати процедуру, яку витягають з масиву, що

включає 10 чисел розміром у слово, число з номером n (n 10).

Програма має такий вигляд:

n_mas proc

mov bx, N ; номер числа

dec bx ; віднімаємо 1

sal bx, 1 ; помножимо на довжину (зсув вліво на 1)

mov ax, MAS [bx] ; результат – у ax

Page 193: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

193

ret

n_mas endp

Приклад 6.22. Для функції Y = 5Х + 25 ≤ 100 знайти кількість ар-

гументів, за яких молодший розряд результату дорівнює “0”, починаючи

з Х = 0 та дискретністю перебору аргументу Х = 2.

Блок-схема виконання прикладу наведена на рис. 6.13.

Програма на асемблері МП платформи х86 може мати такий вигляд:

0000 MOV BL, 00 ; (1) X

0002 MOV BH, 00 ; (1) K

0004 M5: MOV AL, 05 ; (2)

0006 MUL BL ; (2) AX ← BL × AL

0008 ADD AX, 19H ; (2) Виконання функції Y

000B MOV DX, 64H ; (3) Занесення числа 10010 до DX

000E CMP DX, AX ; (3) Порівняння змісту DX та АХ

0010 JNE M1 ; (3) Перехід, якщо “менше або дорівнює”

0012 JMP M2 ; (3)

0014 M1: MOV [0030], BH ; (4)

0018 HLT ; (END) ; (0)

0019 M2: AND AX, 000F ; (5) Виділення молодшого числа

001C JZ M3 ; (5)

Х := 0 ; аргумент Х

К := 0 ; кількість аргум.

Yi := 5Х + 25

Початок

Ні

1

Рис. 6.13. Блок-схема виконання прикладу 6.22

Так

Yi ≤ 100

2

3

0

M2:

Yi[0] = 0 5

Так

К := К + 1 6

Х := Х + 2

Закінчення 0

Ні

7

[0030] ← К 4

Page 194: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

194

001E JMP M4 ; (5)

0020 M3: INC BH ; (6)

0022 M4: ADD BL, 02 ; (7)

JMP M5 ; (7)

Моделювання матриць

Значення матриці можуть розміщуватись в пам’яті по рядках і сто-

впчиках. Для зручності будемо вважати, що матриця розміщена в пам’яті

порядково.

При моделюванні обробки матриці варто розрізняти перегляд по

рядках, перегляд по стовпчиках, перегляд по діагоналях і довільний дос-

туп.

Перегляд за рядками іноді може виконуватися так, як в одновимір-

ному масиві (без врахування переходу від одного рядка до іншого).

Приклад 6.23. Написати процедуру визначення максимального

елемента матриці A(3, 5).

Програма має такий вигляд:

mахмatr proc

mov bx, 0 ;

mov cx, 14 ; лічильник циклу

mov ax, A ; заносимо перше число

CYCL: cmp ax, A[bx + 2] ; порівнюємо числа

jge NEXT ; якщо більше, то перейти до наступного

mov ax, A[bx + 2] ; якщо менше, то запам’ятати

NEXT: add bx, 2 ; переходимо до наступного числa

loop CYCL

ret ; результат – у ax

mахмatr endp

Перегляд по стовпчиках виконується в подвійному циклі: по рядках

– у зовнішньому циклі, по стовпчиках – у внутрішньому чи навпаки. У

цьому випадку звичайно окремо формуються зсуви рядка і стовпчика.

Приклад 6.24. Визначити суму максимальних елементів стовпчиків

матриці A(3, 5).

Програма має такий вигляд:

Page 195: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

195

mахмatr proc

mov ax, 0 ; початкова сума

mov bx, 0 ; елемент стовпчика в рядку

mov cx, 5 ; кількість стовпчиків

CYCL1: push cx ; зберігаємо лічильник

mov cx, 2 ; лічильник елементів у стовпчику

mov dx, A[bx] ; заносимо перший елемент стовпчика

mov si, 10 ; зсув другого елемента стовпчика

CYCL2: cmp dx, A[bx] + [si] ; порівнюємо

jge NEXT ; якщо більше чи дорівнює, – до наступного

mov dx, A[bx]+[si] ; якщо менше, то зберегти

NEXT: add si, 10 ; переходимо до наступного елемента

loop CYCL2 ; цикл по елементах стовпчика

add ax, dx ; додавали максимальний елемент

pop cx ; відновили лічильник

add bx, 2 ; перейшли до наступного стовпчика

loop CYCL1 ; цикл по стовпчиках

ret ; результат – у ax

mахмatr endp

6.5. Завдання для самостійного закріплення матеріалу

1. Проаналізувати масив даних з 15 елементів. Підрахувати і зберег-

ти в комірках пам’яті кількість елементів масиву, якщо їх значення мен-

ше або більше 132; кількість елементів масиву, значення яких дорівню-

ють 132. Вивести відповідні повідомлення.

2. Проаналізувати масив даних з 10 елементів. Додавати елементи

масиву доти, доки значення суми не перевищить 512. Зберегти номер

елемента, на якому відбулося переповнення. Якщо сума елементів не

досягла значення 512, то видати відповідне повідомлення.

3. Проаналізувати масив даних з 16 елементів. Елементами масиву є

числа 32, 64, 96 і 128. Підрахувати та вивести на екран кількість повто-

рень кожного елемента.

4. Проаналізувати масив даних з 12 елементів. Створити масив, до

якого входять елементи першого масиву, що дорівнюють 128. Перервати

виконання програми, якщо буде знайдено 5 елементів зі значенням 128.

Вивести відповідні повідомлення.

Page 196: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

196

5. Проаналізувати 2 масиви, що складаються з 15 елементів кожен.

Підрахувати кількість елементів першого масиву, що мають рівні зна-

чення в другому масиві. Вивести відповідні повідомлення.

6. Проаналізувати масив даних з 14 елементів. Підрахувати кіль-

кість елементів, значення яких дорівнює 55h. Рахунок перервати, якщо

кількість елементів перевищить 3. Вивести відповідні повідомлення.

7. Проаналізувати масив даних з 15 елементів. Елементами масиву є

числа 10, 20, 30 і 180. Підрахувати кількість повторень кожного елемен-

та. Вивести відповідні повідомлення.

8. Для функції Y = 40Х + 65 видати в комірку пам’яті перше зна-

чення аргументу, при якому значення функції перевищить 1024. Почат-

кове значення аргументу Х = 20.

9. Для функції Y = 40Х + 10 одержати перше значення, що переви-

щує 512, починаючи з Х = 1. Значення аргументу та функції записати в

комірки пам’яті.

10. Для функції 7Х + 85 знайти перше значення аргументу, при яко-

му молодші цифри результату виконання функції дорівнюють 155. Ре-

зультат виконання функції та його аргумент розмістити в комірках

пам’яті.

6.6. Обмін даними із зовнішніми пристроями в МПС

На основі використання програм-симуляторів Sms32v23 та

Emu8086 (v2.56, v4.04) можна дослідити програми взаємодії МП з

об’єктами керування.

6.6.1. Ознайомлення з середовищем програмування

Центральний процесор, емульований програмою-симулятором

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

BL, CL, DL. Розрядність регістрів – вісім бітів.

Спеціальні регістри в центральному процесорі називають IP, SR і

SP.

IP – покажчик інструкції. Цей регістр містить адресу виконуваної

інструкції. Коли інструкція виконана, IP збільшується, щоб указати на

наступну інструкцію.

SR – регістр прапорців. Цей регістр містить прапорці, що повідо-

мляють про стан центрального процесора:

Page 197: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

197

Z – прапорець нуля, встановлений в одиницю, якщо обчислення да-

ло нульовий результат.

S – прапорець ознаки (підпису), встановлений в одиницю, якщо об-

числення дало від’ємний результат.

О – прапорець переповнення, встановлюється в одиницю, якщо ре-

зультат був занадто великий, щоб розміститися в регістрі.

I – прапорець переривань, встановлений, якщо переривання дозво-

лені.

SP – покажчик стека. Покажчик стека вказує на наступне вільне

місце розташування стека.

Симулятор має 256 байтів пам’яті. Адреси – від 0 до 255 у десятко-

вих числах від [00] до [FF]. У симуляторі використовується 6 портів:

порт 1 – для моделювання процесу керування світлофором;

порт 2 – для моделювання процесу виводу даних на семисегмент-

ний дисплей;

порт 3 – моделювання роботи терморегулятора;

порт 4 – моделювання процесу руху по лабіринту.

порт 5 – моделювання процесу керування роботою мотора;

порт 6 – моделювання процесу керування ліфтом.

Симулятор використовує такі команди:

ADD AL AND BL CALL CL CLI CLO CMP CPU DB DEC

DIV DL END HALT IN INC INT IRET JMP JNO JNS JNZ

JO JS JZ MOD MOV MUL NOP NOT OR ORG OUT POP

POPF PUSH PUSHF RET ROL ROR SHL SHR STI SUB XOR

6.6.2. Організація взаємодії з об’єктом керування

Для кожного завдання накреслити алгоритм роботи та навести про-

граму реалізації алгоритму з коментарем.

6.6.2.1. Моделювання процесу керування роботою світлофора

Для керування роботою світлофора в програмі-симуляторі

Sms32v23 використовується порт № 1.

Схема підключення світлофора наведена на рис. 6.14.

Page 198: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

198

Лістинг програми для заго-

ряння жовтого індикатора на

лівому світлофорі, а також чер-

воного і зеленого індика- торів

на правому світлофорі:

CLO

Start:

MOV AL, 0

OUT 01

MOV AL, FC

OUT 01

JMP Start

END

Лістинг програми для заго-

ряння індикаторів на лівому і правому світлофорах (дані наведені в

пам’яті):

JMP Start

DB 84

DB C8

DB 31

DB 58

Start: MOV BL, 02

Rep: MOV AL, [BL]

OUT 01

CMP AL, 58

JZ Start

INC BL

JMP Rep

END

При програмуванні двох світлофорів згідно з рис. 6.15 лістинг про-

грами може виглядати й таким чином:

Start: MOV AL, 84

OUT 01

MOV AL, CC

OUT 01

MOV AL, 48

OUT 01

Рис. 6.14. Схема підключення світ-

лофора

Page 199: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

199

MOV AL, 30

OUT 01

MOV AL, 78

OUT 01

JMP Start

END

Рис. 6.15. Кодування станів світлофора

Завдання:

1. Індикація відображення одиниці, “яка біжить” за годинниковою

стрілкою (з використанням директиви однобайтового поля DB).

2. Індикація відображення одиниці, “яка біжить” проти годиннико-

вої стрілки (з використанням директиви однобайтового поля DB).

3. Індикація відображення нуля, “який біжить” за годинниковою

стрілкою (з використанням директиви однобайтового поля DB).

4. Індикація відображення нуля, “який біжить” проти годинникової

стрілки (з використанням директиви однобайтового поля DB).

Накреслити один з алгоритмів роботи та навести програму реаліза-

ції алгоритму.

Для того, щоб використовувати 16-розрядний асемблер при керу-

ванні світлофорами на перехресті скористаємося програмою Emu8086

v.2.57. В цій програмі перехрестя подається у вигляді, наведеному на

рис. 6.16.

Для написання і відладки програми необхідно:

1 0 0 0 0 1 0 0 84 Ч З

1 1 0 0 1 1 0 0 СС Ч + Ж З + Ж

0 1 0 0 1 0 0 0 48 Ж Ж

0 0 1 1 0 0 0 0 30 З Ч

0 1 1 1 1 0 0 0 78 З + Ж Ч + Ж

Ч Ж З Ч Ж З

Page 200: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

200

завантажити програму Emu8086 v.2.57;

натиснути кнопку New і у вільному полі набрати програму керу-

вання світлофорами;

послідовно натиснути

Emulator – Compile and Load

in Emulator – вибір програми

ЕХЕ;

відкрити вікно роз-

поділу пам’яті: View –

External Memory Viewer і

встановити в ньому

segment:offset такими, як і у

вікні 8086 Microprocessor

Emulator (memori);

для послідовної від-

ладки команд програми на-

тискати кнопку Single Step чи

одноразово натиснути кнопку

Run – для виконання всієї

програми.

Програма на асемблері i8086 для послідовного включення і виклю-

чення тільки зеленого світла за годинниковою стрілкою на світлофорах,

починаючи з молодшого номера має такий вигляд:

.model small

data segment

a1 dw 0001h,0008h,0040h,0200h

data ends

.code

st: mov ax,@data

mov ds,ax

mov cx,4

mov si,offset a1

m2: mov ax,[si]

out 4, ax

dec cx

jz m1

inc si

inc si

Рис. 6.16. Схема підключення світлофора

у відладчику Emu8086 v. 2.57

Page 201: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

201

jmp m2

m1: mov ax,4c00h

int 21h

end st

Вікна відладчика Emu8086 v. 2.57 при налагодженні програми наве-

дені на рис. 6.17.

Завдання

1. Правильне керування світлофорами перехрестя, починаючи з

верхнього за схемою. Перед перемиканням чергового сигналу включати

жовте світло.

2. Правильне керування світлофорами перехрестя, починаючи з лі-

вого за схемою. Перед перемиканням чергового сигналу включати жов-

те світло.

3. Правильне керування світлофорами перехрестя, починаючи з

правого за схемою. Перед перемиканням чергового сигналу включати

жовте світло.

Рис. 6.17. Вікна відладчика Emu8086 v. 257 при налагодженні програми

керування світлофорами

Page 202: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

202

4. Правильне керування світлофорами перехрестя, починаючи з ни-

жнього за схемою. Перед перемиканням чергового сигналу включати

жовте світло.

5. Послідовне включення і виключення червоного світла за годин-

никовою стрілкою на світлофорах, починаючи з молодшого номера.

6. Послідовне включення і виключення жовтого світла за годинни-

ковою стрілкою на світлофорах, починаючи з молодшого номера.

7. Послідовне включення і виключення червоного світла проти го-

динникової стрілки на світлофорах, починаючи з молодшого номера.

8. Послідовне включення і виключення жовтого світла проти годин-

никової стрілки на світлофорах, починаючи з молодшого номера.

9. Послідовне включення і виключення зеленого світла проти го-

динникової стрілки на світлофорах, починаючи з молодшого номера.

10. Одночасне включення всіх однакових сигналів світлофорів, по-

чинаючи із зеленого, за годинниковою стрілкою.

11. Одночасне включення всіх однакових сигналів світлофорів, по-

чинаючи з червоного, за годинниковою стрілкою.

12. Одночасне включення всіх однакових сигналів світлофорів, по-

чинаючи з жовтого, за годинниковою стрілкою.

13. Одночасне включення всіх однакових сигналів світлофорів, по-

чинаючи із зеленого проти годинникової стрілки.

14. Одночасне включення всіх однакових сигналів світлофорів, по-

чинаючи з червоного, проти годинникової стрілки.

15. Одночасне включення всіх однакових сигналів світлофорів, по-

чинаючи з жовтого, проти годинникової стрілки.

Накреслити алгоритм роботи та навести програму реалізації алго-

ритму.

6.6.2.2. Моделювання роботи терморегулятора

Для керування роботою терморегулятора в програмі-симуляторі

Sms32v23 використовується порт № 3. Схема підключення терморегуля-

тора наведена на рис. 6.18.

Програма роботи терморегулятора може мати такий вигляд:

a1: in 03 ; введення з порта 03

cmp al, 01 ; порівняння введеного числа з const 01

jnz on ; перехід на ввімкнення терморегулятора

Page 203: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

203

; вимикання терморегулятора

mov al, 00 ; al ← 00

out 03 ;

jmp a1 ;

; ввімкнення терморегулятора

on: mov al, 80 ; al ← 80

out 03 ;

jmp a1 ;

end

Вікно відображення терморегулятора у відладчику Emu8086 v.4.04

(для програми thermometer) наведено на рис. 6.19.

Завдання

1. Для програми-емулятора Sms32v23 накреслити алгоритм роботи

терморегулятора та відображення порога на семисегментних індикато-

рах та навести програму з відповідним коментарем.

2. Для налагоджувача Emu8086 v.4.04 накреслити алгоритм роботи

терморегулятора та навести програму з коментарем і порігом спрацю-

вання відповідно до номера навчаючого в журналі.

Рис. 6.18. Схема підключення тер-

морегулятора Рис. 6.19. Вікно відображення терморе-

гулятора в программі

Emu8086 v.4.04

Page 204: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

204

6.6.2.3. Моделювання процесу управління роботою мотора

Для керування роботою мотора у налагоджувача Emu8086 v.4.04

використовується порт № 7. Схема підключення мотора наведена на

рис. 6.20.

Приклад лістингу програми:

#start=stepper_motor.exe#

name "stepper"

#make_bin#

steps_before_direction_change = 20h ; 32 (decimal)

jmp start

; ========= data ===============

datcw db 0000_0110b

db 0000_0100b

db 0000_0011b

db 0000_0010b

datccw db 0000_0011b

db 0000_0001b

db 0000_0110b

db 0000_0010b

datcw_fs db 0000_0001b

Рис. 6.20. Схема підключення мотора

Page 205: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

205

db 0000_0011b

db 0000_0110b

db 0000_0000b

datccw_fs db 0000_0100b

db 0000_0110b

db 0000_0011b

db 0000_0000b

start:

mov bx, offset datcw ; start from clock-wise half-step.

mov si, 0

mov cx, 0 ; step counter

next_step:

; motor sets top bit when it’s ready to accept new command

wait: in al, 7

test al, 10000000b

jz wait

mov al, [bx][si]

out 7, al

inc si

cmp si, 4

jb next_step

mov si, 0

inc cx

cmp cx, steps_before_direction_change

jb next_step

mov cx, 0

add bx, 4 ; next bin data

cmp bx, offset datccw_fs

jbe next_step

mov bx, offset datcw ; return to clock-wise half-step.

jmp next_step

Завдання

1. Автоматична робота (в циклі) двигуна проти годинникової стріл-

ки з запалюванням послідовно по одній лампочці.

Page 206: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

206

2. Автоматична робота (в циклі) двигуна проти годинникової стріл-

ки з запалюванням послідовно двох лампочок.

3. Автоматична робота (в циклі) двигуна за годинниковою стрілкою

з запалюванням послідовно по одній лампочці.

4. Автоматична робота (в циклі) двигуна за годинниковою стрілкою

з запалюванням послідовно двох лампочок.

5. Автоматична робота (в циклі) двигуна проти годинникової стріл-

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

стрілкою чотирьох лампочок.

6.6.2.4. Моделювання процесу керування роботою ліфта

Схема підключення ліфта в програмі-симуляторі Sms32v23 та його

керування наведена на рис. 6.21.

Рис. 6.21. Схема підключення ліфта

та його керування

Page 207: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

207

Алгоритми керування ліфтом (вантажним), при якому стрілки інди-

кації включаються після вмикання (вимикання) двигуна, наведені на рис.

6.22 – 6.24.

Рис. 6.22. Алгоритм 1 керування вантажним ліфтом

Початок

Так Ні

Введення даних

AL ← 08

Біт[3] = 1

Ввімкнути двигун на підйом ліфта

AL ← 08

Введення даних

AL ← 04

Біт[2] = 1

Ввімкнути двигун на спуск ліфта

AL ← 08

1

2

3

4

5

6

7

8

9

10 Ні

Так 11

0

12

CL ← 16 CL ← 16

Рис. 6.23. Алгоритм 2 керування вантажним ліфтом

Початок

Так Ні

Введення даних

Біт[3] = 1

Ввімкнути двигун на підйом ліфта

Введення даних

Біт[2] = 1

Ввімкнути двигун на спуск ліфта

Ні Так

0

Page 208: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

208

Програма, яка наведена нижче, виконує циклічне піднімання та опу-

скання вантажного ліфта з використанням в CL часу для надійного під-

йому ліфта згідно з рис. 6.22:

M2: IN 06 ; (1)

MOV CL, 16 ; (2)

M5: AND AL, 08 ; (3)

JNZ M1 ; (4)

JMP M3 ; (4)

M1: MOV AL, 21 ; (5)

OUT 06 ; (5)

SUB CL, 01 ; (6)

JZ M2 ; (6)

JMP M1 ; (6)

M3: IN 06 ; (7)

Біт [3] = 1

Початок

Рис. 6.24. Алгоритм 3 та програма керування вантажним ліфтом

Так

Ні

Ввімкнути двигун на підйом ліфта

IN 06

AND AL,08

JNZ A1

JMP A2

A1: MOV AL,21

OUT 06

Біт [2] = 1

Ввімкнути двигун на спуск ліфта

A2: AND AL,04

JNZ A3

JMP A1

A3: MOV AL,12

OUT 06

Біт [3] = 1

IN 06

AND AL,08

JZ A3

JMP A2

END

Ні

Ні Так

Введення даних

Введення даних IN 06

Page 209: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

209

MOV CL, 16 ; (8)

AND AL, 04 ; (9)

JNZ M4 ; (10)

JMP M2 ; (10)

M4: MOV AL, 12 ; (11)

ОUT 06 ; (11)

SUB CL, 01 ; (12)

JNZ M4 ; (12)

JMP M2 ; (12)

END

Приклад лістингу програми згідно із алгоритмом 2:

M2: IN 06

AND AL,08

JNZ VERX

IN 06

AND AL,04

JNZ NIZ

JMP M2

NIZ: MOV AL,12

OUT 06

JMP M2

VERX: MOV AL,21

OUT 06

JMP M2

END

JMP M2

Завдання

Написати алгоритм та програму з коментарем керування пасажир-

ським ліфтом з аналізом світової індикації стрілок.

Page 210: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

210

7. ОРГАНІЗАЦІЯ ВИВЕДЕННЯ НА ЕКРАН

7.1. Виведення на екран символьної інформації

Програма виведення на екран символьної інформації наводиться в

прикладі 7.1.

Приклад 7.1. Виведення на екран інформаційного повідомлення.

text segment ; Початок сегмента команд

assume CS:text,DS:data

begin: mov AX,data ; Ініціалізація сегментного

mov DS,AX ; регістра DS

mov AH,9 ; Функція DOS виведення на екран

mov DX,offset message ; Адреса повідомлення, що виводиться

int 21h ; Виклик DOS

mov AX,4C00h ; Завершення програми

int 21h

text ends ; Кінець сегмента команд

data segment ; Початок сегмента даних

message db ‘Системне програмування. ‘

db ‘Основи мови асемблеру та його використання.$’

data ends ; Кінець сегмента даних

stack segment stack ; Початок сегмента стека

dw 128 dup (0) ; Стек

stack ends ; Кінець сегмента стека

end begin ; Кінець тексту програми

Відзначимо, що ця програма написана стандартним чином: у ній є

сегменти команд, даних і стека.

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 211: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

211

Текст, призначений для виведення на екран, включений з програму

в допомогою директиви db (визначити байт). У кінець тексту включений

знак “$”, що характеризує кінець рядка для функції DOS 09h.

Весь текст виведений на екран суцільною послідовністю символів

без розбиття на рядки і абзаци. Неприємно також і те, що текст виведе-

ний на “брудний” екран із залишками попередніх виведень. Тому в сим-

вольний рядок слід включити коди керування курсором:

9 – табуляція;

10 – переклад рядка;

13 – “повернення каретки”, тобто повернення курсора в початок

рядка екрана.

Для очищення екрана треба вивести на нього стільки рядків пропу-

сків, щоб, переміщаючись у міру виведення вгору по екрану, вони очис-

тили всю його верхню частину.

В прикладі 7.2 наведено опис модифікованого рядка message (вся

решта речень програми не змінюється).

Приклад 7.2. Виведення на екран форматованого тексту.

message db 80*18 dup (‘ ‘)

db 9,’ Системне програмування.’,10,13,’ Основи мови асемблера та

його використання.’’$’

Пропуски (18 рядків по 80 пропусків у рядку) описані за допомогою

оператора dup (duplicate, дублювати). Перед словом dup указується кое-

фіцієнт повторення, в якому можна використовувати арифметичні вира-

зи, а після оператора dup в дужках – повторюваний рядок, що складаєть-

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

червоних рядків. Для того щоб текст виглядав на екрані акуратно, в се-

редину першого абзацу включають коди 10 і 13 переходів на наступний

рядок.

Окрім звичайних алфавітно-цифрових символів і інших знаків, що є

на клавіатурі комп’ютера (наприклад, знаків <, >, [, ],{,}, I та ін.) на ек-

ран можна виводити символи псевдографіки. Таких символів усього 48;

їм відповідають коди від 176 до 223. Так, наприклад, для формування на

екрані подвійної рамки використовують наступні коди:

║ - 186 ╖ – 187 ╜ – 188 ╙ – 200 ╓ – 201 ═ – 205

Коли в рядок, що виводиться на екран, включити код 7, прозвучить

короткий звуковий сигнал.

Page 212: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

212

У прикладі 7.3 наведений символьний рядок, виведення якого за

допомогою функції 09h DOS приведе до зображення приблизно в центрі

чистого екрана рамки зі словом “Achtung!”, супроводжуваним звуковим

сигналом.

Приклад 7.3. Виведення на екран інформаційного кадру.

text segment ; Початок сегмента команд

assume CS:text,DS:data

begin: mov AX,data ; Ініціалізація сегментного

mov DS,AX ; регістра DS

mov AH,9 ; Функція DOS виведення на екран

mov DX,offset message ; Адреса повідомлення, що виводиться

int 21h ; Виклик DOS

mov AX,4C00h ; Завершення програми

int 21h

text ends ;

data segment ;

message db 2 dup (7)

db 80*1 dup (‘ ‘)

db 35 dup (‘ ‘),201,9 dup (205),187,10,13

db 35 dup’ (‘ ‘),186, Achtung!’,186,10,13

db 35 dup (‘ ‘),200,9 dup (205),188,10,13

db 10*80 dup’ (‘ ‘),’$

data ends ; Кінець сегмента даних

stack segment stack ; Початок сегмента стека

dw 128 dup(0) ; Стек

stack ends ; Кінець сегмента стека

end begin ; Кінець тексту програми

Інформаційний кадр прикладу 7.3 після виконання програми в

debug буде наведений у вигляді, зображеним на рис. 7.1

Рис. 7.1. Вікно програми debug після виконання програми прикладу 7.3

Page 213: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

213

У наведених вище прикладах деякі символи вводилися в програму у

вигляді їх зображень (букв), а інші – за допомогою їх кодів. Насправді

всі символи, що відображаються на екрані терміналу або виводяться на

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

Кожен код ASCII займає один байт і може приймати значення від 0 до

255. Сукупність всіх 255 кодів разом із зображеннями символів склада-

ють кодову таблицю ASCII.

Перша половина таблиці ASCII – стандартна, вона містить коди

цифр, розділового, латинських рядкових і прописних літер знаків. На

початку таблиці розміщені коди спеціальних піктограм (зображення пі-

ки, гральних карт, ноток та ін.). Деякі з цих кодів при виведенні за допо-

могою функцій DOS сприймаються, як керівники. Так, код 9 відобража-

ється у вигляді жирного кружка, але функціями DOS інтерпретується як

код табуляції. Код 13 представляє зображення нотки, а програмами DOS

сприймається, як повернення каретки.

Друга половина таблиці ACSII є “національно-залежною”, її коди

відповідають в основному знакам національного алфавіту і символам

псевдографіки. У звичайно використовуваному різновиді кодової табли-

ці символи псевдографіки розташовані так само, як і в початковій аме-

риканській таблиці. Тому програми, що виводять на екран (або на друк)

псевдографічні зображення, працюють однаково як за наявності русифі-

катора, так і без нього.

Транслятор, зустрівшись у тексті програми з символьним рядком,

який повинен бути виведений на екран, перетворить зображення симво-

лів у цьому рядку у відповідні їм коди ASCII. При виконанні програми

коди ASCII посилаються на термінал, який перетворить їх назад в зо-

браження символів. Якщо ж в рядку, що виводиться на термінал, вказані

не символи (у апострофах), а їх числові коди, то транслятор залишає їх в

програмі без зміни. При посиланні на термінал вони сприйматимуться як

коди ASCII і приведуть до того ж результату. Таким чином, пропозиції

string db ‘ABCD’

string db 65,66,67,68

абсолютно еквівалентні, враховуючи, що код ASCII прописної латинсь-

кої літери А дорівнює 65, код букви В – 66 і т.д.

Очевидно, що описувати в програмі текстові рядки за допомогою

кодів ASCII щонайменше незручно. В той же час для виведення на екран

псевдографічних зображень або інших піктограм, для яких немає відпо-

Page 214: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

214

відних клавіш, доводиться користуватися кодами ASCII. Проте мати на

увазі відповідність символів і кодів ASCII доводиться досить часто. На-

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

фактично виконується за кодами ASCII.

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

в якій створюється і виводиться на екран тестовий символьний масив,

заповнений кодами алфавітно-цифрових і псевдографічних символів. Ці

символи мають коди від 32 (пропуск) до 254 (суцільний квадратик). Та-

кий масив можна створити вручну в полях даних програми за допомо-

гою оператора db:

symbols db 32,33,34,35,36,37,38,39...

проте простіше заповнити його даними програмним чином.

Приклад 7.4. Виведення символьного масиву, заповненого кодами

алфавітно-цифрових і псевдографічних символів.

text segment ; (1) Початок сегмента команд

assume CS:text, DS:data ; (2)

begin: mov AX,data ; (3) Ініціалізація сегментного

mov DS,AX ; (4) регістра DS

; Підготуємо все необхідне для організації циклу

mov CX,223 ; (5) Число кроків у циклі

mov SI,0 ; (6) Індекс елемента, що адресується, в масиві

mov AL,32 ; (7) Код першого символу - пропуску

; Цикл, в який входить 4 команди

fill: mov symbols[SI],AL ; (8) Занесення чергового коду в байт

; масиву з індексом SI

inc AL ; (9) Створимо код наступного символу

inc SI ; (10) Зрушимося в масиві на 1 байт

loop fill ; (11) Команда циклу з СХ кроків

; Виведемо для контролю одержаний символьний масив на екран

mov AH,40h ; (12) Функція DOS висновку

mov BX,1 ; (13) Стандартний дескриптор екрана

mov CX,223 ; (14) Число байтів, що виводяться

mov DX,offset symbols ; (15) Адреса повідомлення, що виводиться

int 21h ; (16) Виклик DOS

; Завершимо програму

mov AX,4C00h ; (17)

int 21h ; (18)

Page 215: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

215

text ends ; (19) Кінець сегмента команд

data segment ; (20) Початок сегмента даних

; Поля даних програми

symbols db 223 dup (‘*’) ; (21) Заповнюваний масив

data ends ; (22) Кінець сегмента даних

stack segment stack ; (23) Початок сегмента стека

dw 128 dup (0) ; (24) Стек

stack ends ; (25) Кінець сегмента стека

end begin ; (26) Кінець тексту програми

Результат роботи програми прикладу 7.4 наведено на рис. 7.2

Розглянемо змістовну частину програми. Лічильником кроків циклу

служить регістр СХ. Тому в регістр СХ треба занести необхідне число

кроків циклу (речення 5), що дорівнює довжині заповнюваного масиву.

Робота з масивом здійснюється, як правило, за допомогою одного з ін-

дексних регістрів (SI або DI), в яких зберігається і нарощується індекс

елемента масиву, що адресується, тобто номер байта масиву, до якого

здійснюється звернення в даному кроці циклу. Оскільки починаємо об-

робляти масив із самого початку, в реченні 6 в регістр SI заноситься 0.

Регістр AL вибраний для зберігання поточного коду символу, що відпра-

вляється в масив. З таким же успіхом цю роль міг би виконати будь-який

інший байтовий регістр АН, BL, BH, DL або DH (регістри CL і СН, що

входять до складу регістра СХ, вже зайняті). У реченні 7 в регістр AL

заноситься код першого символу – пропуску. Підготувавши всі необхідні

регістри, можна скласти саме тіло циклу. У реченні 8 код з AL відправ-

ляється в елемент (байт) масиву symbols, номер якого визначається вміс-

том індексного регістра SI. Це так звана індексна адресація, у якої існує

декілька різновидів. Зокрема, як індексний регістр з тим же успіхом мо-

жна було використовувати регістри ВХ або DI. У першому кроці циклу

Рис. 7.2. Вікно результату роботи програми прикладу 7.4

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 216: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

216

заповниться елемент масиву з індексом 0. У наступних двох реченнях

виконується інкремент (збільшення на 1) коду чергового символу і інде-

ксу в масиві. Нарешті, команда loop (петля, речення 11) повертає керу-

вання на мітку fill. Причому робить це рівно 223 рази, відповідно до по-

чаткового вмісту регістра СХ.

Для виведення результатів роботи програми не можна скористатися

функцією 09h, тому що десь в масиві міститиметься код знаку $, а він не

може бути виведений на екран функцією 09h. Тому для виведення ско-

ристаємося іншою функцією DOS з номером 40h, яка дозволяє виводити

інформацію у файли і на пристрої, зокрема на екран. Приймач інформа-

ції визначається числом, що заноситься в регістр ВХ, і так званим де-

скриптором (або файловим індексом). На етапі ініціалізації DOS екрана

привласнюється дескриптор 1, який носить спеціальну назву “дескрип-

тор стандартного виведення”. Окрім дескриптора, функція 40h вимагає,

щоб в регістрі СХ знаходилося число байтів, що виводяться, а в регістрі

DX (точніше, в парі регістрів DS:DX) – адреса інформації, що виводиться

(див. рядки 14 і 15). Нарешті, команда int 21h передає керування DOS,

яка і виконує операцію, що зажадалася.

У полях даних програми оголошений масив байтів (оператор db),

який ініціалізовано кодами символу “*”. Це дуже зручний і поширений

прийом, який полегшує налагодження програми. Якщо через якісь поми-

лки в програмі масив буде заповнений не весь або не заповнений взагалі,

на екран будуть виведені зірочки. Якщо ж програма працює правильно,

початкові зірочки зітруться.

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

даних (речення 8, де заповнюється масив з ім’ям symbols).

Адреса будь-якого елементу пам’яті обов’язково має два компонен-

ти: сегментну адресу, що зберігається в одному з сегментних регістрів, і

відносну адреса, або зсув, який може вказуватися в команді у вигляді

мнемонічного позначення осередку. В реченні 8 є посилання на комірку

symbols, тобто указується зсув. Якщо в команді не вказаний в явній фор-

мі сегментний регістр, за умовчанням використовується регістр DS. Вла-

сне, саме з цим припущенням на початку програми ініціалізували регістр

DS адресою сегмента даних, в якому розташований масив symbols. Про-

те, для того щоб вказане умовчання діяло, необхідно за допомогою опе-

ратора assume зіставити сегментний регістр DS саме з цим сегментом.

Таким чином, визначення DS:data в операторі assume дійсно стало необ-

Page 217: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

217

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

нього.

7.2. Виведення на екран графічних зображень

7.2.1. Виведення на екран простих графічних зображень

Для здійснення введення з клавіатури і виведення на екран симво-

льної інформації доводиться вдаватися до функцій DOS. DOS не підтри-

мує ні позиціонування курсору, ні зміни кольору символів. Для виведен-

ня на екран графічного зображення, необхідно скористатися нижнім рів-

нем операційної системи – базовою системою введення-виведення (Basic

In-Out System, BIOS). Програми BIOS знаходяться в постійному за-

пам’ятовуючому пристрої (ПЗП) BIOS. На відміну від DOS, до всіх фун-

кцій якої звертаються за допомогою переривання 21h, в BIOS за кожним

пристроєм комп’ютера закріплено своє переривання. Так, програмуван-

ня диска здійснюється за допомогою переривання int 13, клавіатури – int

16h, екрана – int 10h. Переривання int 10h забезпечує всі функції відеоа-

даптера: зміну відеорежиму, виведення символьної і текстової інформа-

ції, зміну шрифтів, налагодження колірної палітри, роботу з графічним

зображенням і т.д. Скористаємося перериванням int 10h для переходу в

графічний режим і виведення простого графічного зображення.

Приклад 7.5. Виведення на екран горизонтальної прямої.

.model small ; Коди та дані займають ≤ 64 кбайт

.data ; Початок сегмента даних

dw 128 dup (0)

.code ; Початок сегмента-даних

; Встановимо графічний режим EGA

begin: mov АН,00h ; (1) Функція завдання режиму

mov AL,10h ; (2) Графічний режим EGA

int 10h ; (3) Виклик BIOS

; Нарисуємо пряму лінію в циклі по X

mov SI,150 ; (4) Початкова Х-координата

mov CX,300 ; (5) Число точок по горизонталі

line: push CX ; (б) Збережемо його в стеку

mov АН,0Сh ; (7) Функція виведення пікселя

mov AL,4 ; (8) Колір червоний

Page 218: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

218

mov BH,0h ; (9) Відеосторінка

mov CX,SI ; (10) Х-координата (змінна)

mov DX,175 ; (11) Y-координата (константа)

int 10h ; (12) Виклик BIOS

inc SI ; (13) Інкремент X-координати

pop CX ; (14 ) Відновимо лічильник кроків

loop line ; (15) Цикл з CX кроків

; Зупинимо програму для спостереження результату її роботи

mov АН,08h ; (16) Функція введення з клавіатури без луни

int 21h ; (17) Виклик DOS

; Перемкнемо відеоадаптер назад в текстовий режим

mov АН,00h ; (18) Функція завдання режиму

mov AL,03h ; (19) Текстовий режим

int 10h ; (20) Виклик BIOS

stack segment stack

dw 128 dup (0)

stack ends

end begin

У реченнях 1...3 за допомогою функції 00h переривання BIOS 10h

здійснюється перемикання відеоадаптера в графічний режим. Оскільки

номер режиму заноситься в байтовий регістр AL, всього може існувати

256 різних текстових і графічних режимів, з яких на сьогодні використо-

вуються (апаратурою різних фірм) близько ста. Режим 10h забезпечує

виведення графічного зображення 16 кольорами з дозволом 640 350

точок і широко використовується з відеоадаптерами EGA і VGA.

Зображення рисується по точках (у BIOS не передбачено програм-

них засобів виведення яких-небудь геометричних фігур або ліній, як не-

має і засобів зафарбування областей екрану). Для виведення на екран

кольорової точки (піксела) використовується функція 0С переривання

10h. Ця функція вимагає занесення в регістр AL коду кольору, у ВН –

номерів відеосторінки, в СХ – Х-координати точки, що виводиться, в

діапазоні 0...349, а в DX – Y-координати точки в діапазоні 0...639. Оскі-

льки регістр СХ використовується, як лічильник кроків в циклі, для збе-

рігання Х-координати зарезервований регістр SI.

Пряма горизонтальна лінія в прикладі 6.5 рисується шляхом викли-

ку функції 0Сh в циклі, в кожному кроці якого значення Y-координати

залишається незмінним (175 в прикладі), а значення Х-координати збі-

Page 219: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

219

льшується на 1 (речення 13). Після завершення циклу формування зо-

браження в програмі передбачена зупинка (речення 16 – 17) для того,

щоб користувач міг, залишаючись у графічному режимі, проаналізувати

результати роботи програми. Для зупинки програми використовується

функція DOS 08h введення одного символу з клавіатури. Функція 08h не

відображає введений символ на екрані і тим самим не спотворює графіч-

не зображення. Натиснення будь-якої клавіші (окрім керівних – Ctrl, Alt,

Shift і ін.) відновлює виконання програми.

В кінці даного фрагмента передбачено перемикання відеоадаптера

в стандартний текстовий режим з номером 03h (речення 18...20). Якщо

таке перемикання не виконати, відеоадаптер залишиться в графічному

режимі, що може перешкодити правильному виконанню прикладних

програм.

Розглянемо стисло параметри виклику функції 0Сh переривання

10h. У регістр ВН заноситься номер відеосторінки, на яку виводиться

дана точка. Графічний адаптер EGA забезпечує зберігання і відображен-

ня двох графічних сторінок. За умовчанням видимою (активною) ро-

биться сторінка 0, проте рисувати зображення можна як на видимій, так і

на невидимій сторінці. Для перемикання сторінок передбачена функція

05h переривання 10h.

У регістр AL заноситься код кольору точки. Адаптер підтримує 64

кольори, хоча в кожен момент часу зображення на екрані може містити

тільки 16 кольорів. Цей набір з 16 кольорів, що виводяться на екран (ко-

лірна палітра), задається програмно і може легко змінюватися. При зава-

нтаженні машини встановлюється стандартна палітра, коди кольорів якої

наведені в табл. 7.1.

Таблиця 7.1

Коди кольорів стандартної колірної палітри EGA

Код Колір Код Колір

0 0h Чорний 8 8h Сірий

1 1h Синій 9 9h Блакитний

2 2h Зелений 10 Ah Салатовий

3 3h Бірюзовий 11 Bh Ясно-бірюзовий

4 4h Червоний 12 Ch Рожевий

5 5h Фіолетовий 13 Dh Ясно-фіолетовий

6 6h Коричневий 14 Eh Жовтий

7 7h Білий 15 Fh Яскраво-білий

Page 220: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

220

7.2.2. Підпрограми та їх використання при відображенні графічної

інформації

Істотного спрощення структури програми можна досягти, викорис-

товуючи в ній підпрограми.

Модифікуємо програму з прикладу 7.5, розбивши її на процедури і

організувавши в циклі звернення до підпрограми з передачею їй параме-

трів.

Приклад 7.6. Виведення на екран горизонтальної прямої за допо-

могою підпрограми.

text segment ‘code’ ; (1) Початок сегмента команд

assume CS:text, DS:data ; (2)

; Підпрограма виведення однієї точки. Параметри при виклику знахо-

дяться

; в елементах пам’яті:

; color – колір точки, vpage – відеосторінка, х, у – координати

draw ргос ; (3) Оголошення процедури-підпрограми

mov AH,0Ch ; (4) Функція виведення пікселя

mov AL,color ; (5) Колір

mov BH,vpage ; (6) Відеосторінка

mov CX,x ; (7) Х-координата

mov DX,y ; (8) У-коордіната

int 10h ; (9) Виклик BIOS

ret ; (10) Команда виходу з підпрограми

draw endp ; (11) Кінець процедури

; Головна процедура, на яку передається керування

; після завантаження програми

main ргос ; (12) Оголошення головної процедури

mov AX,data ; (13) Ініціалізація сегментного

mov DS,AX ; (14) регістра DS

; Встановимо графічний режим EGA

mov AH,00h ; (15) Функція задання режиму

mov AL,10h ; (16) Графічний режим EGA

int 10h ; (17) Виклик BIOS

; Нарисуємо горизонтальну лінію в циклі по X

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 221: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

221

mov СХ,300 ; (18) Число точок по горизонталі

line: push CX ; (19) Збережемо його в стеку

call draw ; (20) Виклик підпрограми

inc x ; 21) Інкремент Х-координати

pop CX ; (22) Відновимо лічильник кроків

loop line ; (23) Цикл з СХ кроків

; Зупинимо програму для спостереження результату її роботи

mov AH,08h ; (24) Функція введення з клавіатури

int 10h ; (25) Виклик DOS

; Перемкнемо відеоадаптер назад в текстовий режим

mov АН,00h ; (26) Функція завдання режиму

mov AL,03h ; (27) Текстовий режим

int 10h ; (28) Виклик BIOS

mov AX,4C00h ; (29) Завершення програми

int 21h ; (30)

main endp ; (31) Кінець головної процедури

text ends ; (32) Кінець сегмента команд

data segment ;( 33) Початок сегмента даних

x dw 150 ; (34) Поточна Х-координата

у dw 175 ; (35) Поточна Y-координата

color db 14 ; (36) Колір точок

vpage db 0 ; (37) Відеосторінка

data ends ; (38) Кінець сегмента даних

stack segment stack ; (39) Початок сегмента стека

dw 128 dup (0) (40) Стек

stack ends (41) Кінець сегмента стека

end main ; (42) Кінець тексту програми

Програма складається з двох процедур: головної з ім’ям main і про-

цедури-підпрограми з ім’ям draw. Кожна процедура починається опера-

тором ргос, перед яким указується ім’я процедури, а закінчується опера-

тором endp (end procedure, кінець процедури – пари речень 3...11 і

12...31). Порядок процедур в програмі в більшості випадку не має зна-

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

програми, повинно бути вказано як операнд директиви end (речення 42).

Підпрограми викликаються оператором call (виклик); кожна підп-

рограма повинна закінчуватися командою ret (return, повернення), яка

Page 222: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

222

передає керування в точку повернення, тобто на команду програми, на-

ступну за командою call.

Підпрограма draw виводить на екран одну точку. Як вхідні параме-

три вона повинна одержати дві координати точки, її колір, а також номер

відеосторінки, на яку виводиться зображення.

Параметри підпрограмі параметри можна передати через регістри

загального призначення, стек або елементи пам’яті. У прикладі 7.7 вико-

ристовується останній спосіб, не найшвидший, але найбільш наочніший.

Для зберігання і модифікації параметрів в сегменті даних передбачені

осередки х, у, color і vpage. У даному прикладі виведення горизонтальної

лінії в трьох комірках зберігаються константи і лише комірка x модифі-

кується.

При використанні підпрограми основний цикл спрощується. Фак-

тично в ньому лише два змістовні рядки: виклик підпрограми draw і ін-

кремент Х-координати в комірку х. Проте збереження в стеку і віднов-

лення регістра СХ є обов’язковим, тому що він використовується в підп-

рограмі для задання Х-координати.

Виділивши виведення точки в підпрограму і істотно спростивши

цикл основної програми, можна полегшити завдання її модифікації. У

прикладі 7.7 показано, як можна на додаток до горизонтальної вивести

на екран вертикальну та похилу лінії.

Приклад 7.7. Виведення на екран пучка ліній.

text segment ‘code’ ; Початок сегмента команд

assume CS:text, DS:data ;

draw proc ; Оголошення процедури-підпрограми

mov AH,0Ch ; Функція виведення пікселя

mov AL,color ; Колір

mov BH,vpage ; Відеосторінка

mov CX,x ; Х-координата

mov DX,y ; У-коордіната

int 10h ; Виклик BIOS

ret ; Команда виходу з підпрограми

draw endp ; Кінець процедури

; Головна процедура, на яку передається керування

main proc ;

mov AX,data ; Ініціалізація сегментного

mov DS,AX ; регістра DS

Page 223: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

223

; Встановимо графічний режим EGA

mov AH,00h ; Функція задання режиму

mov AL,10h ; Графічний режим EGA

int 10h ; Виклик BIOS

; Рисуємо горизонтальну лінію, що йде з початку координат

mov CX,300 ; (1) Число точок по горизонталі

line: push CX ; (2) Збережемо його в стеку

call draw ; (3) Виклик підпрограми

inc x ; (4) Інкремент Х-координати

pop CX ; (5) Відновимо лічильник кроків

loop line ;( 6) Цикл з СХ кроків

; Рисуємо похилу лінію

mov x,0 ; (7) Відновимо початкове значення X

mov CX,150 ; (8) Число точок

line1: push CX ; (9) Збережемо його в стеку

push x ; (10) Відправимо значення X

pop у ; (11) в комірку Y

call draw ; (12) Виклик підпрограми

inc x ; (13) Інкремент Х-координати

pop CX ; (14) Відновимо лічильник кроків

loop line1 ; (15) Цикл з СХ кроків

mov cx,300 ; (16) Число точок по горизонталі

; Рисуємо вертикальну лінію

mov x,0 ; (17) Відновимо початкове значення X

mov у,0 ; (18) Відновимо початкове значення Y

mov CX,150 ; (19) Число точок

line2: push CX ; (20) Збережемо його в стеку

call draw ; (21) Виклик підпрограми

inc у ; (22) Інкремент Y-координати

pop CX ; (23) Відновимо лічильник кроків

loop line2 ; (24) Цикл з СХ кроків

; Зупинимо програму для спостереження результату її роботи

mov AH,08h ; Функція введення з клавіатури

int 21h ; Виклик DOS

; Перемкнемо відеоадаптер назад в текстовий режим

mov AH,00h ; Функція задання режиму

mov AL,03h ; Текстовий режим

int 10h ; Виклик BIOS

Page 224: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

224

mov AX,4C00h ; Завершення програми

int 21h ;

main endp ; Кінець головної процедури

text ends ; Кінець сегмента команд

data segment ; Початок сегмента даних

x dw 0 ; Поточна Х-координата

у dw 0 ; Поточна Y-координата

color db 14 ; Колір точок

vpage db 0 ; Відеосторінка

data ends ; Кінець сегмента даних

stack segment stack ; Початок сегмента стека

dw 128 dup (0) ; Стек

stack ends ; Кінець сегмента стека

end main ; Кінець тексту програми

У полях даних програм є 4 комірки з параметрами підпрограми. Дві

з них (color і vpage) описані за допомогою директиви db (визначити

байт); для двох інших (х і у) використана директива dw (define word, ви-

значити слово). Чому директиви різні? Справа в тому, що числа з комі-

рок color і vpage по ходу виконання програми завантажуються в байтові

регістри AL і ВН; числа з комірок х і у завантажуються в 16-розрядні

(листкові) регістри СХ і DX. Дані, наведені в програмі, повинні брати

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

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

Тому при визначенні даних слід наперед подумати, в які регістри ці дані

завантажуватимуться.

У реченнях 10 – 11 прикладу 6.7 вміст комірки х копіюється в комі-

рку у через стек. Взагалі кажучи, тут треба було б виконати команду mov

у,x. Проте в мікропроцесорах 80x86 заборонена операція безпосередньої

пересилання операндів з одного елемента пам’яті в інший. Таке переси-

лання можна здійснити тільки за допомогою проміжного регістра

mov AX,x

mov у, АХ

або через стек (можна було б також скористатися командою пересилання

рядків movs, але це набагато складніше).

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

жих за структурою циклів. Початкові точки цих циклів позначені схо-

Page 225: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

225

жими: line, linel, Iine2. У початковому тексті програми не повинно бути

декількох однакових міток або імен елементів пам’яті (навіть якщо вони

відносяться до різних процедур або програмних сегментів).

7.3. Виведення на екран тексту засобами BIOS

Для виведення на екран символьної (текстової) інформації існують

різні способи. Для цього можна скористатися функціями DOS, напри-

клад, функцією 09h, яка виводить текст до знака “$”, або функцією 40h,

для якої задається довжина рядка (або декількох рядків). Проте можли-

вості DOS обмежені: DOS не має функцій для зміни кольору символів,

що виводяться, і позиціонування курсора. Тому текст, що виводиться

засобами DOS, є суцільною послідовністю чорно-білих рядків, які

з’являються друг за. другом з нижнього краю екрана. Крім того, за до-

помогою DOS можна виводити не всі символи кодової таблиці.

Для виведення кольорових інформаційних кадрів можна скориста-

тися розширенням системного драйвера консолі – встановлюваним

драйвером ANSI.SYS. Включення в рядки ESC-послідовностей, що ви-

водяться на екран, дозволяє очищати екран, змінювати колір символів,

позиціонувати курсор і виконувати інші дії. При цьому необхідно мати

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

Esc-послідовності, за відсутності в системі драйвера ANSI.SYS працюва-

тимуть неправильно.

Всі можливості відеосистеми комп’ютера можна реалізувати за до-

помогою функцій переривання 10h BIOS. Програмування за допомогою

засобів BIOS громіздке, проте великі можливості і висока (у порівнянні з

функціями DOS) швидкість виведення обумовлюють широке викорис-

тання цього методу в прикладних програмах.

Засоби DOS починають функціонувати тільки після повного заван-

таження операційної системи, а засоби BIOS, записані в ПЗП, можна

використовувати навіть в умовах відсутності або непрацездатності DOS.

У BIOS є цілий ряд функцій для обслуговування текстового режиму.

Атрибут символу займає один байт і визначає колір символу і фону під

ним, а також деякі додаткові характеристики зображення на екрані.

Структура байта атрибутів наведена на рис. 7.3.

Page 226: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

226

Рис. 7.3. Байт відеоатрибута:

R – входження червоного кольору :0 – не входить; 1– входить;

G – входження зеленого кольору: 0 – не входить; 1 – входить;

В – входження синього кольору :0 – не входить; 1– входить;

I – інтенсивність: 0 – символ неяскравий; 1 – символ яскравий;

М – мерехтіння: 0 – символ не мерехтить; 1 – символ мерехтить.

* – можливий режим, коли цей біт буде визначати не миготіння

символу, а інтенсивність кольору фону.

Як колір символу, так і колір фону визначаються як сума трьох

основних кольорів – червоного, зеленого і синього. Усі можливі кольори

наведені в табл. 7.2.

Таблиця 7.2

Кольори символів і фона

Для відображення коду символу Д (кирилиця) необхідно за табли-

цею ASCII кодів знайти необхідний код, та перевести його в шістнадцят-

кову систему числення (код 84Н) (табл. 5 – 8). У таблиці атрибутів роз-

ставимо одинички в ті біти кольорів фону і символу, які хочемо відобра-

зити на моніторі. Переведення коду з двійкової системи числення в

шістнадцяткову здійснюється потетрадно. Наприклад, код атрибута, що

дорівнює 41Н, позначає, що символ відображається синім кольором на

червоному фоні.

M R G B I R G B

* Колір фону Колір символу

I R G B Колір

0

0

0

0

0

0

0

0

1

1

0

0

0

0

1

1

1

1

0

0

0

0

1

1

0

0

1

1

0

0

0

1

0

1

0

1

0

1

0

1

Чорний

Синій

Зелений

Голубий

Червоний

Рожевий

Коричневий

Сірий

Темно-сірий

Яскраво-синій

Page 227: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

227

Якщо відеоадаптер поставлений в режим мерехтіння символів, то

фон може приймати тільки 8 кольорів, відповідних лівій половині наве-

деної вище таблиці. Для перемикання призначення біта 7

передбачена підфункція 03h функції 10h драйвера BIOS (переривання Int

10h). При включенні комп’ютера встановлюється режим керування ме-

рехтінням.

Приклад 7.8. Виведення на екран кольорового вікна:

.model small ; коди та дані займають <= 64 кбайт

.data ; початок сегмента даних

dw 128 dup (0)

.code

begin:

mov AH,06h

mov AL,0

mov BH,1Eh

mov CH,5

mov CL,10

mov DH,9

mov DL,75

int 10h

mov ах,4c00h

int 21h

end begin

Результат роботи програми прикладу 7.8 наведено на рис. 7.4.

Приклад 7.9. Виведення на екран символьної інформації засобами

BIOS:

.model small ; коди та дані займають <= 64 кбайт

.data ; початок сегмента даних

; Поля даних

mesl db 16, ‘Рядок, виведений у вікно’,17

lenl=$-mesl

mes2 db 22,22,22, ‘Рядок, виведений поза вікна’,22,22,22

1en2=$-mes2

.code ; початок сегмента команд

; Очистимо екран, наклавши на нього чорно-біле вікно

begin: mov AH,06h ; Функція задання вікна

Page 228: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

228

mov AL,0 ; Режим створення (не прокручування)

mov BH,07h ; Атрибут всіх символів у вікні – ч/б

mov CH,0 ; Верхня Y-координата

mov CL,0 ; Ліва Х-координата

mov DН,24 ; Нижня Y-координата

mov DL,79 ; Права Х-координата

int 10h ; Переривання BIOS

; Нарисуємо на екрані невелике кольорове вікно

mov AH,06h ; Функція задання вікна

mov AL,0 ; Режим створення (не прокручування)

mov BH,1Eh ; Атрибут жовтий по синьому

mov СН,5 ; Верхня Y-координата

mov CL,40 ; Ліва Х-координата

mov DH,9 ; Нижня Y-координата

mov DL,75 ; Права Х-координата

int 10h ; Переривання BIOS

; Позиціонуємо курсор

mov AH,02h ; Функція позиціонування

mov BH,0 ; Видеосторінка

mov DН,7 ; Рядок

mov DL,45 ;Стовпчик

int 10h ; Переривання BIOS

; Виведемо у вікно рядок символів без задання атрибутів

; (тобто з атрибутами вікна)

mov CX,len1 ; Довжина рядка

mov BX,offset mesl ; Адреса рядка символів

mov AH,0Eh ; Функція виведення одного символу

wr: mov AL[BX] ; Символ у AL

inc BX ; Зсув по рядку

int 10h ; Переривання BIOS

loop wr ; Цикл по рядку

; Виведемо рядок поза вікном, задавши атрибути символів

mov AH,13h ; Функція виведення рядка

mov AL,0 ; Режим (атрибут у BL)

mov BH,0 ; Відеосторінка

mov BL,04h ; Атрибут всіх символів

mov CX,len2 ; Довжина рядка

mov DН,16 ; Початкова позиція – рядок

Page 229: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

229

mov DL,25 ; Початкова позиція – стовпчик

push DS ; Задання

pop ES ; ES на наш сегмент даних

mov BP,offset mes2 ; ES:BP рядок

int 10h ; Переривання BIOS

; Позиціонуємо курсор в початок останнього рядка екрана

mov AH,02h ; Функція позиціонування

mov BH,0 ; Видеосторінка

mov DН,24 ; Рядок

mov DL,0 ; Стовпчик

int 10h ; Переривання BIOS

mov ах,4c00h

int 21h

stack segment stack

dw 128 dup (0)

stack ends

end begin

У прикладі 7.9 показане використання деяких найбільш споживаних

функцій BIOS для роботи з екраном (переривання 10h).

Стисло опишемо можливості функцій BIOS, використаних в наве-

деній програмі.

За допомогою функції 06h у заданому місці екрана дисплея створю-

ється кольорове прямокутне вікно заданого розміру. Якщо в створеному

раніше вікні виведений який-небудь текст, то за допомогою цієї ж функ-

ції текст можна прокручувати вгору (функція 07h дозволяє прокручувати

колір вниз). При цьому текст, що йде за край вікна, пропадає, а з-під

протилежного краю з’являються порожні рядки із заданими атрибутами.

Для заповнення рядків, що з’являються, текстом слід використовувати

відповідні функції BIOS.

Функція 02h дозволяє позиціонувати текстовий курсор, задаючи йо-

Рис. 7.4. Результат роботи програми прикладу 7.8

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 230: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

230

го місцерозташування у вигляді номера рядка (0...24) і номера стовпчика

(0...79). Відеодрайвер підтримує 8 незалежних курсорів – поодинці на

кожну відеосторінку, причому функція 02h позиціонує курсор на будь-

якій заданій сторінці, незалежно від того, яка сторінка є активною.

Для виведення на екран символів і символьних рядків передбачені

функції 09h, 0Ah, 0Eh і 13h. У прикладі використані функції 0Eh (виве-

дення символу) і 13h (виведення рядка).

Функція 0Eh фільтрує коди 07h (звуковий сигнал), 08h (повернення

на крок), що керують, l0h (переклад рядка) і 13h (повернення каретки),

виконуючи відповідні їм дії. Після виведення кожного символу курсор

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

рядки (використовують виклик функції в циклі). Проте атрибут символу

встановити не можна. Символ, що виводиться, набуває колишнього ат-

рибуту тієї позиції, куди він виводиться.

Функція 13h призначена для виведення рядків із вказівкою атрибу-

тів як кожного символу окремо, так і всього рядка. Функція може вико-

нуватися в чотирьох варіантах залежно від коду режиму, що вказується в

регістрі AL. У режимах 0 і 1 атрибут символів указується відразу для

всього рядка в регістрі BL, причому в режимі 0 курсор не зміщується в

процесі виведення, а в режимі 1 – зміщується на довжину рядка. В ре-

жимах 2 і 3 атрибути символів включаються в рядок, що виводиться, в

якому чергуються коди атрибутів і коди символів, що ускладнює формат

рядка, але дозволяє встановлювати атрибути для кожного символу неза-

лежно. Режим 2 відрізняється від режиму 3 тим, що в першому випадку

курсор після виведення не зміщується, а в другому – зміщується на дов-

жину рядка.

При виклику функції 13h в регістрі DX задаються координати поча-

тку рядка (у DH – рядок екрана і в DL – стовпчик), а в регістрі СХ – дов-

жина рядка, який у режимах 2 і 3 виявляється за рахунок байтів з атрибу-

том у два рази більше довжини рядка, що реально з’являється на екрані.

Інколи незвично вказується адреса рядка. Вона повинна бути поміщена в

регістри ES:BP (ES – сегментна адреса і ВР – зсув в межах сегмента).

Функція 13h виводить не всі символи, оскільки коди 07h, 08h, 0Ah і

0Dh розглядаються нею як керівні.

При виведенні на екран тексту засобами BIOS необхідно мати на

увазі, що введення з клавіатури <Ctrl>/C не приводить до завершення

програми. Слід побоюватися нескінченних циклів виведення на екран –

вихід з них можливий тільки шляхом перезавантаження комп’ютера.

Page 231: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

231

8. СКЛАДНІ СТРУКТУРИ ДАНИХ

8.1. Масиви

8.1.1. Загальні відомості про масиви

Програмування масиву мало чим відрізняється від програмування

задач, які пов’язані з обробкою рядків даних. Програми обробки текстів

та керування базами даних повинні виконувати обробку рядків даних без

помітної втрати швидкості роботи. Компілятори мов високого рівня ви-

конують великий обсяг роботи з рядками чисел. Тому програмісти по-

винні оптимізувати ці програми, при цьому виконувати критичні за шви-

дкістю фрагменти на мові асемблеру.

Масив – структурований тип даних, що складається з деякого чи-

сла елементів одного типу.

Для того, щоб розібратися в можливостях і особливостях обробки

масивів в програмах на асемблері, необхідно:

– описати масив;

– ініціалізувати масив;

– організувати доступ до елементів масиву;

– організувати виконання типових операцій з масивами.

Опис і ініціалізація масиву в програмі

Спеціальних засобів опису масивів в програмах асемблеру немає.

При необхідності використовувати масив в програмі його потрібно мо-

делювати одним з таких способів:

1. Переліком елементів масиву в полі операндів однієї з директив

опису даних. При переліку елементи розділяються комами. Наприклад:

mas dd 1,2,3,4,5 ; масив з 5 елементів по 4 байти кожен

2. Використовуючи оператора повторення dup. Наприклад:

mas dw 5 dup (0) ; масив з 5 нульових елементів по 2 байти кожен

Такий спосіб визначення використовується для резервування

пам’яті з метою розміщення і ініціалізації елементів масиву.

3. Використовуючи директиви label і rept. Пара цих директив може

полегшити опис великих масивів в пам’яті і підвищити наочність такого

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 232: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

232

опису. Директива rept відноситься до макрозасобів мови асемблеру і

викликає повторення вказане число раз рядків, поміщених між директи-

вою і рядком endm. Наприклад, визначимо масив байт в області пам’яті,

позначеної ідентифікатором mas_b. У даному випадку директива label

визначає символічне ім’я mas_b, аналогічно тому, як це роблять дирек-

тиви резервування і ініціалізації пам’яті. Перевага директиви label в то-

му, що вона не резервує пам’ять, а лише визначає характеристики

об’єкта. В даному випадку об’єкт – це елемент пам’яті. Використовуючи

декілька директив label, записаних одна за одною, можна привласнити

одній і тій же області пам’яті різні імена і різний тип, що і зроблено в

наступному фрагменті:

n=0

...

mas_b label byte

mas_w label word

rept 4

dw 0f1f0h

endm

У результаті в пам’яті буде створена послідовність з чотирьох слів

f1f0. Цю послідовність можна трактувати як масив байт або слів залежно

від того, яке ім’я області використовуватимемо в програмі – mas_b або

mas_w.

4. Використовуючи циклу для ініціалізації значеннями області

пам’яті, яку можна буде згодом трактувати як масив. Це виконується

таким чином:

; Ініціалізація масиву в циклі

MASM

MODEL small

STACK 256

.data

mes db 0ah,0dh,’Массив ‘,’$’

mas db 10 dup (?) ; початковий масив

i db 0

.code

main:

mov ах,@data

mov ds,ax

Page 233: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

233

xor ах, ах ; обнулення ах

mov cx,10 ; значення лічильника циклу в cx

mov si,0 ; індекс початкового елемента в cx

go: ; цикл ініціалізації

mov bh,i ; i у bh

mov mas[si],bh ; запис в масив i

inc i ; інкремент i

inc si ; просування до наступного елемента масиву

loop go ; повторити цикл

; виведення на екран масиву

mov cx,10

mov si,0

mov ah,09h

lea dx,mes

int 21h

show: mov ah,02h ; функція виведення значення з al на екран

mov dl,mas[si]

add dl,30h ; перетворення числа в символ

int 21h

inc si

loop show

exit: mov ах,4c00h ; стандартний вихід

int 21h

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

Доступ до елементів масиву

При роботі з масивами необхідно уявляти собі, що всі елементи ма-

сиву розташовуються в пам’яті комп’ютера послідовно. Програміст за

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

ктувати цю послідовність байт складових масив. Так, одну і ту ж область

пам’яті можна трактувати як одновимірний масив, і одночасно ті ж самі

дані можуть трактуватися як двовимірний масив. Самі по собі дані не

несуть ніякої інформації про свій “смисловий”, або логічний, тип.

Ці ж міркування можна розповсюдити і на індекси елементів ма-

сиву. Асемблер не підозрює про їх існування і йому абсолютно все одно,

які їх чисельні смислові значення. Для того, щоб локалізувати певний

елемент масиву, до його імені потрібно додати індекс. Оскільки ми мо-

делюємо масив, то необхідно моделювати й індекс. У мові асемблеру

Page 234: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

234

індекси масивів – це звичайні адреси, але з ними працюють особливим

чином. Іншими словами, коли при програмуванні на асемблері ми гово-

римо про індекс, то швидше маємо на увазі не номер елемента в масиві,

а деяку адресу.

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

mas dw 0,1,2,3,4,5

Хай ця послідовність чисел трактується як одновимірний масив. Ро-

змірність кожного елемента визначається директивою dw, тобто вона

дорівнює 2 байтам. Щоб дістати доступ до третього елемента, потрібно

до адреси масиву додати 6. Нумерація елементів масиву в асемблері по-

чинається з нуля. Тобто в нашому випадку фактично йдеться про 4-й

елемент масиву – 3.

У загальному випадку для отримання адреси елемента в масиві не-

обхідно початкову (базову) адресу масиву скласти з добутком індексу

(номер елемента мінус одиниця) цього елемента на розмір елемента ма-

сиву:

база + (індекс*розмір елемента)

Архітектура мікропроцесора надає достатньо зручні програмно-

апаратні засоби для роботи з масивами. До них відносяться базові і інде-

ксні регістри, що дозволяють реалізувати декілька режимів адресації

даних. Використовуючи ці режими адресації, можна організувати ефек-

тивну роботу з масивами в пам’яті. Пригадаємо ці режими:

– індексна адресація із зсувом – режим адресації, при якому ефек-

тивна адреса формується з двох компонентів:

= постійного (базового) – зазначенням прямої адреси масиву у

вигляді імені ідентифікатора, що позначає почало масиву;

= змінного (індексного) – зазначенням імені індексного регіст-

ра.

Наприклад:

mas dw 0,1,2,3,4,5

...

mov si,4

; помістити 3-й елемент масиву mas в регістр ах:

mov ах,mas[si]

– базова індексна адресація із зсувом – режим адресації, при якому

ефективна адреса формується максимум з трьох компонентів:

Page 235: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

235

= постійного (необов’язковий компонент), за який може висту-

пати пряма адреса масиву у вигляді імені ідентифікатора, що позначає

початок масиву, або безпосереднє значення;

= змінного (базового) – вказівкою імені базового регістра;

= змінного (індексного) – вказівкою імені індексного регістра.

Цей вид адресації зручно використовувати при обробці двовимірних

масивів.

Нагадаємо, що як базовий регістр може використовуватися будь-

який з восьми регістрів загального призначення. Як індексний регістр

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

ня, за винятком esp/sp.

Мікропроцесор дозволяє масштабувати індекс. Це означає, що

якщо вказати після імені індексного регістра знак множення “*” з пода-

льшою цифрою 2, 4 або 8, то вміст індексного регістра буде помножати-

ся на 2, 4 або 8, тобто буде масштабуватися.

Застосування масштабування полегшує роботу з масивами, які ма-

ють розмір елементів, що дорівнює 2, 4 або 8 байтам, оскільки мікроп-

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

го елемента масиву. Нам потрібно лише завантажити в індексний регістр

значення необхідного індексу (рахуючи від 0). До речі, можливість мас-

штабування з’явилася в мікропроцесорах Intel, починаючи з моделі i486.

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

тива .486. Її призначення, як і призначення директиви .386, що раніше

використовувалася, в тому, щоб вказати асемблеру при формуванні ма-

шинних команд на необхідність обліку і використання додаткових мож-

ливостей системи команд нових моделей мікропроцесорів.

Як приклад використання масштабування розглянемо видимий ма-

сив, що складається із слів, і проведемо порівняння цих елементів з ну-

лем. Виводиться відповідне повідомлення.

Приклад 8.1. Порівняти елементи масиву з нулем з використанням

масштабування. MASM MODEL small STACK 256 .data ; початок сегмента даних ; тексти повідомлень: mes1 db ‘що не дорівнює 0!$’,0ah,0dh

Page 236: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

236

mes2 db ‘що не дорівнює 0!$’,0ah,0dh mes3 db 0ah,0dh,’Елемент $’ mas dw 2,7,0,0,1,9,3,6,0,8 ; початковий масив .code .486 ; це обов’язково main: mov ах,@data mov ds,ax ; зв’язка ds з сегментом даних xor ах, ах ; обнулення ах prepare: mov cx,10 ; значення лічильника циклу в cx mov esi,0 ; індекс в esi compare: mov dx,mas[esi*2] ; перший елемент масиву в dx cmp dx,0 ; порівняння dx з 0 je equal ; перехід, якщо дорівнює not_equal: ; не дорівнює mov ah,09h ; виведення повідомлення на екран lea dx,mes3 int 21h mov ah,02h ; виведення номера елемента масиву на екран mov dx,si add dl,30h int 21h mov ah,09h lea dx,mes1 int 21h inc esi ; на наступний елемент dec cx ; умова для виходу з циклу jcxz exit ; cx=0? Якщо так – на вихід jmp compare ; немає – повторити цикл equal: ;дорівнює 0 mov ah,09h ; виведення повідомлення mes3 на екран lea dx,mes3 int 21h mov ah,02h mov dx,si add dl,30h int 21h mov ah,09h ; виведення повідомлення mes2 на екран lea dx,mes2

Page 237: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

237

int 21h inc esi ; на наступний елемент dec cx ; всі елементи оброблені? jcxz exit jmp compare exit: mov ах,4c00h ; стандартний вихід int 21h end main ; кінець програми

Приклад 8.2. У пам’яті з адреси 0040h знаходиться масив із 8 чи-

сел. Елементами масиву є числа 32 та 64. Зберегти в пам’яті: в комірці

0048h – значення 1-го числа; в комірці 0049h – число повторень 1-го

числа; в комірці 004Аh – значення 2-го числа; в комірці 004Вh – число

повторень 2-го числа.

Блок-схему алгоритму виконання програми наведено на рис. 8.1.

Програма на асемблері МП платформи х86 може мати такий вигляд:

0000 C606480032 MOV [0048], 32 ; (1) Завантаження в const 32

0005 C606490000 MOV [0049], 00 ; (2

000A C6064A0064 MOV [004A], 64 ; (3) Завантаження в const 64

000F C6064B0000 MOV [004B], 00 ; (4)

0014 B108 MOV CL, 08 ; (5) Лічильник кількості елементів

0016 BE4000 MOV SI, 0040 ; (6) Початкова адреса масиву

0019 8A04 M6: MOV AL, [SI] ; (7) Завантаження елемента масиву

001B 46 INC SI ; (8) Збільшення номера масиву на 1

001C B332 MOV BL, 32 ; (9)

001E B764 MOV BH, 64 ; (10)

0020 38C3 CMP BL, AL ; (11) Порівняння const та елемента

0022 740C JZ M1 ; (0030) ; (12)

0024 38C7 CMP BH, AL ;(13) Порівняння const та елемента

0026 7402 JZ M3 ; (002A) ; (14) Перехід на М3 при BH – AL = 0

0028 EB0A JMP M4 ; (0034) ; ) Перехід на М4 при BH – AL ≠ 0

002A FF064B00 M3: INC [004B] ; (15)

002E EB04 JMP M4 ; (0034) ;

0030 FF064900 M1: INC [0049] ; (16)

0034 FEC9 M4: DEC CL ; (17) Зменшення вмісту лічильника

0036 7402 JZ M5 ; (003A) ; (18) Перевірка лічильника

0038 EBDF JMP M6 ; (0019) ; Перехід, якщо CL ≠ 0

Page 238: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

238

003A F4 HLT ; (END) ; (0) Зупинка

Приклад 8.3. Задано масиви А та В по 4 елементи. Навести алго-

ритм та програму сформування масиву С за правилом: якщо Аі < Bi, то Сі

= Аі, інакше – Сі = Ві.

Блок-схема виконання прикладу наведено на рис. 8.2.

Програма на асемблері МП платформи х86 може мати такий вигляд: .MODEL small ; коди та дані займають <= 64 кбайт DATA SEGMENT ; початок сегмента даних

a1 db 0,1,2,3 ; визначення даних-байт масиву з ім’ям а1 a2 db 1,2,3,4 ; визначення даних-байт масиву з ім’ям а2

DATA ENDS ; кінець сегмента-даних .CODE ; початок сегмента-даних

START: MOV AX, @DATA ; встановити адресу сегмента даних MOV DS,AX ; ініціювати DS для завдання DS:SI MOV ES, AX ; ініціювати ES для завдання ES:DI LEA SI, A1 ; завантаження початкового слова з пам’яті з масиву а1

MOV DI, OFFSET A2 ; адресу масиву а2 – в DI MOV BX, 04 ; (5) початкове зміщення адреси масиву С MOV СL, 04 ; (6) кількість елементів масиву M3: MOV AL, [SI] ; (7) занесення елементу масиву А1 MOV AH, [DI] ; (8) занесення елементу масиву А2

Рис. 8.1. Алгоритм виконання прикладу 8.2

Початок

Закінчення

Ні

[0048] := 32h

Z = 1

[0040] := 00

BH – AL [0049] := [0049] +

1

Z = 1

Так

Ні

1

2

12

13 16

14

0

0

M1: [004A] := 64h

[004B] := 00

3

4

CL := 08h

SI := 0040h

5

6

AL := [SI]

SI := SI + 1

7

8

BL := 32h 9

BL – AL 11

[004B] := [004B] +

1

Z = 1 Ні 18

BH := 64h 10

15

CL := CL – 1 17

Так

M3:

M4:

Так

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 239: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

239

CMP AL, AH ; (9) порівняння елементів масивів А1 та А2 JS M1 ; (10) перейти, якщо А1 < А2 MOV [DI + BX], AH ; (12) JMP M2 ; (12) M1: MOV [DI + BX], AL ; (11) M2: ADD SI, 01 ; (13) збільшення адреси елемента масива А1 ADD DI, 01 ; (14) збільшення адреси елемента масива А2 ADD BX, 01 ; (15) збільшення адреси елемента масива С DEC СL ; (16) зменшення лічильника кількості елементів JNZ M3 ; ; (17)

MOV AH, 4CH ; код успішного завершення програми INT 21H ; exit DOS END START ; кінець програми

Вікна налагоджувача Emu8086 v. 4.04 при налагодженні програми

прикладу 8.3 наведені на рис. 8.3.

Для налагоджування програми під Windows з використанням API-

функцій найчастіше використовується налагоджувач OllyDbg і асемблер

masm32 або tasm32. Для компіляції програми під Windows необхідно

виконати такі дії:

– компіляція masm32:

ml /c /coff 2.asm

Ні

Рис. 8.2. Блок-схема виконання прикладу 8.3

Так S = 1

Закінчення

[DI + BX] ← AL

BX ← 04

СL ← 4

AL ← [SI]

AH ← [DI]

AL – AH

[DI + BX] ← AH

SI := SI + 1

DI := DI + 1

BX := BX + 1

СL := СL – 1

СL = 0

Так

5

6

7

8

9 Ні

10

11 12

13

14

15

16

17

Початок

0

Визнач. A1

Визнач. A2

1

2

DI := адр А2 4

SI := адр А1 3

Page 240: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

240

link /SUBSYSTEM:CONSOLE 2.obj

– компіляція tasm32:

tasm /m /ml /2.asm

tlink32 /Tpe /aa /c /x 2.obj

Для tasm32 програма прикладу 8.3 може бути такою: .386 .MODEL flat,stdcall DATA SEGMENT a1 db 0,1,2,3 a2 db 1,2,3,4 DATA ENDS .CODE START: LEA ESI,A1 MOV EDI,OFFSET A2 MOV EBX, 00000004

Рис. 8.3. Вікна налагоджувача Emu8086 v. 4.04 при налагодженні програми прикладу 8.3

Page 241: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

241

MOV CL, 04 M3: MOV EAX,[ESI] MOV EDX,[EDI] CMP AL,DL JS M1 MOV [EDI+EBX],DL JMP M2 M1: MOV [EDI+EBX],AL M2: ADD ESI, 01 ADD EDI, 01 ADD EBX, 01 DEC CL JNZ M3 END START

Вікна відладчика OllyDbg з відповідною програмою наведені на

рис. 8.4.

Приклад 8.4. Задано масив А з 5 елементів. Навести алгоритм та

програму визначення елементів масиву А, які задовольняють умові 6

≤ Аі < 3А, та розмістити їх в новому масиві.

Блок-схему виконання прикладу наведено на рис. 8.5.

Рис. 8.4. Вікна відладчика OllyDbg з програмою прикладу 8.3

Page 242: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

242

Програма прикладу 8.4 із директивами асемблеру яка повністю го-

това до виконання, наведена нижче:

.MODEL small ; коди та дані займають <= 64 кбайт

DATA SEGMENT ; початок сегмента даних

a1 db 0,4,6,3ah,3bh ; визначення даних-байт масиву з ім’ям а1

a2 db 5 dup(?) ; зарезервування 5 байт масиву даних з ім’ям а2

DATA ENDS ; кінець сегмента-даних

.CODE ; початок сегмента-даних

start: mov ax, @DATA ; встановити адресу сегмента даних

mov ds,ax ; ініціювати DS для завдання DS: SI

mov es, ax ; ініціювати ES для завдання ES:DI

Занесення const2

Порівняння елемента з const2

Порівняння елемента

з const1

Підготовка

лічильника

до читання

наступного

елемента

Занесення в АХ елемента, адреса якого розміщена в РгSI

Ні

Рис. 8.5. Блок-схема виконання прикладу 8.4

Так CX = 0

Початок

0

Закінчення

CX := 5

Визнач. A1

Визнач. A2

AX ← [SI]

CX ← CX – 1

AX – 3A

3

1

AX – BX

SI := SI + 1

Так

2

6

7

10

13

8

9

BX := 6

AX < 3A

Так Ні

[DI] ←AX 15

DI := DI + 1 16

0

11

12

12 14

Кількість елементів масиву Початкова адреса масиву А1 Початкова адреса масиву A2

AX > BX

Ні

DI := адр А2 5

SI := адр А1 4

M1:

M3:

Page 243: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

243

mov cx, 5 ;

lea si, a1 ; завантаження початкового слова з пам’яті з масиву а1

mov DI, offset a2; завантаження початкового слова з пам’яті з масиву а2

M4: mov ax, [si] ;

dec cx ;

jz m1 ;

inc si ;

cmp al, 3ah ;

jl m3 ;

jmp m4 ;

M3: mov bl, 06 ;

cmp al,bl ;

jnl m5 ;

jmp m4 ;

M5: mov [di], al ;

inc di ;

jmp m4 ;

M1: mov ah, 4ch

int 21h

end start

Вікна налагоджувача Emu8086 v. 2.57 при налагодженні програми

прикладу 8.4 наведено на рис. 8.6.

Рис. 8.6. Вікна налагоджувача Emu8086 v. 2.57 при налагодженні програми

прикладу 8.4

Page 244: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

244

Рис. 8.7. Програма прикладу 8.4 з ди-

рективами асемблера під Windows

Програму прикладу 8.4 з

директивами асемблеру під

Windows наведено на рис. 8.7, а

вікна налагоджувача OllyDbg з

відповідною програмою – на

рис. 8.8.

Рис. 8.8. Вікна налагоджувача OllyDbg з програмою прикладу 8.4

Page 245: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

245

Приклад 8.5. Задані масиви А і В по N = 8 елементів. Навести ал-

горитм та програму сформування масиву С за правилом: якщо Аi

– Вi ≥ 0, то Сj = Aі.

Блок-схему виконання прикладу 8.5 наведено на рис. 8.9.

Програма на асемблері МП платформи х86 може мати такий вигляд:

0000 BE3000 MOV SI, 0030 ; (1) Початкова адреса масиву А

0003 BF3800 MOV DI, 0038 ; (2) Початкова адреса масиву В

0006 BB4000 MOV BX, 0040 ; (3) Початкова адреса масиву С

0009 B90800 MOV CX, 0008 ; (4) Кількість елементів в масиві

000C 8B15 M4: MOV DX, [DI] ; (5)

000E 3914 CMP [SI], DX (6) Порівняння [SI] та [DI] через DX

0010 7D02 JNL M1; (JGE); (0014) ; (7)

0012 EB07 JMP M2; (001E) ; (7)

0014 8B04 M1: MOV AX, [SI] ; (8) Запис байта в AL

0016 B400 MOV AH, 00 ; (9) Обнулення ст. частини AX

0018 8907 MOV [BX], AX ; (10)

001A 49 DEC CX ; (11)

001B 7405 JZ M3 ; (0022) ; (12)

Рис. 8.9. Блок-схема виконання прикладу 8.5

Так CX = 0

Початок

0

DI := 0038

BX := 0040

CX := 08

DX := [DI]

[SI] – DX

2

3

4

5

6

12 DI := DI + 1

BX := BX + 1

Закінчення 0

SI := 0030 1

AX := [SI] 8

[BX] := AX

CX := CX – 1 SI := SI +1

[SI] – [DI] ≥ 0

7

Так M1:

Ні

AX := 00

9

10

11

14

15

13

Ні

Page 246: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

246

001D 43 INC BX ; (15)

001E 46 M2: INC SI ; (13)

001F 47 INC DI ; (14)

0020 EBE3 JMP M4 ; (0009) ; (15’)

0022 F4 M3: HLT ; (END)

Приклад 8.6. Задано масив А з N = 4 елементів. Навести алгоритм

та програму визначення кількості елементів масиву А, у яких біти 0 ма-

ють нулі.

Блок-схему алгоритму виконання програми наведено на рис. 8.10.

Програма на асемблері МП може мати такий вигляд:

.386

.MODEL flat,stdcall

DATA SEGMENT ;

a1 db 0,1,0,1

DATA ENDS ;

.CODE ;

START:

MOV EBX, 4

MOV EDX, 0

MOV ESI, offset a1 ;

M1: MOV EAX, [ESI] ;

INC ESI ; підготовка адреси нового елемента

Рис. 8.10. Алгоритм виконання прикладу 8.6

Закінчення

S = 1

AL := [SI]

SI := SI + 1

EAX := EAX ^ 01

Z = 1

CH := CH + 1

EDX ← 0

EBX ← 4 2

Початок

0

Визнач. A1 1

SI := адр А1

3

4

Лічильник кількості

елементів у масиві

Лічильник кількості збігів еле-

ментів

Page 247: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

247

DEC EBX

JS M2 ; перейти , якщо закінчилась кількість елементів масиву

AND EAX, 01 ; виделення нульового біту

JNZ M1

INC EDX

JMP M1

M2: END START

Вікна відладчика OllyDbg з відповідною програмою наведені на

рис. 8.11.

8.1.2. Двовимірні масиви

При розгляданні двовимірного масиву проблеми виникають через

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

має. Двовимірний масив потрібно моделювати. На описі самих даних це

майже ніяк не відбивається – пам’ять під масив виділяється за допомо-

гою директив резервування і ініціалізації пам’яті. Безпосередньо моде-

лювання обробки масиву проводиться в сегменті коду, де програміст,

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

пам’яті необхідно трактувати як двовимірний масив. При цьому програ-

міст сам вибирає, як розуміти розташування елементів двовимірного

масиву в пам’яті: по рядках або по стовпцях.

DI := DI – 1

Рис. 8.11. Вікна налагоджувача OllyDbg з програмою приклада 8.6

Page 248: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

248

Якщо послідовність однотипних елементів в пам’яті трактується як

двовимірний масив, розташований по рядках, то адреса елемента (i, j)

обчислюється за формулою

(база + кількість_елементів_в_рядку * розмір_елемента * i+j)

Тут i = 0...n – 1 вказує номер рядка, а j = 0...m-1 вказує номер стов-

пця.

Наприклад, хай є масив чисел (розміром в 1 байт) mas(i, j) з розмір-

ністю 4 на 4 (i= 0...3, j = 0...3):

23 04 05 67

05 06 07 99

67 08 09 23

87 09 00 08

У пам’яті елементи цього масиву будуть розташовані в такій послі-

довності:

23 04 05 67 05 06 07 99 67 08 09 23 87 09 00 08

Якщо хочемо трактувати цю послідовність як двовимірний масив,

наведений вище, і витягнути, наприклад, елемент mas(2, 3)= 23, то про-

вівши підрахунок, переконаємося в правильності міркувань:

Ефективна адреса mas(2, 3)= mas + 4 * 1 * 2 + 3 = mas + 11

Організувати адресацію двовимірного масиву логічно, використо-

вуючи розглянуту раніше базово-індексну адресацію. При цьому можли-

ві два основні варіанти вибору компонентів для формування ефективної

адреси:

поєднання прямої адреси, як базового компоненту адреси, і

двох індексних регістрів для зберігання індексів:

mov ах,mas[ebx][esi]

поєднання двох індексних регістрів, один з яких є і базовим і ін-

дексним одночасно, а інший – тільки індексним:

mov ах[ebx][esi]

8.1.3. Завдання для самостійного дослідження двовимірних масивів

Ввести двовимірний масив А(N,M). Скласти алгоритм і програму

заміни всіх нульових елементів на мінімальний елемент.

Page 249: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

249

1. Ввести двовимірний масив А(N,N). Скласти алгоритм і програму

підрахунку середнього арифметичного значень двовимірного масиву.

Знайти відхилення від середнього у елементів першого рядка.

2. Ввести двовимірний масив А(N,N). Скласти алгоритм і програму

підрахунку середнього арифметичного значення двовимірного масиву.

Обчислити відхилення від середнього для всіх елементів двовимірного

масиву.

3. Ввести двовимірний масив А(N,N). Скласти алгоритм і програму

заміни всіх негативних елементів на середнє арифметичне значення

елементів двовимірного масиву.

4. Скласти алгоритм і програму знаходження числа рядків двовимі-

рного масиву А(N,N), кількість негативних елементів в яких більше M.

5. Ввести двовимірний масив розміром 7*4. Знайти найбільший

елемент двовимірного масиву. Видалити рядок з максимальним елемен-

том.

6. Ввести двовимірний масив розміром 7*4. Поміняти стовпець з

максимальним елементом з першим стовпцем двовимірного масиву .

7. Ввести двовимірний масив розміром 7*7. Знайти максимальний

елемент двовимірного масиву, розташований нижче за побічну діаго-

наль.

8. Ввести двовимірний масив розміром 7*4. Знайти найменший

елемент двовимірного масиву. Перенести рядок, що містить цей еле-

мент, в кінець.

9. Ввести двовимірний масив розміром 7*4. Знайти максимальний

елемент двовимірного масиву. Перенести рядок, що містить цей еле-

мент, в кінець.

10. Ввести двовимірний масив розміром 6*4. Знайти мінімальний

елемент двовимірного масиву. Переставляючи рядки і стовпці, добитися

того, щоб він опинився в правому нижньому кутку.

11. Скласти алгоритм обчислення суми елементів двовимірного ма-

сиву А(1.. N, 1..М), розташованих вище за головну діагональ.

12. Скласти алгоритм обчислення кількості непарних елементів в

кожному рядку двовимірного масиву А(1.. N, 1..М).

14. Скласти алгоритм пошуку максимального значення в двовимір-

ному масиві А(N,M).

Page 250: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

250

8.2. Рядки

8.2.1. Команди обробки рядків

Однобайтні команди обробки рядків, крім одноразового їх вико-

нання, можуть бути виконані й багаторазово, якщо команді передує

префікс-повторювач (мнемокоди: REP, REPE, REPZ, REPNE, REPNZ).

Окремі операції можуть поєднуватись для формування складних опера-

цій над рядками. У таких випадках повторення забезпечується операція-

ми ітерації. Наявність префікса дозволяє передавати однією командою

рядок з однієї області пам’яті в іншу при відповідній ініціалізації регіст-

рів DS:SI, ES:DI, CX. Всі елементарні операції над рядками використовує

регістр SІ для адресації операндів. Регістр DІ використовується для ад-

ресації результату, що знаходиться в додатковому сегменті. Якщо біт DF

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

над байтами на одиницю, а після операції над словами – на два. Якщо

встановлений біт DF, вміст індексних регістрів операнда і результату

зменшується після кожної операції.

Кожній елементарній рядковій команді може передувати одно-

байтний префікс (мнемокоди: REP, REPE, REPZ, REPNE, REPNZ), який

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

гістрі СХ не буде вичерпаний. Перевірка вмісту лічильника CX викону-

ється до повторення операції. Якщо вміст лічильника в регістрі СХ дорі-

внює нулю, операція виконуватись не буде. Префікс повторення визна-

чає також величину, що повинна порівнюватися з бітом ZF. Якщо еле-

ментарна команда впливає на біт ZF і його значення не дорівнює позна-

ченій величині після деякої кількості повторень операції, її повторення

припиняється. Це дозволяє організувати цикл типу WHІLE чи UNTІ.

Під час виконання повторюваної елементарної команди індексні

регістри SІ, DІ і лічильник повторень (СХ) змінюються після кожного

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

та префікса (у припущенні, що він безпосередньо передує команді над

рядками). Перервана команда над рядками буде вірно продовжена після

повернення керування з перериваючої програми, якщо перед елементар-

ною командою розміщений тільки один префікс. Тому варто уникати

використання двох інших префіксів разом з префіксом-повторювачем у

командах роботи з рядками, тобто префікса сегмента і префікса LOCK

(це пов’язано з тим, що після виходу з перериваючої програми, виконан-

Page 251: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

251

ня відновиться з адреси, на один байт меншої від адреси команди (тобто

адреси, у якій приблизно розміщений префікс-повторювач, а додаткові

префікси будуть ігноруватись).

Префікс REP використовується з командами MOVS і STOS і ініціює

дію “повторювати, поки не буде досягнутий кінець ланцюжка”, тобто

доти, поки вміст регістра СХ не досягне нуля. Префікси REPE і REPZ

діють аналогічно і є таким же байтом, як і префікс REP. Вони викорис-

товуються з командами CMPS і SCAS і оперують з прапорцем ZF = 1,

стан якого визначається результатом виконання цих команд. Префікси

REPNE і REPNZ діють аналогічно попереднім префіксам, але прапорець

ZF повинен дорівнювати нулю. Інакше повторення закінчується.

Існує п’ять елементарних команд роботи з рядкам, які наведені у

табл. 8.1.

У регістрі ES необхідно вказати початок сегмента даних ще до то-

го, як будуть використовуватись команди роботи з рядками. Регістри ES

та DS можуть бути ініційовані таким чином:

MOV AX, @data ; встановити адресу сегмента даних

MOV DS, AX ; ініціювати DS для завдання DS: SI

MOV ES, AX ; ініціювати ES для завдання ES:DI

Таблиця 8.1

Команда Опис Операнди

MOVS Переміщує рядки даних: байт, слово, по-

двійне слово з однієї частки пам’яті в іншу

MOVS [ЕDI],[ЕSI]

STOS Збереження вмісту регістрів AL, AX або

EAX у пам’яті, комірка якої визначається

регістром DI

STOS [DI], AL

STOS [DI], АХ

STOS [EDI], EAX

CMPS Порівняння у пам’яті [ЕSI] – [ЕDI] CMPS [ЕSI], [ЕDI]

SCAS Сканування рядків. Порівняння вмісту

комірки пам’яті, адреса якої визначається

регістром DI із вмістом регістрів AL, AX

або EAX: [EDI] – EAX

SCAS [DI], AL

SCAS [DI], AX

SCAS [EDI], EAX

LODS Збереження у регістрі AL, AX або EAX

байта, слова або подвійного слова з

пам’яті, адреса якої визначається вмістом

регістра SI

LODS AL, [SI]

LODS AX, [SI]

LODS ЕАХ, [ESI]

Page 252: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

252

Кожна з рядкових команд може додатково використовувати літери:

B – робота з байтом; W – з словом; D – з подвійним словом (для МП

Intel386+).

Команда MOVS пересилає байт (слово) з поля, що вказується Рг SІ

в поле, що задається Рг DІ (MOVS [DI],[SI]). При використанні команди

з префіксом RET команда MOVS здійснює блокову передачу ланцюжка

(поки СХ ≠ 0), елементами якого є байти.

MOVS BUFFER, DATA; Передати один елемент з області DATA,

; адреса якого зазначена Рг SІ в область

; BUFFER, адреса якого зазначена у Рг DІ.

RET MOVSB BUFFER, DATA; Передати блок даних з області DATA

; в область BUFFER (В – байт, W – слово) доти, поки СХ = 0

При використанні з префіксом REP команда MOVS виконує блоко-

ву передачу пам’ять – пам’ять.

Прапорець напряму. Рядкові команди використовують прапорець

напряму DF регістра Flags, щоб визначити, який з регістрів (SI або DI)

буде інкрементуватись або декрементуватись при виконанні команди.

Значення прапорця Дія на SI або DI Напрям

0 Інкрементується від низу до верху

1 Декрементується зверху вниз

Прапорець напряму змінюється командами CLD і STD:

CLD ; скинути прапорець напряму, напрям – вгору

STD ; встановити прапорець напряму, напрям – вниз

Наступна програма переміщує 10 байт із області пам’яті S1 в об-

ласть пам’яті S2:

CLD ; напрям – вгору

MOV SI, offset S1 ; DS: SI вказує на передавач

MOV DI, offset S2 ; ES: DI вказує на приймач

MOV CX, 10 ; встановлює лічильник в 10

REP MOVSB ; переміщення 10 байт

S1 DB ‘ABCDEFGHIJ’

S2 DB 10 dup(?)

Page 253: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

253

Наступні дві програми показують переваги використання команди

обробки рядків.

Приклад 8.7. Cкопіювати всі значення з масиву source в масив

target без використання команд обробки рядків.

Програма може мати такий вигляд:

.MODEL small ; коди та дані займають <= 64 кбайт

DATA SEGMENT ; початок сегмента даних

source dw -1h,5h,10h,15h,20h ; визначення масиву з ім’ям source

target dw dup(0) ; масив target, всі елементи якого дорівнюють нулю

DATA ENDS ; кінець сегмента-даних

.code ; початок сегмента-даних

st: mov ax,@data ; встановити адресу сегмента даних

mov ds, ax ; ініціювати DS для завдання DS: SI

mov es, ax ; ініціювати ES для завдання ES:DI

mov cx,5 ; кількість слів у масиві

LI: mov ax, source[si] ; завантаження слова з пам’яті з масиву source,

; адреса якого знаходиться в регістрі SI

mov target[di+6], ax ; запис слова з АХ в масив пам’яті target

; за адресою, яка находиться в регістрі SI

add si, 2 ; вирівнювання вмісту регістра SI на границю слова

add di,2

loop LI ; цикл на LI поки СХ ≠ 0

mov ah, 4ch ; код успішного завершення програми

int 21h ; exit DOS

end st ; кінець програми

Вікна налагоджувача Emu8086 v.4.04 при налагодженні програми

прикладу 8.7 наведено на рис. 8.12.

Приклад 8.8. Cкопіювати всі значення з масиву source в масив

target з використанням команд обробки рядків.

Програма з використанням команди MOVSW може мати такий ви-

гляд:

.MODEL small ; коди та дані займають <= 64 кбайт

DATA SEGMENT ; початок сегмента даних

source dw 0,5,10,15,20

target dw dup(0)

Page 254: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

254

DATA ENDS ; кінець сегмента даних

.code

st: mov ax,@data

mov ds, ax

mov es, ax ;

mov si, offset source ;

mov di, offset target

mov cx, 5 ;

cld ; напрям – вгору

rep movsw

mov ah, 4ch ; код успішного завершення програми

int 21h ; exit DOS

end st ; кінець програми

Вікна налагоджувача Emu8086 v.2.57 при налагодженні програми

прикладу 8.8 наведено на рис. 8.13.

Для копіювання вмісту екрана в буфер перед тим, як програма MS-

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

Рис. 8.12. Вікна налагоджувача Emu8086 v.4.04 при налагодженні про-

грами прикладу 8.7

Page 255: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

255

екрана, де це меню відображається. Якщо меню прибрати, попередній

вміст екрана відновиться. Буфер визначається як масив розміром в 2000

слів. Адреса в DS:SI указує на простір відеодисплея. Регістри ES:DI ука-

зують на буфер в сегменті даних, що відноситься до програми. Екран

містить 25 рядків і 80 стовпців, що відповідає 2000 символам. Для кож-

ного символу необхідно два байти: один байт – для коду символу і дру-

гий – для атрибутів.

Така програма може бути такою: .data VIDEO_SEG = 0B800h ; сегмент кольорового відео буфера WORD COUNT = 2000 buffer dw WORD_COUNT dup(?) .code

mov si, VIDEO_SEG ; DS:SI указує на простір відео mov ds, si mov si, 0 mov di, seg buffer ; ES:DI указує на буфер mov es, di mov di, offset buffer cld ; напрям – вгору mov cx WORD_COUNT ; число слів для копіювання

rep movsw ; копіювання з DS:SI у ES:DI

Рис. 8.13. Вікна налагоджувача Emu8086 v.2.57 при налагодженні

програми прикладу 8.8

Page 256: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

256

Команда CMPS здійснює віднімання байта (слова), який адресуєть-

ся другим операндом (з [DI]), з байта (слова), який адресується першим

операндом (з [SI]) (CMPS [SI], [DI]). Команда впливає на біти умов, але

не формує результат. Вона призначена для порівняння рядків. При від-

повідному префіксі-повторювачі можливо визначити, після якого елеме-

нта два рядки починають відрізнятись один від одного і, таким чином,

установити порядок, в якому вони повинні розміщуватись.

CMPS BUFFER, DATA; (DATA) – (BUFFER).

;Відняти елемент області BUFFER, адреса якої зазначена

;у Рг DІ з елемента області DATA, адреса якої зазначена у Рг SІ.

Коли перед командою CMPS знаходиться префікс REPE (або

REPZ), операція інтерпретується як “порівнювати, поки не буде досягну-

тий кінець ланцюжків або поки елементи ланцюжків не будуть рівні”. За

наявності префікса REPNE (або REPNZ) операція набуває сенсу “порів-

нювати не до кінця, а до першого виконання умови слідкуючої команди

(або поки елементи ланцюжків будуть рівні)”. Таким чином, команду

CMPS зручно застосовувати для знаходження однакових або таких, що

розрізняються, елементів ланцюжків.

Прапорець напряму визначає інкремент або декремент регістрів SI і

DI. Таким чином можуть бути використані такі префікси повторення:

REP ; Повторювати, поки СХ > 0

REPE, REPZ ; Повторювати, поки відправник = одержувачу

REPNE, REPNZ ; Повторювати, поки відправник >< одержувача

Якщо рядок операнда-відправника менший, ніж рядок операнда-

одержувача, то CF = 1. Якщо рядки рівні, то ZF = 1.

Якщо рядок операнда-відправника більший, ніж рядок операнда-

одержувача, то ZF = 0 та CF = 0. Умовні переходи, використовувані з

командою CMPS, наведено в табл. 8.2.

Таблиця 8.2

Умова Без знаку Із знаком

Одержувач < відправник JB JL

Одержувач <= відправник JBE JLE

Одержувач <> відправник JNE (JNZ) JNE (JNZ)

Одержувач = відправник JE (JZ) JE (JZ)

Одержувач >= відправник JAE JGE

Одержувач > відправник JA JG

Page 257: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

257

Приклад 8.9. Порівняти літери двох змінних. У випадку, якщо кі-

лькість літер у першій змінній менша, ніж кількість літер другої змінної,

то записати у регістр BX ← 1. В протилежному випадку – у BХ заванта-

жити 0.

Програма може бути такою:

.MODEL tine ; коди та дані займають < 64 кбайт

DATA SEGMENT ; початок сегмента даних

source db ‘MARTIN’

dest db ‘MARTINEZ’

DATA ENDS ; кінець сегмента даних

.CODE

start: mov ax, @DATA

mov ds, ax ; ініціювати DS для завдання DS: SI

mov es, ax ; ініціювати ES для завдання ES:DI

cld ; напрям – вгору

mov si, offset source ; в SI – адресу першого елемента масиву source

mov di, offset dest ; указує на одержувача

mov cx, 8 ; довжина рядка

repne cmpsb ; порівняти відправника і одержувача

jb min ; перехід, якщо source < destination

mov bx, 0

jmp m1

min: mov bx, 1

m1: mov ah, 4Ch ; код успішного завершення програми

int 21h ; exit DOS

end start ; кінець програми

Для явного зазначення вказівки типу елементів ланцюжків звичайно

допускаються мнемокоди CMPSB і CMPSW; при цьому операнди в ко-

манді відсутні.

Порівняння чисел із знаком. Команда CMPS може порівнювати два

списки цілих чисел із знаком до першого незбіжного числа.

Приклад 8.10. Порівняти два списки цілих чисел із знаком до пер-

шого незбіжного числа.

У наступному прикладі кожне число в масиві a1 порівнюється з від-

повідними числами з масиву а2. Початкова частина масиву a1 вважаєть-

Page 258: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

258

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

сиву а2 буде дорівнювати 3. Числа в пам’яті комп’ютера зберігаються у

додаткових числах. Порівняння четвертих елементів масивів не відбува-

ється.

.MODEL small ; коди та дані займають <= 64 кбайт

DATA SEGMENT ; початок сегмента даних

a1 db 12,2,-3,4

a2 db 12,2,3,-4 ;

DATA ENDS ; кінець сегмента даних

.CODE

start: mov ax, @DATA

mov ds,ax

mov es, ax

cld ; напрям – вгору

lea si, a1 ; завантаження адреси масиву a1

mov di,offset a2 ; завантаження адреси масиву a2

mov cx, 4 ; встановити в лічильник max значення

repe cmpsb ; повторювати порівняння байт поки не буде дорівнювати

jl min ; перехід, якщо а1(і) < а2(і)

mov bx, 0 ; bx ← 0 якщо а1(і) > а2(і)

jmp m1 ; безумовний перехід на мітку m1

min: mov bx, 1 ; bx ← 1 якщо а1(і) < а2(і)

m1: mov ah, 4Ch ; код успішного завершення програми

int 21h ; exit DOS

end start ; кінець програми

Вікна налагоджувача Emu8086 v.2.57 при налагодженні програми

прикладу 8.10 наведено на рис. 8.14.

Команда SCAS виконує віднімання з операнда, адреса якого роз-

ташовується в регістрі DI операнда з регістра AL (АХ чи EAX), впливає

на біти умов, але не формує результату (SCAS [DI], AL/AX/EAX). У

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

пошуку входження деякої величини в рядок.

З префіксом REPE (або REPZ) дану команду можна використовува-

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

заданого значення. Якщо перед командою SCAS знаходиться префікс

Page 259: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

259

REPNE (або REPNZ), то операція інтерпретується як “переглядати доти,

поки не буде досягнутий кінець ланцюжка або значення елементу лан-

цюжка не буде дорівнювати відшукуваному значенню”.

Час виконання команди SCAS без префікса повторення складає 15

тактів, а з префіксом повторення – 9+15* (число повторень) тактів синх-

ронізації.

Для явної вказівки типу елементів ланцюжка звичайно використо-

вуються мнемокоди SCASВ і SCASW; при цьому операнд в команді від-

сутній.

Сканування для збіжних символів

Приклад 8.11. Сканувати рядок символів доти, поки символ F не бу-

де знайдений.

Коли символ F буде виявлений, регістр DI указуватиме на перший

байт після цього символу і значення регістра треба декременувати, щоб

він вказував на символ F: .MODEL tine ; коди та дані займають не більше 64 кбайт DATA SEGMENT ; початок сегмента даних

mas db ‘abcdefgh’ ; масив байт з іменем mas із символами коду ASCII

Рис. 8.14. Вікна налагоджувача Emu8086 v.2.57 при налагодженні програми

прикладу 8.10

Page 260: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

260

DATA ENDS ; кінець сегмента даних .CODE

start: mov ax, @DATA mov es, ax lea di, mas ; завантаження адреси масиву mas mov al, ‘f’ ; завантаження символу ‘f’ mov cx, 8 ; встановити в лічильник max значення літерів cld ; напрям – вгору

repne scasb ; повторювати поки не буде дорівнювати dec di ; знайдений: декременувати DI mov ah, 4Ch ; код успішного завершення програми int 21h ; exit DOS end start ; кінець програми start

Вікна налагоджувача Emu8086 v.2.57 при налагодженні програми

прикладу 8.11 наведено на рис. 8.15.

Відразу після того, як команда SCASB буде виконана, DI вкаже на

символ, що іде за шуканим символом.

Рис. 8.15. Вікна налагоджувача Emu8086 v.2.57 при налагодженні програми

прикладу 8.11

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 261: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

261

Використання команд умовного переходу. Відразу після виконан-

ня команди CMPSB ще неможливо визначити, що саме стало причиною

її завершення: те, що СХ = 0, або те, що відповідний символ вже знайде-

ний, причому і те, і інше може відбутися одночасно.

При використанні префікса REPNZ звичайно використовують ко-

манду JNZ для переходу, коли символ знайдений. В цьому випадку ке-

руються таким принципом: якщо прапорець нуля скинутий, символ не

знайдений, а якщо прапорець нуля встановлений, то символ знайдений:

repnz cmpsb

jnz not_found

або:

repnz cmpsb

jz found

Може виникнути помилка при використанні команди JCXZ при ух-

валенні рішення після того, як символ знайдений. Символ може бути

знайдений в самій останній позиції, і СХ стане дорівнювати нулю після

останнього порівняння. Тому наступні команди будуть помилковими:

repnz scasb

jcxz exit

Приклад 8.12. Задано рядки А і В (констант типу BYTE). У всіх

байтах рядка А замінити символи Х на відповідні символи із масиву В.

Програма може бути такою: .model small ; коди та дані займають <= 64 кбайт data segment ; початок сегмента даних

a db ‘atxfx’ ; масив байт з іменем a із символами коду ASCII b db ‘abcef’ ; масив байт з іменем b із символами коду ASCII

data ends ; кінець сегмента даних .code assume cs:code, ds:data st: mov ax,@data ; встановити адресу сегмента даних mov es,ax ; ініціювати ES для завдання ES:DI mov ds,ax ; ініціювати DS для завдання DS:SI cld ; напрям – вгору lea di,a ; завантаження адреси масиву a в di lea si,b ; завантаження адреси масиву b в si mov al,’x’ ; завантаження символу ‘x’ mov cx,5 ; кількість слів у масиві

Page 262: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

262

a2: scasb ; [di] – al jnz m1 ; перейти, якщо не нуль dec di ; повернення di mov bl,[si] mov [di],bl inc di ; встановлення di для порівняння

m1: inc si ; просування si loop a2 ; цикл, поки сх ≠ 0 mov ax,4c00h ; код успішного завершення програми int 21h ; exit DOS end st ; кінець програми st

Вікна налагоджувача Emu8086 v.2.57 при налагодженні програми

прикладу 8.12 наведено на рис. 8.16.

На рис. 8.16 наведено два вікна відображення пам’яті: праворуч –

до виконання, ліворуч – після виконання програми. По вмісту комірок

пам’яті й судять про правильність виконання програми.

Видалення додаткових пропусків. Команда SCASB може викорис-

товуватися для видалення зайвих пропусків в рядку з кодуванням

Рис. 8.16. Вікна налагоджувача Emu8086 v.2.57 при налагодженні програми

прикладу 8.12

Page 263: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

263

ASCIIZ. У наступному прикладі регістри ES:DI указують на останній

байт рядка, а СХ дорівнює довжині рядка, AL = 20h (символ пропуску) і

DF = 1. Для повторення циклу використовується префікс REРЕ, поки

значення регістра AL збігається із значенням в пам’яті.

.data

dest db "DESTINATION STRING ",0

destlen = $ - dest - l ; розрахунок довжини

.code

mov di, seg dest

mov es, di

mov di,offset dest ; встановити зсув рядка

add di, destlen - l ; вказати на останній байт

mov ex, destlen ; встановити лічильник

mov al, 20h ; порівняння з пропусками

std ; напрям – вниз

repe scasb ; сканування рядка

jnz exit ; пропусків більше немає

dec di скоректувати DI, якщо СХ = 0

exit:

mov byte ptr es:[di + 2],0 ; вставити нульовий байт

Після того, як буде знайдений перший символ, що не дорівнює про-

пуску, відразу після нього вставляється нульовий байт, внаслідок чого

змінюється довжина рядка. В даному випадку необхідні такі команди:

mov byte ptr [di + 2],0

Після виконання команди SCASB регістр DI указуватиме на остан-

ній символ перед початком пропусків. Для отримання позиції наступно-

го символу (тобто початку пропусків) необхідно до DI додати 2.

Команда LODS пересилає байт (чи слово) у регістр AL/AX/EAX із

пам’яті, адреса якого знаходиться в SI (LODS AL/AX/EAX, [SI]). Зви-

чайно ця команда не використовує префікс-повторювач.

У регістрах DS:SI міститься адреса операнда-відправника. Для ко-

манди необхідно указувати ім’я операнда-відправника. З командою

LODSB використовується 8-розрядний операнд, з командою LODSW –

16-розрядний операнд, і з командою LODSD – 32-розрядний. Прапорець

напряму визначає інкрементування або декрементування регістрів SI і

Page 264: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

264

DI.

Префікси повторення рідко використовуються з командами LODS,

тому що кожне нове значення, що завантажується в регістри AL або АХ,

руйнує їх колишні значення. Замість окремої команди LODSB можна

використовувати такі дві команди:

mov al, [si] ; перемістити байт за адресою DS:SI у AL

inc si ; вказати на наступний байт

Приклад 8.13. Просканувати буфер buffer та при цьому очистити

старший біт кожного байта і отримане значення зберегти в масиві output.

.data

buffer db 0C8h, 0FBh, 0F5h, 0CAh, 41h, 42h, 43h, 64h, 87h, 8Ch

output db 10 dup(1) ; попереднє заповнення масиву одиницями

.code

start: mov ax, @DATA

mov ds,ax

mov es, ax

mov si, offset buffer ;

mov di, offset output ;

mov cx, 10

cld ; напрям – вгору

L1: lodsb ; AL ← DS: [SI]

and al, 7Fh ; логічне перемноження

stosb ; AL ← ES:[DI]

loop L1 ; цикл, поки СХ ≠ 0

mov ah, 4Ch ; код успішного завершення

int 21h ; exit DOS

end start ; кінець програми start

На рис. 8.17 наведено вікно відображен-

ня пам’яті налагоджувача Emu8086 v.2.57 при

налагодженні програми прикладу 8.13, в яко-

му видно, що в комірках 0B67:0002 –

0B67:000B знаходиться масив buffer, а в комі-

рках 0B67:000C – 0B67:0015 – масив output.

При виконанні цього фрагмента виходять

такі значення у вихідному рядку (повторю-

ється кожен початковий байт зі скинутим ста-

Рис. 8.17. Вікно відобра-

ження пам’яті відладчика

Emu8086 v.2.57 при налаго-

дженні програми прикла-

ду 8.13

Page 265: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

265

ршим бітом):

48 7В 75 4А 41 42 43 64 07 0С

Попереднє заповнення масиву output одиницями корисно викорис-

товувати на етапі налагодження програми для візуального контролю за-

повнення елементів пам’яті.

Команда STOS пересилає байт (чи слово) з регістра АН/AX/EAX за

адресою ES:DI (STOS [DI], AL/AX/EAX). З використанням префікса-

повторювача вона може використовуватись для заповнення рядка визна-

ченою величиною.

З префіксом повторення ця команда є зручним засобом ініціалізації

ланцюжка на фіксоване значення, наприклад нуль або пропуск. Час ви-

конання команди STOS без префікса повторення складає 11 тактів, а з

префіксом повторення 9+10 * (число повторень) тактів синхронізації.

Регістри ES:DI містять адресу операнда-одержувача. З командою

STOSB використовується 8-розрядний операнд, з командою STOSW –

16-розрядний операнд і з командою STOSD – 32-розрядний.

Прапорець напряму визначає інкрементування або декрементуван-

ня регістрів SI та DI.

Також можна використовувати STOS для ініціалізації пам’яті єди-

ним значенням.

Приклад 8.14. Заповнити кожен байт рядка stringl значенням 0FFh

та вивести повідомлення про успішне закінчення програми.

; варіант 1

.model small

.data

string1 db 5 dup(?)

text1 db "end labrab",’$’

.code

start: mov ax, @data

mov es, ax

mov cx, 5

mov al, 0ffh

cld

rep stosb

mov ax, @data ; ініціалізація сегментного регістра

mov ds, ax ;

Page 266: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

266

mov ah, 9h ; функція DOC виведення на екран

mov dx, offset text1 ; адреса повідомлення

int 21h ; виклик DOC

mov ax, 4C00h ; код успішного завершення програми

int 21h ; exit DOS

end start ;

; варіант 2

.data

stringl db 100 dup(?)

.code

mov di, seg stringl

mov es,di

mov al, 0FFh ; значення для заповнення

mov di, offset stringl ; ES:DI – адреса одержувача

mov сx,100 ; лічильник символів

eld ; напрям – вгору

rep stosb ; заповнити вмістом AL

Приклад. Необхідно порівняти два масиви байт, що знаходяться в

пам’яті, і при рівності елементів вийти з циклу. Припустимо, що регістр

SI адресує поточний елемент першого масиву, регістр DI – поточний

елемент другого масиву, а вміст регістра СХ є довжиною масивів. Тоді

стандартна програма порівняння масивів байт набуває такого вигляду:

A1: MOV AL, [SI] ; елемент першого масиву

CMP [DI], AL ; порівняти

JZ A2 ; елементи рівні

INC SI ; просунути покажчики

INC DI

DEC СХ ; перевірити закінчення

JNZ A1

A2: …

При розподілі регістрів завдання порівняння масивів розв’язується

набагато коротшим фрагментом:

REPNZ CMPSB

JZ A2

Команда STOS зручна для ініціалізації областей даних на конкретне

Page 267: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

267

значення. Наступна програма скидає масив слів з початковою адресою

ARRAY і довжиною, визначуваною змінною LENGTH:

LES DI, ARRAY ; адреса в ES: DI

MOV СХ, LENGTH ; довжина в СХ

MOV АХ, 0 ; початкове значення

REP STOSW ; ініціалізація

8.2.2. Завдання для самостійного дослідження команд обробки

ланцюжків 1. Дано текст, що складається з 6 слів по 8 символів, розділених

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

2. Задано послідовність латинських букв завдовжки 18 символів. Розставити їх за абеткою.

3. Задано текст із 30 символів. Стиснути текст, залишивши між словами по одному пропуску.

4. Задано текст із 20 символів. Визначити кількість повторень по-єднань "ОР" в тексті і замінити його символом "!".

5. Задано текст із 35 символів. Визначити кількість слів, які містять більше 3-х символів. Слова розділяються одним пропуском.

6. Задано текст із 8 слів по 6 символів. У словах з парним номером змінити порядок букв на зворотний.

7. Побудувати послідовність з n (n ≤ 30) символів наступного ви-гляду: АББВВВГГГГДДДДДЕЕЕЕЕЕ...

8. Побудувати послідовність вигляду АААБББББСССССС із 40 символів по заданій таблиці, що містить символ і кількість його повто-рень. Наприклад: А – 3 рази; Б – 5 разів; C – 6 разів та т.д.

9. Задано текст із 32 символів, що складається із слів, розділених одним пропуском. Визначити кількість слів і кількість букв в кожному слові.

10. Задано текст із 34 символів, що складається із слів, розділених одним пропуском. Визначити кількість слів, в яких буква Е зустрічається більш ніж 2 рази.

11. Дана послідовність із 37 символів. Визначити частоту повто-рення кожного символу.

12. Дано 8 слів по 6 символів. На початку кожного слова записаний номер з двох символів. Розставити слова за збільшенням номерів.

13. Задано текст із 15 слів, розділених пропуском. Визначити кіль-

Page 268: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

268

кість слів, в яких буква “А” зустрічається більш 3-х разів. 14. Задано текст із 10 слів, розділених пропусками (одним і більш).

Визначити кількість слів, що містять більше 4 символів. 15. Задано текст із 8 слів, розділених пропуском. Визначити кіль-

кість повторень букви “Е” в кожному слові. 16. Задано текст із 12 слів, розділених пропуском. Розставити слова

відповідно до латинського алфавіту. 17. Задано текст із 26 символів. Визначити кількість різних симво-

лів і частоту їх повторень. 18. Задано текст, що складається з 5 слів по 7 символів. Розставити

слова відповідно до російського алфавіту. 19. Задано текст, що складається з 10 слів, розділених деякою кіль-

кістю пропусків. Визначити кількість букв “А” в кожному слові. 20. Задано текст, що складається з 8 слів по 5 символів. Визначити

кількість голосних букв в кожному слові. 21. Задано текст, що складається з 4 слів по 8 символів. Визначити

кількість різних букв в кожному слові. 22. Задано текст, що складається з 7 слів по 5 символів. Видалити

слова, що містять більш 3-х букв “О”. 23. Задано текст, розділений на слова пропусками. Змінити порядок

букв в словах на протилежний. 24. Задано текст із 25 символів. Знайти слова, порядок букв в яких

зворотний по відношенню до першого слова. (Слова розділені пропус-ками).

25. Задано текст із 18 символів: 3 слова по 6 символів. Здійснити кі-льцеве зрушення кожного слова: 1-го – на 1 символ вліво; 2-го – на 2 символи; 3-го – на 3 символи.

8.3. Структури

Масиви є сукупністю однотипних елементів. У додатках виникає

необхідність розглядати деяку сукупність даних різного типу як деякий

єдиний тип. Це дуже актуально, наприклад, для програм баз даних, де

необхідно пов’язувати сукупність даних різного типу з одним об’єктом.

Структура – це тип даних, що складається з фіксованого числа

елементів різного типу.

Для використання структур в програмі необхідно виконати три дії:

1. Задати шаблон структури. По сенсу це означає визначення но-

вого типу даних, який згодом можна використовувати для визначення

змінних цього типу.

Page 269: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

269

2. Визначити екземпляр структур. Цей етап має на увазі ініціалі-

зацію конкретної змінної наперед певною (за допомогою шаблону) стру-

ктурою.

3. Організувати звернення до елементів структури.

Описати структуру в програмі – означає лише вказати її схему або

шаблон; пам’ять при цьому не виділяється. Цей шаблон можна розгляда-

ти лише як інформацію для транслятора про розташування полів і їх зна-

чення за умовчанням.

Визначити структуру – означає дати вказівку транслятору виділити

пам’ять і привласнити цій області пам’яті символічне ім’я.

Описати структуру в програмі можна тільки один раз, а визначити –

будь-яку кількість разів.

Опис шаблону структури

Опис шаблону структури має такий синтаксис:

Ім’я_структури STRUC

<опис полів>

Ім’я_структури ENDS

Тут <опис полів> є послідовністю директив опису даних db, dw, dd,

dq і dt.

Їх операнди визначають розмір полів і, при необхідності, початкові

значення. Цими значеннями, можливо, ініціалізуються відповідні поля

при визначенні структури.

Місцеположення шаблону в програмі може бути довільним, але,

відповідно до логіки роботи однопрохідного транслятора, він повинен

бути розташований до того місця, де визначається змінна з типом даної

структури. Тобто при описі в сегменті даних змінної з типом деякої

структури її шаблон необхідно помістити на початку сегмента даних або

перед ним.

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

даних про співробітників деякого відділу. Для простоти, щоб піти від

проблем перетворення інформації при введенні, умовимося, що всі поля

символьні.

Визначимо структуру запису цієї бази даних таким шаблоном: worker struc ; інформація про співробітника nam db 30 dup (‘ ‘) ; фамілія, ім’я, по батькові

Page 270: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

270

sex db ‘м’ ; стать, за умовчанням ‘м’ – чоловіча position db 30 dup (‘ ‘) ; посада age db 2 dup(‘ ‘) ; вік standing db 2 dup(‘ ‘) ; стаж salary db 4 dup(‘ ‘) ; оклад birthdate db 8 dup(‘ ‘) ; дата народження worker ends

Визначення даних з типом структури

Для використання описаної за допомогою шаблону структури в про-

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

використовується така синтаксична конструкція:

[ім’я змінної] ім’я_структури <[список значень]>

Тут:

– ім’я змінної – ідентифікатор змінної даного структурного типу.

Завдання імені змінної необов’язкове. Якщо його не вказати, буде прос-

то виділена область пам’яті розміром в суму довжин всіх елементів

структури.

– список значень – взятий в кутові дужки список початкових зна-

чень елементів структури, розділених комами. Його завдання також не-

обов’язкове. Якщо список вказаний не повністю, то всі поля структури

для даної змінної ініціалізувалися значеннями з шаблону, якщо такі за-

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

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

значеннями з шаблону структури. Якщо при визначенні нової змінної з

типом даної структури ми згодні зі всіма значеннями полів в її шаблоні

(тобто заданими за умовчанням), то потрібно просто написати кутові

дужки. Наприклад: victor worker <>.

Для прикладу визначимо декілька змінних з типом описаної вище

структури.

data segment

sotr1 worker <‘Гурко А. В.’, ‘художник’, ‘33’, ‘15’, ‘1800’, ‘26.01.64’<

sotr2 worker <‘Михайлова Н. Г.’,’ж’, ‘програміст’, ‘30’, ‘10’, ‘1680’,

‘27.10.58’<

sotr3 worker <‘Степанов Ю. Л.’, ‘художник’, ‘38’,’20’, ‘1750’, ‘01.01.58’<

sotr4 worker <‘Юрова Е. А.’,’ж’, ‘зв’язківець’,’32’,’2’, ‘09.01.66’<

sotr5 worker <> ; тут всі значення за умовчанням

data ends

Page 271: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

271

Методи роботи із структурою

Ідея введення структурного типув будь-яку мову програмування по-

лягає в об’єднанні різнотипних змінних в один об’єкт. У мові повинні

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

структури. Для того, щоб послатися в команді на полі деякої структури,

використовується спеціальний оператор – символ “.” (крапка). Він вико-

ристовується в такій синтаксичній конструкції:

адресний_вираз.ім’я_поля_структури

Тут:

– адресний_вираз – ідентифікатор змінної деякого структурного ти-

пу або вираз в дужках відповідно до вказаних нижче синтаксичних пра-

вил;

– ім’я_поля_структури – ім’я поля з шаблону структури. Це, на-

справді, теж адреса, а точніше зсув поля від початку структури.

Таким чином оператор "." (крапка) обчислює вираз

(адресний_вираз) + (ім’я_поля_структури)

Продемонструємо на прикладі визначеної нами структури worker

деякі прийоми роботи із структурами. Наприклад, витягнути в ах зна-

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

більше величини 99 років, то після приміщення вмісту цього символьно-

го поля в регістр ах його буде зручно перетворити в двійкове уявлення

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

“молодший байт за молодшою адресою” старша цифра віку буде помі-

щена в al, а молодша – в ah. Для коректування досить використовувати

команду xchg al,ah: mov ах,word ptr sotr1.age ; в al вік sotr1 xchg ah,al а можна і так: lea bx,sotr1 mov ах,word ptr [bx].age xchg ah,al

Якщо співробітників не четверо, а набагато більше, і до того ж їх

число і інформація про них постійно міняються, то в цьому випадку

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

тних осіб. Мова асемблеру дозволяє визначати не тільки окрему змінну з

Page 272: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

272

типом структури, але і масив структур. Наприклад, визначимо масив з 10

структур типу worker:

mas_sotr worker 10 dup (<>)

Подальша робота з масивом структур проводиться так само, як і з

одновимірним масивом. Аналогічно іншим ідентифікаторам, визначеним

в програмі, транслятор призначає імені типу структури і імені змінної з

типом структури атрибут типу. Значенням цього атрибуту є розмір в

байтах, займаний полями цієї структури. Витягнути це значення можна з

допомогою оператора type. Після того, як став відомий розмір екземп-

ляра структури, організувати індексацію в масиві структур можна без

особливих труднощів.

Наприклад: worker struc ... worker ends ... mas_sotr worker 10 dup (<>) ... mov bx,type worker ; bx=77 lea di,mas_sotr

; витягнути і вивести на екран поля всіх співробітників:

mov cx,10

cycl:

mov al[di].sex

...

; виведення на екран вмісту поля sex структури worker

add di,bx ; к наступній структурі в масиві mas_sort

loop cycl

Як виконати копіювання поля з однієї структури у відповідне поле

іншої структури? Або як виконати копіювання всієї структури? Давайте

виконаємо копіювання поля nam третього співробітника в полі nam

п’ятого співробітника: worker struc ... worker ends ... mas_sotr worker 10 dup (<>)

Page 273: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

273

... mov bx,offset mas_sotr mov si(type worker)*2 ; si = 77*2 add si,bx mov di(type worker)*4 ; si = 77*4 add di,bx mov cx,30 rep movsb

Наявність в мові наступних двох типів даних пояснюється прагнен-

ням максимально ефективно використовувати оперативну пам’ять для

розміщення даних програми.

8.4. Об’єднання

Об’єднання – тип даних, що дозволяє трактувати одну і ту ж об-

ласть пам’яті як що має різні типи і імена.

Опис об’єднань в програмі нагадує опис структур, тобто спочатку

описується шаблон, в якому за допомогою директив опису даних пере-

раховуються імена і типи полів:

ім’я _об’єднання UNION

<опис полів>

ім’я _об’єднання ENDS

Відмінність об’єднань від структур полягає, зокрема, в тому, що при

визначенні змінної типу об’єднання пам’ять виділяється відповідно до

розміру максимального елементу. Звернення до елементів об’єднання

відбувається по їх іменах, але при цьому потрібно, звичайно, пам’ятати

про те, що всі поля в об’єднанні накладаються один на одного. Одночас-

на робота з елементами об’єднання виключена. Як елементи об’єднання

можна використовувати і структури.

Розглянемо приклад, який окрім демонстрації використання власне

типу даних “об’єднання” показує можливість взаємного вкладення

структур і об’єднань. Основна ідея тут в тому, що указівник на

об’єднання може бути зображений у вигляді:

– 16-бітового зсуву;

– 32-бітового зсуву;

– пари з 16-бітового зсуву і 16-бітової сегментної складової адреси;

– пари з 32-бітового зсуву і 16-бітового селектора.

Page 274: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

274

Які з цих указівників можна застосовувати в конкретній ситуації,

залежить від режиму адресації (use16 або use32) і режиму роботи мік-

ропроцесора. Наведений приклад шаблону об’єднання дозволяє полег-

шити формування і використання указівників різних типів.

; Приклад використання об’єднання masm model small stack 256 .586P pnt struc ; структура pnt, що містить вкладене об’єднання union ; опис вкладеного в структуру об’єднання offs_16 dw ? offs_32 dd ? ends ; кінець опису об’єднання segm dw ? ends ; кінець опису структури .data point union; визначення об’єднання, що містить вкладену структуру off_16 dw ? off_32 dd ? point_16 pnt <> point_32 pnt <> point ends tst db ‘Рядок для тестування’ adr_data point <> ; визначення екземпляра об’єднання .code main: mov ах,@data mov ds,ax mov ах,seg tst

; записати адресу сегмента рядка tst в полі структури adr_data mov adr_data.point_16.segm,ax

; можна витягнути значення з цього поля назад, наприклад, в регістр bx: mov bx,adr_data.point_16.segm

; формуємо зсув в полі структури adr_data mov ах,offset tst ; зміщення рядка в ах mov adr_data.point_16.offs_16,ax

; аналогічно можна витягнути значення з цього поля: mov bx,adr_data.point_16.offs_16

Page 275: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

275

exit: mov ах,4c00h int 21h end main

8.5. Записи

TASM надає спеціальний тип даних, використання якого допомагає

вирішити проблему роботи з бітами ефективніше. Йдеться про спеціаль-

ний тип даних – записи.

Запис – структурний тип даних, що складається з фіксованого числа

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

кожного елемента указується його довжина в бітах і, що необов’язково,

деяке його значення. Сумарний розмір запису визначається сумою роз-

мірів його полів і не може бути більше 8, 16 або 32 біт. Якщо сумарний

розмір запису менший від вказаних значень, то всі поля запису “притис-

каються” до молодших розрядів.

Використання записів в програмі, так само, як і структур, організо-

вується в три етапи:

1. Завдання шаблону запису, тобто визначення набору бітових по-

лів, їх довжин і, при необхідності, ініціалізація полів.

2. Визначення екземпляра запису. Так само, як і для структур, цей

етап передбачає ініціалізацію конкретної змінної типом наперед визна-

ченого за допомогою шаблону запису.

3. Організація звернень до елементів запису

Компілятор TASM, окрім стандартних засобів обробки записів, під-

тримує також і деякі додаткові можливості їх обробки.

Опис запису

Опис шаблону запису має такий синтаксис:

ім’я _запису RECORD <опис елементів>

Тут: < опис елементів > є послідовністю описів окремих елементів

запису згідно з синтаксичною діаграмою.

При описі шаблону пам’ять не виділяється, оскільки це всього лише

інформація для транслятора асемблеру про структуру запису. Так само,

як і для структур, місцеположення шаблону в програмі може бути будь-

яким, але при цьому необхідно враховувати логіку роботи однопрохід-

ного транслятора.

Page 276: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

276

Розглянемо декілька варіантів ініціалізації.

Якщо ініціалізація поля не потрібна, то достатньо вказати знак ? при

визначенні екземпляра запису:

...

iotest record

i1:1,i2:2=11,i3:1,i4:2=11,i5:2=00

...

flag iotest ?

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

всі поля змінної типу запис flag обнуляються. Це відбувається незважа-

ючи на те, що у визначенні запису задано початкові значення полів.

Якщо потрібна часткова ініціалізація елементів, то вони беруться в

кутові (< і >) або фігурні ({ і }) дужки. Відмінність тут в тому, що в ку-

тових дужках елементи повинні бути задані в тому ж порядку, що і у

визначенні запису. Якщо значення деякого елемента збігається з почат-

ковим, то його можна не указувати, але треба обов’язково позначити

його комою. Для останніх елементів що йдуть підряд коми можна опус-

тити. Наприклад, погодитися із значеннями за умовчанням можна так:

iotest record

i1:1,i2:2=11,i3:1,i4:2=11,i5:2=00

...

flag iotest <> ; згодилися із значенням за умовчанням

Змінити значення поля i2 можна так:

iotest record

i1:1,i2:2=11,i3:1,i4:2=11,i5:2=00

...

flag iotest <,10,> ; перевизначили i2

Застосовуючи фігурні дужки, також можна вказати вибіркову ініціа-

лізацію полів, але при цьому необов’язково позначати комами поля, із

значеннями за умовчанням яких ми згодні:

iotest record

i1:1,i2:2=11,i3:1,i4:2=11,i5:2=00

...

Flag iotest {i2=10}; перевизначили i2, не звертаючи уваги на поря-

док

; проходження інших компонентів запису

Page 277: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

277

Робота із записами

Як організувати роботу з окремими елементами запису? Звичайні

механізми адресації тут безсилі, оскільки вони працюють на рівні елеме-

нтів пам’яті, тобто байтів, а не окремих бітів. Перш за все для розуміння

проблеми потрібно засвоїти декілька моментів:

Кожному імені елемента запису асемблер привласнює числове

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

для того, щоб цей елемент виявився “притиснутим” до початку комірки.

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

цього потрібно знати довжину елемента в бітах.

Зрушення управо проводиться за допомогою команди зрушення

shr.

Асемблер містить оператора width, який дозволяє дізнатися про

розмір елемента запису в бітах або повністю про розмір запису. Варіанти

застосування оператора width:

width ім’я _елемента_запису

; значенням оператора буде розмір елемента в бітах.

width ім’я _екземпляра_запису

або

width ім’я _типу_запису

; значенням оператора буде розмір всього запису в бітах.

mov al,width i2

...

mov ах,width iotest

Асемблер містить оператора mask, який дозволяє локалізувати

біти потрібного елемента запису. Ця локалізація проводиться шляхом

створення маски, розмір якої збігається з розміром запису. У цій масці

обнулені біти на всіх позиціях, за винятком тих, які займають елемент в

запису.

Самі дії по перетворенню елементів запису проводяться за до-

помогою логічних команд.

Тепер є вся інформація про засоби асемблеру для роботи із записа-

ми. Безпосередньо звернутися до елемента запису неможливо. Щоб про-

вести обробку елемента, що цікавить, потрібно спочатку виділити, зру-

шити його, при необхідності, до молодших розрядів, виконати необхідні

Page 278: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

278

дії і помістити його назад на своє місце в запису. Тому, щоб не винахо-

дити кожного разу велосипед, далі опишемо типові алгоритми здійснен-

ня цих операцій над елементами запису. Ваше завдання – закодувати ці

алгоритми тим або іншим способом відповідно до вимог завдання.

Виділення елемента запису:

Помістити запис в тимчасову пам’ять – регістр (8-/16-/32-

бітовий залежно від розміру запису).

Одержати бітову маску, відповідну до елемента запису, за допо-

могою оператора mask.

Локалізувати біти в регістрі за допомогою маски і команди and.

Зрушити біти елемента до молодших розрядів регістра коман-

дою shr. Число розрядів для зрушення одержати з використанням імені

елемента запису.

У результаті цих дій елемент запису буде локалізований на початку

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

Робота з елементом запису:

Як ми вже з’ясували, з елементами запису проводяться будь-які дії,

як над звичайною двійковою інформацією. Єдине, що потрібно відсте-

жувати, – це розмір бітового поля. Якщо, наприклад, розмір поля збіль-

шиться, то згодом може відбутися випадкова зміна сусідніх полів бітів.

Тому бажано виключити зміну розміру поля.

Поміщення зміненого елемента на його місце в запис:

Використовуючи ім’я елемента запису як лічильник зрушень,

зрушити вліво біти елемента запису.

Якщо ви не упевнені в тому, що розрядність результату перетво-

рень не перевищила початкову, можна виконати “обрізання” зайвих бі-

тів, використовуючи команду and і маску елемента.

Підготувати початковий запис до вставки зміненого елемента

шляхом обнулення бітів в записі на місці цього елемента. Це можна зро-

бити шляхом накладення командою and інвертованої маски елемента

запису на початковий запис.

За допомогою команди or накласти значення в регістрі на поча-

тковий запис.

Розглянемо приклад, який обнуляє поле i2 у запису iotest.

; Робота з полем запису

Page 279: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

279

masm model small stack 256 iotest record i1:1,i2:2=11,i3:1,i4:2=11,i5:2=00 .data flag iotest <> .code main: mov ах,@data mov ds,ax mov al,mask i2 shr al,i2 ; біти i2 на початку ах and al,0fch ; обнулили i2

; поміщаємо i2 на місце shl al,i2 mov bl[flag] xor bl,mask i2 ; скинули i2 or bl,al ; exit: mov ах,4c00h ; стандартний вихід int 21h end main ; кінець програми

Якщо знадобиться змінити розмір елемента або його початкове зна-

чення, досить внести зміни в екземпляр запису або в опис його типу;

функціональну частину програми, що працює з цим записом, чіпати не

потрібно.

Записи: додаткові можливості обробки

Розуміючи важливість ефективного програмування такого типу да-

них, як запис, розробники транслятора TASM, починаючи з версії 3.0,

включили в систему його команд дві додаткові команди на правах дире-

ктив. Останнє означає, що ці команди зовні мають формат звичайних

команд асемблеру, але після трансляції вони приводяться до однієї або

декількох машинних команд. Введення цих команд в мову TASM підви-

щує наочність роботи із записами, оптимізує код і зменшує розмір про-

грами. Ці команди дозволяють приховати від програміста дії по виділен-

ню і установці окремих полів запису.

Page 280: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

280

Для установки значення деякого поля запису використовується ко-

манда setfield з синтаксисом:

setfield ім’я _елемента_запису призначення, регістр_джерело

Для вибірки значення деякого поля запису використовується коман-

да getfield з синтаксисом:

getfield ім’я _елемента_запису призначення, регістр_джерело

Робота команди setfield полягає ось в чому. Місцеположення запису

визначається операндом призначення, який може бути ім’ям регістра

або адресою пам’яті. Операнд ім’я _елемента_запису визначає елемент

запису, з яким ведеться робота (по суті, якщо ви були уважні, він визна-

чає зсув елемента в запису щодо молодшого розряду). Нове значення, в

яке необхідно встановити вказаний елемент запису, повинне міститися в

операнді регистр_джерело. Обробляючи дану команду, транслятор ге-

нерує послідовність команд, які виконують наступні дії:

зрушення вмісту регістр_джерело вліво на кількість розрядів,

відповідну розташуванню елемента в запису;

логічну операцію or над операндами призначення і ре-

гістр_джерело. Результат операції поміщається в операнд призначення.

Команда setfield не проводить попереднього очищення елемента, в

результаті після логічного складання командою or можливо накладення

старого вмісту елемента і нового встановлюваного значення. Тому пот-

рібно заздалегідь підготувати поле в запису шляхом його обнулення.

Як операнд джерело може бути вказане або регістр або адреса

пам’яті. У регістр, вказаний операндом регістр_призначення, поміща-

ється результат роботи команди – значення елемента запису. Цікава осо-

бливість пов’язана з операндом регістр_призначення. Команда getfield

завжди використовує 16-бітовий регістр, навіть якщо ви вкажете в цій

команді ім’я 8-бітового регістра.

Як приклад розглянемо застосування команд setfield і getfield.

; Робота з полями запису masm model small stack 256 iotest record i1:1,i2:2=11,i3:1,i4:2=11,i5:2=00 .data

Page 281: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

281

flag iotest <> .code main: mov ах,@data mov ds,ax mov al,flag mov bl,3 setfield i5 al,bl xor bl,bl getfield i5 bl,al mov bl,1 setfield i4 al,bl setfield i5 al,bl exit: mov ах,4c00h ; стандартний вихід int 21h end main ; кінець програми

Результат роботи команд setfield і getfield найзручніше вивчати у

налагоджувачі. При установці значень полів не проводиться їх поперед-

нє очищення. Це зроблено спеціально. Для такого роду операцій краще

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

ризик внесення помилок, які важко виявити і виправити. Як такий меха-

нізм можна запропонувати механізм макрозасобів.

Розглянемо регістр eflags. Для зручності цей опис розбитий на три

частини: – eflags_1_7 – молодший байт eflags/flags; – eflags_8_15 – другий байт eflags/flags; – eflags_h – старша половина eflags. eflags_l_7 record sf7:1=0,zf6:1=0,c5:1=0,af4:1=0,c3:1=0,pf2:1=0,c1:=1,cf0:1=0 eflags_l_15 record c15:1=0,nt14:1=0,iopl:2=0,of11:1=0,df10:1=0,if9:1=1,tf8:1=0 eflags_h record c:13=0,ac18:1=0,vm17:1=0,rf16:1=0

Цей опис необхідний при написанні макросу при роботі з виявлен-

ням помилок.

Page 282: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

282

9. ПІДПРОГРАМИ

9.1. Прямий виклик підпрограм

При цьому способі користуються командою call з вказівкою в якості

операнда імені підпрограми, що викликається. Такий виклик наочний,

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

викликати іншу підпрограму, необхідно змінити початковий текст і пе-

ретранслювати програму.

Непрямі виклики підпрограм. Більшою гнучкістю визначаються

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

а з елементів пам’яті або регістрів; у коді команди міститься інформація

про те, де знаходиться адреса переходу. Змінюючи програмним чином

вміст call комірок, що адресуються командою, або регістрів, тобто заси-

лаючи в них адресу тієї або іншої підпрограми, можна програмно на-

строїти команду call на виклик потрібної зараз підпрограми.

У прикладі 9.1 наведено ілюстрацію непрямого виклику з викори-

станням для адреси підпрограми елемента пам’яті, що викликається.

Приклад 9.1. Непрямий виклик підпрограм:

main ргос

; виведемо за допомогою функції DOS 09h повідомлення prompt

; поставимо запит на введення символа

inpt: mov AH,01h ; функція введення символа з луною

int 21h

cmp AL,’y’ ; натиснута клавіша ‘у’?

je mode_dos ; так, працюємо з DOS

cmp AL,’n’ ; натиснута клавіша ‘п’?

je modejnos ; так, працюємо з BIOS

jmp inpt ; натиснуте незаплановане. Повторити введення

mode_dos: mov addr,offset dos ; зашлемо адресу процедури dos

jmp cont ; і на продовження

mode_bios: mov addr,offset bios ; зашлемо адресу процедури bios

Page 283: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

283

cont: call DS:addr ; непрямий виклик процедури

; Завершимо програму

main endp

dos ргос ; процедура виведення засобами DOS

mov AH,09h

mov DX,offset mesl

int 21h

ret

dos endp

bios ргос ; процедура виведення засобами BIOS

; очистимо екран

mov AH,06h ; функція завдання вікна

mov AL,0 ; режим створення вікна

mov BH,07h ; атрибут всіх символів у вікні (ч/б)

mov CX,0 ; координати верхнього лівого кута

mov DН,79 ; нижня Y-координата

mov DL,24 ; права Х-координата

int 10h ; переривання BIOS

; виведемо рядок

mov AH,13h ; функція виведення рядка

mov AL,0 ; режим 0 (атрибут в BL)

mov ВН,0 ; відеосторінка

mov BL,0Eh ; атрибут всіх символів

mov CX,len ; довжина рядка

mov DH,12 ; початкова позиція – рядок

mov DL,20 ; початкова позиція – стовпець

push DS ; набудуємо

pop ES ; ES на наш сегмент даних

mov BP, offset mes2 ; ES:BP – рядок, що виводиться

int 10h ; переривання BIOS

; позиціонуємо курсор в початок останнього рядка екрана

mov AH,02h ; функція позиціонування

mov BH,0 ; відеосторінка

mov DН,24 ; рядок

mov DL,0 ; стовпець

int 10h ; переривання BIOS

ret ; повернення з переривання

Page 284: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

284

bios endp

; Поля даних

addr dw 0 ; поле для адреси підпрограми

prompt db ‘Драйвер ANSI.SYS встановлений? [Y/N] : $’

mes1 db 27,’[2J’,27,’[12;20H’,27,’[31;1m Начинаємо працювати’

db ‘, використовуючи засоби DOS’

db 27,’[0m’,27,’[25;lH$’

mes2 db ‘Починаємо працювати, використовуючи засоби BIOS’

len=$-mes2

У програмі є головна процедура main і дві процедури-підпрограми:

dos і bios. Обидві виконують очищення екрана і виведення в середину

екрана “свого” кольорового рядка “Починаємо працювати...”. Процедура

dos використовує для очищення екрану позиціонування курсора і за-

вдання кольору Esc-послідовності і, отже, може функціонувати тільки за

наявності в системі драйвера ANSI.SYS. Процедура bios виводить на

екран те ж саме, але засобами BIOS і не потребує драйвера ANSI.SYS.

Для наочності в процедурах для символів, що виводяться, використову-

ються різні кольори.

Основна процедура виводить на екран запитання про наявність в си-

стемі драйвера ANSI.SYS і вводить в програму відповідь користувача у

вигляді символів у (так) або n (ні). Далі введений символ аналізується;

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

mode_dos або mode_bios. У пропозиціях з цими мітками комірка addr

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

рка addr виконується команда call DS:addr, яка і здійснює непрямий пе-

рехід.

Указання перед ім’ям елемента пам’яті позначення сегментного ре-

гістра, в даному випадку DS, задає швидкість виклику. Також можна

скористатися описувачем word ptr (word pointer, покажчик на слово):

call word ptr addr

Непрямі виклики можна виконувати за допомогою широкого набору

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

нести в один з базових або індексних регістрів, то команда виклику

спрощується:

mov BX,offset bios ; в BX адреса самої підпрограми

Регістрова адресація можлива і у тому випадку, коли адреса підпро-

Page 285: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

285

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

mov SI,offset addr ; в SI адреса комірки з адресою підпрограми

call [SI] ; непрямий виклик

9.2. Табличний виклик підпрограм

У тих випадках, коли програма з включеними до неї підпрограмами

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

програми можна розмістити в окремих процедурах (або призначити ним

вхідні мітки) і викликати по іменах. У гнучкіших програмних комплек-

сах буває зручно передбачити механізм виклику необхідної підпрограми

по її номеру. Така ситуація типова, зокрема, для програм DOS і BIOS.

Дійсно, для виклику необхідної функції DOS ми задаємо (у регістрі АН)

її номер і викликаємо за допомогою переривання int 21h диспетчера

DOS. Диспетчер витягує з регістра АН номер функції і активізує по цьо-

му номеру відповідну програму з числа тих, що містяться в DOS. Так

само викликаються і функції BIOS.

Переривання користувача. Програми обробки переривань (або

просто обробники переривань) відносяться до найважливіших програм-

них засобів персональних комп’ютерів. Запити на обробку переривань

можуть мати різну природу. Перш за все розрізняють апаратні перери-

вання, на відміну від периферійних пристроїв або інших компонентів

системи, і програмні переривання, що викликаються командою int, яка

використовується, зокрема, для програмного звернення до функцій DOS

і BIOS. Сигнали, збудливі апаратні переривання, можуть ініціюватися

ланцюгами самого процесора, наприклад, при спробі виконання операції

ділення на нуль (такі переривання називаються внутрішніми, або відмо-

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

реривання). Зовнішні апаратні переривання викликаються, наприклад,

сигналами мікросхеми таймера, сигналами від принтера або контролера

диска, натисненням або відпуском клавіші. Таким чином, можна говори-

ти про переривання трьох типів: внутрішні, зовнішні і програмні. Неза-

лежно від джерела, дії процесора по обслуговуванню переривання, що

надійшло, завжди виконуються однаково як для апаратних, так і для про-

грамних переривань. Ці дії звичайно називають процедурою перериван-

ня. Йдеться лише про реакцію самого процесора на сигнал переривання,

а не про алгоритми обробки переривання, що передбачаються користу-

Page 286: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

286

вачем в обробнику.

Самий початок оперативної пам’яті від адреси 0000h до 03FFh від-

водиться під вектори переривань – чотирьохбайтові області, в яких збе-

рігаються адреси програм обробки переривань (ПОП). У два старші

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

дших – відносна адреса точки входу в ПОП в сегменті. Вектори, як і від-

повідні їм переривання, мають номери, причому вектор з номером 0 роз-

ташовується, починаючи з адреси 0, вектор 1 – з адреси 4, вектор 2 – з

адреси 8 і т.д. Вектор з номером N займає, таким чином, байти пам’яті

від N*4 до N*4 + 3. Всього у виділеній під вектори області пам’яті помі-

щається 256 векторів.

Одержавши сигнал на виконання процедури переривання з певним

номером, процесор зберігає в стеку виконуваної програми поточний

вміст трьох регістрів процесора: регістра прапорів, CS і IP. Два останні

числа утворюють повну адресу повернення в перервану програму. Далі

процесор завантажує CS і IP з відповідного вектора переривань, здійс-

нюючи тим самим перехід на ПОП.

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

повернення з переривання iret (interrupt return, повернення з перериван-

ня), що виконує зворотні дії, – завантаження IP, CS і регістра прапорів із

стека, що приводить до повернення в основну програму в ту саму точку,

де вона була перервана.

Велика частина векторів переривань призначена для виконання пев-

них дій і автоматично заповнюється адресами системних програм при

завантаженні системи; частина векторів зарезервована для майбутніх

застосувань, а частина (конкретно з номерами 60h...66h) вільна і може

використовуватися в прикладних програмах.

Для того, щоб прикладний обробник одержував можливість керу-

вання в результаті переривання, його адресу слід помістити у відповід-

ний вектор переривання. Хоча вміст вектора переривань можна змінити

простою командою mov, проте краще використовувати спеціально пе-

редбачену функцію DOS 25h. При виклику функції 25h в регістр AL по-

міщається номер вектора, що модифікується, а в регістри DS:DX – повна

двословна адреса нового обробника.

Розглянемо методику використання в прикладній програмі перери-

вання користувача.

Приклад 9.2. Обробка переривань користувача:

new_65h ргос

Page 287: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

287

; процедура накладення на екран кольорового вікна для динамічного ; очищення екрана по ходу виконання програми

mov AH,06h ; функція завдання вікна mov AL,0 ; режим створення вікна mov BH,1Bh ; атрибут всіх символів у вікні:

; ясно-бірюзові символи, синій фон mov CX,0 ; координати верхнього лівого кута 0, 0 mov DH,24 ; нижня Y-координата mov DL,79 ; права X-координата int 10h ; переривання BIOS iret

new_65h endp main proc mov ах,data mov ds,ax

; заповнимо вектор переривання користувача адресою нашого обробника mov AH,25h ; функція заповнення вектора переривання mov AL,65h ; номер вектора mov DX,offset new_65h ; зсув прикладного обробника push DS ; збережемо DS push CS ; настроємо DS на сегмент команд pop DS ; у якому знаходиться обробник int 21h pop ds ; відновлення

; виведення на екран рядка з попереднім очищенням екрана gogo: int 65h ; виклик прикладного обробника ; (очищення екрана перед виведенням тексту) ; позиціонуємо курсор

mov AH,02h ; функція позиціонування mov BH,0 ; відеосторінка mov DH,line ; рядок mov DL,coloumn ; стовпець int 10h ; переривання BIOS

; виведемо на екран рядок символів mov AH,0Ah ; функція виведення символа без атрибута mov AL,sym ; символ mov BH,0 ; відеосторінка mov CX,60 ; коефіцієнт повторення int 10h ; переривання BIOS

; змінимо символ і позицію і зациклимо програму з можливістю її завершення inc sym ; наступний символ по таблиці ASCII

Page 288: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

288

inc line ; наступний рядок екрана mov AH,08h ; функція введення без луни, чутлива <Ctrl>/C int 21h jmp gogo ; нескінченний цикл

main endp ; Поля даних line db 2 ; рядок coloumn db 10 ; стовпець sym db 01 ; символ, що виводиться

Процедура new_65h, що викликається за допомогою програмного

переривання виконує просту операцію – очищає екран, накладаючи на

нього вікно із заданим атрибутом.

У основній програмі перш за все заповнюється вектор переривання

65h. Оскільки функція заповнення вектора 25h вимагає, щоб адреса при-

кладного обробника містилася в парі регістрів DS:DX, а DS у нас указує

на сегмент даних, перед викликом DOS в DS слід занести сегментну ад-

ресу того сегмента, в якому знаходиться обробник, тобто, в нашому ви-

падку, загального сегмента команд. Ця адреса витягується з CS.

Далі в нескінченному циклі виконується виклик нашого обробника,

позиціонування курсора за допомогою функції 02h BIOS і виведення на

чистий екран рядка символів (функцією 0Ah BIOS). Ця функція не до-

зволяє задавати атрибути символів, що виводяться. Після виведення на

екран рядка виконується зміна коду символів і номера рядка екрана, ку-

ди ці символи виводяться.

Функція DOS 08h (введення символа без луни), що включена в цикл,

виконує два завдання. По-перше, вона зупиняє виконання програми і

дозволяє вивчити зміст екрана в кожному кроці циклу. Для того, щоб

продовжити виконання програми, досить натиснути на будь-яку клавішу.

По-друге, ця функція, будучи чутлива до введення з клавіатури комбіна-

ції <Ctrl>/C, дозволяє завершити програму, яка інакше виконувалася б

вічно.

Розглянемо спрощену імітацію диспетчера DOS. Хай ми маємо в

програмі групу підпрограм і хочемо викликати їх так само, як викликає-

мо функції DOS – за допомогою якого-небудь переривання користувача,

указуючи в регістрі АН номер “функції”. Тоді в нашій програмі, окрім

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

допомогою переривання і змінює далі управління на підпрограму із за-

даним в регістрі АН номером. Адреса цього диспетчера повинна бути

Page 289: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

289

занесена в якому-небудь з вільних векторів. Використовуємо так само,

як і в прикладі 9.3, вектор користувача 65h.

Приклад 9.3. Табличний виклик підпрограм:

text segment ‘code’

assume cs:text,ds:data

; диспетчер переривання 65h

new_65h: push BX ; для порядку збережемо

push DX ; використовувані регістри

mov BL,AH ; “функцію”відправимо в BL

mov ВН,0 ; тепер номер функції у ВХ

shl BX,1 ; помножимо на два

call addr_tbl[BX] ; викличемо підпрограму

pop DX ; відновимо

pop BX ; регістри

iret ; повернення з переривання

; Підпрограми-функції

sub0: mov АН,9

mov DX,offset mes0

int 21h

ret subl: mov AH,9

mov DX, off set mesl

int 21h

ret sub2: mov AH,9

mov DX, offset mes2

int 21h

ret sub3: mov AH,9

mov DX,offset mes3

int 21h

ret sub4: mov AH,9

mov DX,offset mes4

int 21h

ret

main proc

; використовуємо переривання 65h для виклику підпрограм по номеру

; встановимо прикладний обробник переривання 65h

mov AX,2565h ; функція заповнення вектора, вектор 65h

mov DX,offset new_65h

Page 290: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

290

push CS ; настроємо DS

pop DS ; на сегмент команд

int 21h

mov AX,data ; ініціалізація сегментного

mov DS,AX ; регістра DS

; викличемо послідовно підпрограми. Номер – в АН

mov АН,00Н

int 65h

mov AH,01h

int 65h

mov AH,02h

int 65h

mov AH,03h

int 65h

mov AH,04h

int 65h ; завершимо програму

mov AX,4C00h

int 21h

main endp

text ends

data segment

; поля даних. Таблиця адрес підпрограм

addr_tbl dw sub0

dw subl

dw sub2

dw sub3

dw sub4

; Повідомлення, що виводяться

mes0 db 9, ‘Oтработала подпрог0’,10,13,27,’$’

mesl db 27, ‘Отработала подпрог1’,10,13,27,’$’

mes2 db 27, ‘Oтработала подпрог2’,10,13,27,’$’

mes3 db 27, ‘Oтработала подпрог3’,10,13,27,’$’

mes4 db ‘Oтработала подпрог4’,10,13,27,’$’

data ends

end main

Результати роботи програми прикладу 9.3 наведено на рис. 9.1.

Page 291: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

291

У диспетчері переривання int 65h зберігаються використовувані в

ньому і в підпрограмах регістри, після чого номер “функції”, що викли-

кається, пересилається з байтового регістра АН в регістр ВХ, який надалі

використовуватиметься як індексне. Далі командою shl (shift left, ариф-

метичне зрушення вліво) вміст ВХ зрушується вліво на 1 двійковий роз-

ряд, що еквівалентно множенню на два. Тепер вміст ВХ можна розгляда-

ти як індекс в таблиці адрес addr_tbl, у якій записані зсуви (відносні ад-

реси) підпрограм в порядку, що визначає їх номери.

Команда

call addr_tb1[BX]

непрямого виклику передає керування на необхідну підпрограму. Після

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

чи керування в основну процедуру.

Всі використані в прикладі підпрограми практично однакові. Вони

виводять на екран деякі повідомлення за допомогою функції DOS 09h.

Для кожної підпрограми передбачено власне повідомлення, в які для

краси включені Esc-послідовності установки кольору.

Алгоритм основної процедури main не містить нічого нового. У ній

встановлюється прикладний обробник переривання int 65h (можна було,

звичайно, вибрати і інший вектор з діапазону 60h...66h). Сегментний

регістр DS настроюється на сегмент даних і, нарешті, за допомогою ко-

манд int 65h викликаються послідовно підпрограми, номери яких указу-

ються за допомогою регістра АН.

Рис. 9.1. Результати роботи програми прикладу 9.3

Page 292: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

292

10. ЗВ’ЯЗОК АСЕМБЛЕРУ З МОВАМИ ВИСОКОГО РІВНЯ

10.1. Характеристика мов системного програмування

Мова системного програмування повинна задовольняти такі влас-

тивості:

забезпечувати створення ефективної програми з необхідними ре-

сурсами (пам’яті, часу процесора, дисковому простору);

забезпечувати можливість використання всіх особливостей

комп’ютера, наприклад доступ до всієї оперативної пам’яті, роботу в

захищеному режимі, використання і управління кеш-пам’яттю і т.д.;

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

ри. Деякі програми, наприклад, драйвери для управління зовнішніми

ресурсами мають спеціальну структуру.

бути надійною і наочною для зменшення вірогідності пропуску

помилок в програмі.

У даний час немає мови, що повністю задовольняє ці властивості.

Всі вимоги, окрім останньої, задовольняє машинно-орієнтована мова

асемблера. Останній вимозі відповідають мови високого рівня, але вони

не задовольняють перші три вимоги, тому при створенні системних про-

грам використовують і мову асемблеру, і мову високого рівня (мова С,

С++). І, хоча для систем, що підтримують роботу з процесорами різних

типів, наприклад, WINDOWS NT, драйвери пишуться на мові високого

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

нання команд і їх зберігання в пам’яті допомагає писати "хороші" про-

грами на будь-якій мові.

10.2. Загальні відомості

Питання стиковки різних мов одна з одною цікаве, складне і важли-

ве.

Коли програміст пише програму, він повинен дотримуватися певних

зовнішніх правил:

витримувати синтаксис операторів мови, інакше компілятор не

зрозуміє, що ж ми хочемо зробити;

дотримуватися певної структури оформлення своїх модулів

Page 293: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

293

(програм).

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

кожного з модулів (інтерфейсу) стають дуже важливими, інакше дані

(або підпрограми) з одного модуля стануть не доступні командам іншого

модуля.

Розглянемо стиковку асемблеру тільки з мовами Pascal і С++. Точ-

ніше використовуватимемо компілятори фірми Borland – Borland Pascal і

Borland С++. Все, про що піде мова, відноситиметься і до інших компі-

ляторів, що припускають інтерфейс з мовою асемблеру. Одержавши де-

які навики, надалі можливо використовувати мову асемблеру з іншими

мовами, заздалегідь проглянувши документацію до цих мов.

Помітимо, що С і C++ є різними мовами, хоча між ними є багато за-

гального. С – це процедурна мова, а C++ – об’єктно-орієнтована. Вони

продовжують розвиватися, кожна в свою сторону. Середовище програ-

мування Borland C++ має в своєму складі комбінований компілятор,

який реагує на розширення файлів *.с – модуль на мові С, *.срр – мо-

дуль на мові C++. Окрім того, фірма Borland дає програмісту можливість

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

йок.

Існують такі форми комбінування програм на мовах високого рівня

з асемблером:

використання вбудованих операторів і асемблерних вставок. Ця

форма сильно залежить від синтаксису мови високого рівня і конкретно-

го компілятора. Вона припускає, що асемблерні коди у вигляді команд

асемблеру або прямо в машинних командах вставляються в текст про-

грами на мові високого рівня. Компілятор мови розпізнає їх як команди

асемблеру (машинні коди) і без змін включає у формований їм об’єктний

код. Ця форма зручна, якщо треба вставити невеликий фрагмент.

використання зовнішніх процедур і функцій. Це більш універса-

льна форма комбінування. У неї є ряд переваг:

написання і відладку програм можна проводити незалежно;

написані підпрограми можна використовувати в інших проектах;

полегшуються модифікація і супровід підпрограм протягом

життєвого циклу проекту. Наприклад, якщо ваша процедура на асембле-

рі проводить роботу з деяким зовнішнім пристроєм, то при зміні при-

строю вам немає необхідності перебудовувати весь проект – досить за-

мінити тільки працюючу з ним процедуру, залишивши незмінним інтер-

фейс програми на мові високого рівня з асемблером.

Page 294: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

294

В основному зв’язок між мовами програмування здійснюється через

зовнішні процедури і функції. В даному випадку можливі два види

зв’язку – програма на мові високого рівня викликає процедуру на асемб-

лері і навпаки. Обмежимося розглядом зв’язку, коли програма на мові

високого рівня викликає процедуру на асемблері. Це найбільш часто

використовуваний вид зв’язку.

Синтаксис директиви ргос:

Ім’я_процедури PROC [[модификатор_мови]мова] [відстань]

Одним з операндів є мова. Він служить для того, щоб компілятор

міг правильно організувати інтерфейс (зв’язок даних) між процедурою

на асемблері і програмою на мові високого рівня. Необхідність такої

вказівки виникає внаслідок того, що способи передачі аргументів при

виклику процедур різні для різних мов високого рівня.

TASM підтримує декілька значень операнда мова. У табл. 10.1 для

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

тів і угоди про те, яка процедура очищає стек, – що викликає або викли-

кається.

Таблиця 10.1

Передача аргументів в мовах високого рівня

Операнд “мова” Мова Напрям передаван-

ня аргументів

Яка процедура

очищає стек

NOLANGUAGE Асемблер Зліва направо Що викликається

BASIC Basic Зліва направо Що викликається

PROLOG Prolog Зліва направо Що викликає

FORTRAN Fortran Зліва направо Що викликається

С С Зліва направо Що викликає

C++ (СРР) C++ Зліва направо Що викликає

PASCAL Pascal Зліва направо Що викликається

STDCALL - Зліва направо Що викликається

SYSCALL C++ Зліва направо Що викликає

Під напрямом передачі аргументів розуміється порядок, в якому

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

у виклику процедури.

Наприклад, для мови Pascal характерний прямий порядок включен-

ня аргументів в стек: першим в стек записується перший передаваний

Page 295: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

295

аргумент з оператора виклику процедури, другим – другий аргумент і

т.д. На вершині стека після запису всіх передаваних аргументів виявля-

ється останній аргумент.

Для мови С++, навпаки, характерний зворотний порядок передачі

аргументів. Відповідно до нього в стек спочатку включається останній

аргумент з оператора виклику процедури (або функції), потім передос-

танній і т.д. Зрештою на вершині стека виявляється перший аргумент.

Що ж до очищення стека, то зрозуміло, що повинні бути певні домовле-

ності про це. У мові Pascal цю операцію завжди здійснює процедура, що

викликається, в мові С++ – що викликає. При розробці програми з вико-

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

має сенсу, але якщо ми збираємося зв’язувати декілька різномовних мо-

дулів, то ці угоди потрібно мати на увазі.

10.3. Зв’язок Pascal-асемблер

Організацію такого зв’язку розглянемо на прикладі такого завдання:

розробимо програму на мові Pascal, яка виводить символ задану кіль-

кість раз, починаючи з певної позиції на екрані. Всі числові аргументи

визначаються в програмі на Pascal. Виведення символу здійснює проце-

дура асемблеру. Очевидно, що основна проблема в цьому завданні – ор-

ганізація взаємодії модулів на Pascal і асемблері.

Модуль Pascal-программи створюється в інтегрованому середовищі

Borland Pascal. { Програма, що викликає процедуру на асемблері} program my_p; {SD+} { включення повної інформації для налагоджувача} uses crt; procedure asmproc(ch:char;x, у, kol :1nteger); external; { процедура asmproc оголошена як зовнішня} {$L asmprg.obj} BEGIN clrscr; { очищення екрана} asmprg("a",l,4,5); asmprg("s",9,2,7); END.

Процедура на асемблері, яку викликає програма на Pascal, створю-

Page 296: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

296

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

вигляд:

; для виведення на екран використовуються служби BIOS: ; 02h – позиціонування курсора і ; 09h – виведення символу задану кількість разів. MASM MODEL small STACK 256 .code asmprog proc near PUBLIC asmprog ; оголошена як зовнішня push bp ; пролог mov bp,sp mov dh[bp+6] ; номер рядка для виведення символу у – в dh mov d1,[bp+8] ; номер стовпця для виведення символу х – в d1 mov ah,02h ; номер служби BIOS int 10h ; виклик переривання BIOS ; виклик функції 09h переривання BIOS 10h: ; виведення символу з аl на екран mov ah,09h ;номер служби BIOS mov а1[bр+10] ; символ ch в а1 mov bl,07h ; атрибут символу xor bh, bh mov сх[bр+4] ; кількість виведень символу – в сх int 10h ; виклик переривання BIOS pop bp ; встановлення bp, очищення стека і повернення ret 8 asmprog endp ; кінець процедури end Типова схема організації зв’язку Pascal-асемблер така: – написати процедуру на асемблері дальнього (far) або ближнього

типу (near). – провести компіляцію програми asmprog.asm з метою усунення

синтаксичних помилок і отримання об’єктного модуля програми. Для того, щоб це можливо було зробити не виходячи з середовища Borland Pascal. компілятор tasm.exe повинен знаходитися в BIN-каталозі пакета Borland Pascal;

– у програмі на мові Pascal, яка викликатиме зовнішню процедуру на асемблері, слід вставити директиву компілятора {$L};

Page 297: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

297

– якщо передбачається дослідження роботи програми у налагоджу-вачі, то необхідно зажадати, щоб компілятор включив налагоджувальну інформацію у виконуваний модуль, що генерується їм. Для цього є дві можливості. Перша полягає у використанні глобального ключа {$D+}. Цей ключ повинен бути встановлений відразу після заголовка програми на Pascal. Друга, альтернативна можливість, полягає в установці опції

– виконати компіляцію програми на Pascal. Для компіляції зручно

використовувати інтегроване середовище. Для вивчення особливостей зв’язку Pascal-асемблер зручно прямо в інтегрованому середовищі взя-

клавішами Shift+F4). Буде завантажений налагоджувач. В даному випад-ку у вікні Module з’явиться текст програми на Pascal. Натискаючи клаві-шу F7, у покроковому режимі буде виконана програма на Pascal. Коли черга дійде до виклику процедури на асемблері, налагоджував відкриє вікно з текстом програми на асемблері. Проте налагоджував приховує момент переходу з програми на Pascal в процедуру на асемблері. Тому краще всього виконувати програму при відкритому вікні CPU налаго-джувача.

10.4. Зв’язок С++ -асемблер

Залежно від призначення програм, можливо, потрібно буде викона-

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

мови асемблеру. У таких випадках можна використовувати оператора

C++ asm для вбудовування команд мови асемблеру в програму. Далі в

операторних дужках повинні бути записані команди асемблеру.

Синтаксис оператора наступний: //оператори мови С++ asm { ; команди на мові асемблеру } //оператори мови С++ Наприклад: int funcAsmI (int x) { asm { mov ах, x cwd

Page 298: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

298

mov сx, 3 idiv сx } } unsigned int funcAsmU (unsigned int x) { asm { mov ах, x xor dx, dx mov cx, 3 div cx } }

Приклад 10.1. Програма використання оператора .asm для озвучу-

вання динаміка комп’ютера в середовищі MS-DOS:

#include <iostream.h>

void main(void)

{

cout << “Зараз дзвонитиме!” << endl;

.asm

{ mov ah,2

mov dl,7

int 21h

}

cout << "Є!" << endl;

}

Приклад 10.2. Програма на мові С++ обробляє асемблерну команду

cpuid. Це дозволяє одержати інформацію про поточний процесор. Для

отримання даної інформації, необхідно в регістр EAX помістити пара-

метр – одне із значень 0, 1 або 2.

Якщо ЕАХ = 0, то в регістрах EAX, EBX, EDX і ECX формуються бі-

тові маски (рис. 10.1). Ідентифікуючі конкретні біти або їх сукупності на

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

з довідковими даними) (рис. 10.2).

Page 299: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

299

/*Програма виводить у вікні консольного додатку інформацію про поточний процесор в регістрах EAX, EBX, EDX і ECX */ #include <iostream.h> #include <stdio.h> #include <conio.h>

Рис. 10.1. Перша сторінка з результатами роботи програми при ЕАХ = 0

Рис. 10.2. Друга сторінка з результатами роботи програми

при ЕАХ=0

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 300: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

300

#include <dos.h> #include <stdlib.h> #include <ctype.h> long а b,c,d, n; unsigned long eax, ebx, ecx, edx;//для 4 байтів unsigned int ах, bx, cx, dx; //для 0 байтів //наведення 32-розрядного бітового поля з даними регістрів union bit { unsigned long ss; struct { unsigned a0:1; unsigned a1:1; unsigned a2:1; unsigned a3:1; unsigned a4:1; unsigned a5:1; unsigned a6:1; unsigned a7:1; unsigned a8:1; unsigned a9:1; unsigned a10:1;unsigned a11:1; unsigned a12:1;unsigned a13:1; unsigned a14:1;unsigned a15:1; unsigned a16:1;unsigned a17:1; unsigned a18:1;unsigned a19:1; unsigned a20:1;unsigned a21:1; unsigned a22:1;unsigned a23:1; unsigned a24:1;unsigned a25:1; unsigned a26:1;unsigned a27:1; unsigned a28:1;unsigned a29:1; unsigned a30:1;unsigned a31:1; } dword; }; void binar_32 (unsigned long);//зміст байта в двійковому вигляді void binar (unsigned char); //зміст 0 байта void soder_reg (long);//зміст регістрів EAX, EBX, ECX, EDX void dan_cpu_0(int,int,int,int);// дані про процесор, якщо ЕАХ=0 // дані про процесор, якщо ЕАХ=1 void dan_cpu_1(unsigned long, unsigned long); // дані про процесор, якщо ЕАХ=0 void dan_cpu_2(unsigned long, unsigned long unsigned long,unsigned long); //--------------------------------------------- main () { cout<<"Vvedite EAX = 0,1,2"<<endl; cin>>n; if (n>2) cout<<"Error!"<<endl;

Page 301: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

301

else { soder_reg (n);// проглядання регістрів cout<<"Registers:"<<endl; cout.setf(ios::hex); cout<<"EAX="<< a<<endl; cout<<"EBX="<< b<<endl; cout<<"ECX="<< c<<endl; cout<<"EDX="<< d<<endl; cout<<"-------------"<<endl; cout<<"4 byte EAX="<< endl; binar_32(a); cout<<"-------------"<<endl; cout<<"4 byte EBX="<< endl; binar_32(b); cout<<"-------------"<<endl; cout<<"4 byte ECX="<< endl; binar_32(c); cout<<"-------------"<<endl; cout<<"4 byte EDX="<< endl; binar_32(d); cout<<"-------------"<<endl; getch(); cout.setf(ios::hex); ax=a<<24; ax>>=24; cout<<"AX= "<<a<<endl; bx=b<<24; bx>>=24; cout<<"BX= "<<bx<<endl; cx=c<<24; cx>>=24; cout<<"CX= "<<cx<<endl; dx=d<<24; dx>>=24; cout<<"DX= "<<dx<<endl; cout<<"0 byte EAX="; binar(ах); cout<<"-------------"<<endl; cout<<"0 byte EBX="; binar(bx); cout<<"-------------"<<endl;

Page 302: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

302

cout<<"0 byte ECX="; binar(cx); cout<<"-------------"<<endl; cout<<"0 byte EDX="; binar(dx); cout<<"-------------"<<endl; switch(n){ case 0: dan_cpu_0(ах,bx,cx,dx); break; case 1: dan_cpu_1(а,d); break; case 2: dan_cpu_2(а,b,c,d);break; } getch(); } } //***************************** // функція отримання даних з регістрів EAX, EBX, ECX, EDX void soder_reg (long m) { //******асемблерна вставка***** asm{ .586 mov EAX, m cpuid mov [a],EAX mov [b],EBX mov [c],ECX mov [d],EDX } } //****************************** void binar_32 (unsigned long ch) { bit cod; cod.ss=ch; //заносимо значення cout<< "No bits: 313029282726252423222120" ; cout<<"191817161514131211109 8 7 6 5 4 3 2 1 0"<<endl; cout<< "Val. of bits"; cout<<‘\t’<<cod.dword.a31<<‘ ‘<<cod.dword.a30; cout<<‘ ‘<<cod.dword.a29<<‘ ‘<<cod.dword.a28; cout<<‘ ‘<<cod.dword.a27<<‘ ‘<<cod.dword.a26; cout<<‘ ‘<<cod.dword.a25<<‘ ‘<<cod.dword.a24; cout<<‘ ‘<<cod.dword.a23<<‘ ‘<<cod.dword.a22; cout<<‘ ‘<<cod.dword.a21<<‘ ‘<<cod.dword.a20;

Page 303: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

303

cout<<‘ ‘<<cod.dword.a19<<‘ ‘<<cod.dword.a18; cout<<‘ ‘<<cod.dword.a17<<‘ ‘<<cod.dword.a16; cout<<‘ ‘<<cod.dword.a15<<‘ ‘<<cod.dword.a14; cout<<‘ ‘<<cod.dword.a13<<‘ ‘<<cod.dword.a12; cout<<‘ ‘<<cod.dword.a11<<‘ ‘<<cod.dword.a10; cout<<‘ ‘<<cod.dword.a9<<‘ ‘<<cod.dword.a8; cout<<‘ ‘<<cod.dword.a7<<‘ ‘<<cod.dword.a6; cout<<‘ ‘<<cod.dword.a5<<‘ ‘<<cod.dword.a4; cout<<‘ ‘<<cod.dword.a3<<‘ ‘<<cod.dword.a2; cout<<‘ ‘<<cod.dword.a1<<‘ ‘<<cod.dword.a0<<endl; } //---------------------------------------------- void binar (unsigned char ch) { union { unsigned char ss; struct { unsigned a0:1; unsigned a1:1; unsigned a2:1; unsigned a3:1; unsigned a4:1; unsigned a5:1; unsigned a6:1; unsigned a7:1; } byte; } cod; cod.ss=ch; //заносимо значення cout<< "\nNombers bits: 7 6 5 4 3 2 1 0"<<endl; cout<< "Values of bits"; cout<<‘\t’<<cod.byte.a7<<‘ ‘<<cod.byte.a6; cout<<‘ ‘<<cod.byte.a5<<‘ ‘<<cod.byte.a4; cout<<‘ ‘<<cod.byte.a3<<‘ ‘<<cod.byte.a2; cout<<‘ ‘<<cod.byte.a1<<‘ ‘<<cod.byte.a0<<endl; } //***************************************** void dan_cpu_0(int а, int b, int с,int d) //ЕАХ=0 { cout<<"max EAX= "<<a<<endl; cout<<"ide CPU= "; switch (toascii(b)){ case 0x47: cout<<‘G’; break; //Intel case 0x41: cout<<‘A’; break; //AMD } switch (toascii(c)){ case 0x6E: cout<<‘l’; break; case 0x44: cout<<‘D’; break; }

Page 304: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

304

switch (toascii(d)){ case 0x69: cout<<‘I’<<" CPU Intel"; break; case 0x65: cout<<‘e’<<" CPU AMD"; break; } cout<<endl; } //***************************************** void dan_cpu_1(unsigned long а, unsigned long d)//ЕАХ=1 { bit cod cod1; long r=0, s=0, t=0, u=0; cod.ss=a; //заносимо значення eax cout.setf(ios::dec); r=cod.dword.a0 + cod.dword.a1 + cod.dword.a2 + cod.dword.a3; cout<<"Modificasion CPU (stepping ID) = "<<r<<endl; s=cod.dword.a4 + cod.dword.a5 + cod.dword.a6 + cod.dword.a7; t=cod.dword.a8 + cod.dword.a9 + cod.dword.a10 + cod.dword.a11; cout<<"Model CPU and family CPU = "; if ((t==2)&&(s==1)) cout<<" Pentium III 566"<<endl; if ((t==4)&&((s==0)||(s==1))) cout<<" I486DX"<<endl; if ((t==4)&&(s==2)) cout<<" I486SX"<<endl; if ((t==5)&&(s==2)) cout<<" Pentium 75-200"<<endl; if ((t==5)&&(s==4)) cout<<" Pentium MMX 166-200"<<endl; if ((t==6)&&(s==1)) cout<<" Pentium Pro"<<endl; if ((t==6)&&(s==3)) cout<<" Pentium II model 3, Pentium II OverDrive"<<endl; if ((t==6)&&(s==5)) cout<<" Pentium II model 5, Pentium II Xeon"<<endl; if ((t==6)&&(s==6)) cout<<" Celeron model 6"<<endl; if ((t==6)&&(s==7)) cout<<" Pentium III, Pentium III Xeon"<<endl; if ((t==6)&&(s==3)) cout<<" Pentium II model 3"<<endl; cout<<"Type CPU = "; u=cod.dword.a12 + cod.dword.a13; switch (u){ case 0: cout<<u<<" Type OEM"<<endl; break; case 1: cout<<u<<" Type Overdrive"<<endl; break; case 2: cout<<u<<" Type Dual"<<endl; break; } getch(); cod1.ss=d; //заносимо значення edx cout<<"FPU= "<<cod1.dword.a0<<endl; cout<<"VME= "<<cod1.dword.a1<<endl;

Page 305: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

305

cout<<"DE= "<<cod1.dword.a2<<endl; cout<<"PSE= "<<cod1.dword.a3<<endl; cout<<"TSC= "<<cod1.dword.a4<<endl; cout<<"MSR= "<<cod1.dword.a5<<endl; cout<<"PAE= "<<cod1.dword.a6<<endl; cout<<"MCE= "<<cod1.dword.a7<<endl; cout<<"CX8= "<<cod1.dword.a8<<endl; if (bx==0x41) cout<<"PGE= "<<cod1.dword.a9<<endl; else cout<<"APIC= "<<cod1.dword.a9<<endl; cout<<"SEP= "<<cod1.dword.a11<<endl; cout<<"MTRR= "<<cod1.dword.a12<<endl; cout<<"PGE= "<<cod1.dword.a13<<endl; cout<<"MCA= "<<cod1.dword.a14<<endl; if (cod1.dword.a0) cout<<"SMOV= "<<cod1.dword.a15<<endl; cout<<"PAT= "<<cod1.dword.a16<<endl; cout<<"36 adress - 4Mb page= "<<cod1.dword.a17<<endl; cout<<"PPN= "<<cod1.dword.a18<<endl; cout<<"CLFLUSH= "<<cod1.dword.a19<<endl; cout<<"Inf. to buf.= "<<cod1.dword.a21<<endl; cout<<"MSR-registers= "<<cod1.dword.a22<<endl; cout<<"MMX= "<<cod1.dword.a23<<endl; getch(); cout<<"FXSR= "<<cod1.dword.a24<<endl; cout<<"SSE= "<<cod1.dword.a25<<endl; cout<<"SSE2= "<<cod1.dword.a26<<endl; cout<<"self cnoop= "<<cod1.dword.a27<<endl; cout<<"Hiper Treading= "<<cod1.dword.a28<<endl; cout<<"The temperature control= "<<cod1.dword.a29<<endl; cout<<"CPU Intel Itanium= "<<cod1.dword.a30<<endl; cout<<"FERR#/PBE#= "<<cod1.dword.a31<<endl; } void dan_cpu_2(unsigned long а, unsigned long b unsigned long с,unsigned long d)//ЕАХ=2 { bit cod cod1, cod2, cod3; long r=0; cod.ss=a; //заносимо значення eax cout.setf(ios::dec); r=cod.dword.a0 + cod.dword.a1 + cod.dword.a2 + cod.dword.a3+

Page 306: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

306

+cod.dword.a4 + cod.dword.a5 + cod.dword.a6 + cod.dword.a7; cout<<"Amoun CPUID= "<<r<<endl; cout<<"EBX="<< b<<endl; cout<<"ECX="<< c<<endl; cout<<"EDX="<< d<<endl; cod1.ss=b;//заносимо значення ebx cod2.ss=c;//заносимо значення ecx cod3.ss=d;//заносимо значення edx if ((cod1.dword.a31==0)&& (cod2.dword.a31==0)&& (cod3.dword.a31==0)) cout<<"Information = true"<<endl; } //******************************************************* При стиковці модулів на С++ і асемблері необхідно вирішити на-

ступні проблеми: як передати аргументи в процедуру на асемблері, як до ним звернутися в процедурі на асемблері і як повернути результат?

Відзначимо, що завжди потрібно зберігати і перед виходом з проце-дури відновлювати вміст регістрів bp, sp, cs, ds і ss. Це робиться перед викликом процедури. Решту регістрів потрібно зберігати з потреби, але, хорошим тоном є збереження і подальше відновлення всіх регістрів, які піддаються зміні усередині процедури.

Передача аргументів в процедуру на асемблері з програми на С++ здійснюється також через стек (рис. 10.3), але порядок їх розміщення в стеку є зворотним тому, що розглянутий для зв’язку Pascal-асемблер. Як приклад використовуємо те ж завдання.

Рис. 10.3. Вид стека після передачі управління ближнього

типа процедурі на асемблері

Page 307: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

307

Процедури на асемблері мають доступ до аргументів, переданих в

стек за допомогою регістра bp. Перш за все в початок процедури асемб-

леру необхідно вставити код прологу:

push bp

mov bp,sp

Після цього доступ до аргументів в стеку здійснюється за зсувом bp,

наприклад:

mov ах[bp+4] ; переписати значення ch із стека в ах

mov bx[bp+6] ; значення х – в регістр bх

При організації зв’язку С++-асемблер також можна використовува-

ти директиву аrg. Це позбавить нас від необхідності підраховувати зсуви

в стеку для доступу до аргументів і дозволить звертатися до них за іме-

нами.

Приклад.

arg сh:byte; x:word; у:word; kol:word

push bp

mov bp,sp

mov ах[ch] ; переписати значення ch із стека в ах

mov bx[x] ; значення x – в регістр bx

Основні вимоги до головного модуля на мові C++ наступні:

1. Імена зовнішніх змінних і функцій повинні бути описані, як гло-

бальні.

2. Імена зовнішніх функцій повинні бути унікальними.

3. До імен зовнішніх функцій повинен бути застосований специфі-

катор збірки: extern "С" { прототипи_ функцій; }, щоб вони інтерпре-

тувалися в стилі мови С.

4. Константи зовнішніми бути не можуть!

5. Виклик зовнішніх функцій робиться, як завжди це прийнято в

мові C++.

6. Стикуємі модулі повинні бути описані в проекті.

Розглянемо на конкретному прикладі питання стиковки модулів для

виконання програм C++ у вікні консольного додатку MS-DOS для ліній-

ки операційних систем Windows.

Порядок взаємодії модулів на алгоритмічних мовах С++ і асемблері

Page 308: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

308

наступний.

Для створення проекту, де файли з модулями на С++ і асемблері бу-

ли б рівноправними, знадобиться інтегроване середовище С++ (у даному

прикладі це Borland C++ 5.02) і пакет TASM. Для зручності взаємодії

файлів, доцільно створити окремий каталог на робочому диску. Напри-

клад

D:\primer\

Основні вимоги до модуля на мові асемблеру наступні:

1. Модель пам’яті бажано вибирати типу large (щоб уникнути про-

блем з оперативною пам’яттю, особливо в 32- і 64-розрядних операцій-

них системах) з обов’язковою вказівкою мови програмування С:

model large,С

Вибір моделі пам’яті краще надавати програмісту, виходячи із спе-

цифіки обробки конкретної інформації в конкретних умовах роботи про-

грами.

2. Зовнішні змінні, які передаються з срр-модуля, можуть бути опи-

сані як в сегменті даних, так і в сегменті коду за допомогою директиви

extrn.

3. Опис констант повинен бути повторений. Вони повинні бути ло-

кальними і можуть бути розташовані як в сегменті даних, так і в сегменті

коду.

4. Зовнішні функції повинні бути описані за допомогою директиви

опису загальних імен з обов’язковою вказівкою мови програмування С:

PUBLIC С ім’я_зовнішньої_ функції.

5. При стиковці модулів в середовищі Вorland С++ опис сегментів

краще робити в рідному стилі ideal: CODESEG і DATASEG (хоча можна

і в стилі MASM: .code і .data).

У текстовому редакторі скласти текст файлу на асемблері, напри-

клад prga.asm, у якому оголосити процедуру asmprog загальнодоступ-

ною за допомогою директиви PUBLIC. Обов’язково, ідентифікатору з

ім’ям процедури asmprog слід передавати символ підкреслення

_asmprog. Компілятори Сі та C++ додають знак підкреслення до всіх

глобальних ідентифікаторів.

Процедура, що викликається, на асемблері має вигляд: MASM MODEL small ; модель пам’яті і тип коду

Page 309: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

309

STACK 256 PUBLIC _asmprog ; символ підкреслення обов’язковий

.code main: _asniproc proc з near c:BYTE,x:WORD,y:WORD,ko1:WORD

mov dh,y ; у-координата символу в dh mov dl,x ; х-координата символу в d1 mov ah,02h ; номер служби BIOS int 10h ; виклик переривання BIOS mov ah,09h ; номер служби BIOS mov ex,kol ; kol – кількість MOV BL,07h ; маска висновку в bl xor bh,bh ; онуляем bl mov al,c ; с – символ в аl int 10h ; виклик переривання BIOS ret ; повернення з процедури _asmprog endp end main

Оскільки основним середовищем роботи є Borland С++, то для того,

щоб можливо було відкомпілювати текст файлу prga.asm, компілятор

tasm.exe повинен знаходитися в BIN-каталозі пакету Borland С++.

Наприклад

C:\Bc502\BIN\tasm.exe

Скласти текст модуля C++ у середовищі Borland С++. Це файл

prgc.cpp. У цій програмі оголосити процедуру asmprog зовнішньою ди-

рективою extern:

extern void asmproc(char ch, unsigned x, unsigned у, unsigned kol);

#include <studio.h>

#include <conio.h>

extern "с" void asmprog(char ch, unsigned x, unsigned у,unsigned kol);

void main (void)

{ clrscr();

asmprog(‘a", 2, 3, 5);

asinprog(‘s", 9, 2. 7);

}

Page 310: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

310

Помістити цей файл в каталог primer. Файл модуля на мові асемблера prga.asm також можна набирати і

редагувати в текстовому редакторі інтегрованого середовища Borland C++ (рис. 10.4).

Далі необхідно створити проект. Для цього вибирається послідов-

ність опцій головного меню середовища Borland C++: File/New/Progect. Після цього з’являється діалогове вікно New Target, що містить опції проекту (рис. 10.5):

ім’я проекту, наприклад pr1.ide; платформа DOS (Standart); використовувана модель пам’яті – Small, оскільки дана модель

використовується в модулі на мові асемблеру. Після натиснення клавіші ОК, з’являється вікно редактора проекту з

пропонованим середовищем Borland C++, шаблоном майбутнього прое-кту з виконуваним модулем pr1.exe (рис. 10.6).

Рис. 10.4. Вид модулів prgc.cpp і prga.asm в середовищі

Borland C++ 5.02

Page 311: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

311

Пропонований файл модуля pr1.cpp нам не знадобиться, тому, за-

здалегідь поставивши курсор на даний рядок і, використовуючи пункт

контекстного меню (Alt+F10 або натиснення правої клавіші мишки)

Delete note, видалимо запис (рис. 10.7).

Рис. 10.5. Зміст діалогового вікна New Target

Рис. 10.6. Вікно з шаблоном проекта

Page 312: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

312

Тепер необхідно додати в проект наші модулі: prga.asm і prgc.cpp.

Для цього, використовуючи двічі пункт контекстного меню Add note,

вибираємо необхідні файли і додаємо їх до проекту (рис. 10.8).

Є деяке зауваження з приводу правильності формування проекту. У

проекті модулі prga.asm і prgc.cpp повинні бути рівноправними. Тому

після того, як до проекту був доданий перший файл, необхідно переміс-

тити з нього курсор знову на рядок з ім’ям файлу проекту pr1.exe, інакше

другий файл стане залежним від першого, а дана ієрархія примусить

проект неправильно працювати.

Рис. 10.7. Вікно повідомлення з ім'ям файлу проекту

Рис. 10.8. Файли проекту pr1.exe

Page 313: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

313

Для побудови проекту необхідно вибрати послідовність опцій голо-

вного меню середовища Borland C++: Project/Build all або натиснути на

п’яту кнопку на панелі інструментів, що знаходиться в головному меню

середовища Build Progect. Результатом роботи нашого проекту стане

консольний додаток, що виводить рядки символів на екран (рис. 10.9).

Якщо компілятор tasm.exe в процесі створення ехе-файлу не буде

знайдений, можна asm-файл відкомпілювати окремо. Це необхідно зро-

бити з урахуванням регістра зовнішніх символів (додається ключ /ml).

Запис в командному рядку має вигляд:

tasm prga.asm /I /ml

Опція /I указує на необхідність створення файлу листингу, навіть

якщо він не “замовляється” в командному рядку. Якщо немає помилок,

ми одержимо obj-файл, який потрібно замість asm-файлу включити в

проект.

Наступний приклад також ілюструє взаємозв’язок модулів на алго-

ритмічних мовах С++ і асемблеру. Щоб перевірити працездатність прое-

кту, необхідно також виконати всі, раніше описані, кроки по його фор-

муванню.

Приклад 10.2. Знайти суму елементів масиву

\Виклик модуля на C/C++

#include <iostream.h>

extern "C" int sum_asm(int massiv[],int count);

main()

{ int mas[5]={1,2,3,4,5};

int len=5, sum;

sum=sum_asm(mas,len);

Рис. 10.9. Фрагмент вікна консольного додатку з резуль-

татом роботи проекту pr1.exe

Page 314: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

314

cout<<"sum="<<sum;

return(0);

}

; Процедура, що викликається, на асемблері

; prga1.asm

MASM

MODEL small

.stack 100h

.code

public _sum_asm

_sum_asm proc з near adr_mas:word,len_mas:word

mov ах,0

mov cx,len_mas ; довжина масиву – в cx

mov si,adr_mas ; адреса масиву – в si

cycl: add ах[si] ; додавання вмісту акумулятора з елементом масиву

add si,2 ; адресувати наступний елемент масиву

loop cycl

ret ; повернення з функції, результат – в ах

_sum_asm endp

end

Результатом роботи буде також вікно консольного додатка, в якому

наведено суму елементів початкового масиву (рис. 10.10).

Залишилося вирішити питання повернення результату в програму на

С++ з процедури на асемблері. Для цього існують стандартні угоди

(табл. 10.2). Перед поверненням керування в програму на С++ в програ-

мі на асемблері необхідно помістити результат або сформувати указів-

ник у зазначених регістрах. Повернення аргументів з процедури на асем-

блері в програму на C++.

Рис. 10.10. Фрагмент вікна з результатом

Page 315: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

315

Таблиця 10.2

Результат роботи процедури на асемблері

Тип поверненого значення (C++) Результат

unsigned char ax

char ax

enum ax

unsigned short ax

short ax

unsigned int ax

int ax

unsigned long dx:ax

long dx:ax

покажчик near ax

Покажчик far dx:ax

Трудність опису зв’язку програм на мові C++ і асемблерних про-

грам полягає в тому, що різні версії мови C++ мають різні угоди про

зв’язки і для точнішої інформації слід користуватися довідником з наяв-

ної версії мови C++.

Інтерес викликають наступні особливості взаємозв’язку мов С++ і

асемблеру.

Більшість версій мови C++ забезпечують передачу параметрів через

стек в зворотній (в порівнянні з іншими мовами) послідовності. Звичай-

но доступ, наприклад, до двох параметрів, передаваних через стек, здій-

снюється таким чином:

MOV ES,BP

MOV BP,SP

MOV DH[BP+4]

MOV DL[BP+6]

...

POP BP

RET

Багато версій мови C++ розрізняють великі і малі букви, тому ім’я

Page 316: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

316

асемблерного модуля повинне бути наведено в тому ж символьному ре-

гістрі, який використовують для посилання C++-програми.

У деяких версіях мови C++ потрібно, щоб асемблерні програми, що

змінюють регістри di і si, записували їх вміст в стек при вході і віднов-

лювали ці значення із стека при виході.

Асемблерні програми повинні повертати значення, якщо це необхі-

дно, в регістрі ах (одне слово) або в регістровій парі dx:ax (два слова).

Для деяких версій мови C++, якщо асемблерна програма встанов-

лює прапорець df, то вона повинна скинути його командою cld перед

поверненням.

Page 317: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

317

11. МОДУЛЬНЕ ПРОГРАМУВАННЯ І МАКРОЗАСОБИ МОВИ

АСЕМБЛЕРУ

11.1. Макроасемблер

11.1.1. Стислі відомості про макроасемблер

Мова асемблеру надає ряд засобів підвищення зручності написання

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

– розширення набору директив;

– введення деяких додаткових команд, що не мають аналогів у сис-

темі команд мікропроцесора. Вони приховують від програміста рутинні

дії і генерують найбільш ефективний код;

– введення складних типів даних.

Для розв’язання локальних задач, для полегшення роботи у визна-

ченій проблемній області розроблювачі компіляторів асемблеру вклю-

чають у мову і постійно удосконалюють апарат макрозасобів або макро-

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

тин – безпосередньо транслятора, що формує об’єктний модуль, і мак-

роасемблеру.

Основна ідея – використання підстановок, що заміщають певним

чином організовану символьну послідовність іншою символьною послі-

довністю. Створювана в такий спосіб послідовність може бути як послі-

довністю, що описує дані, так і послідовністю програмних кодів.

Макроси дозволяють при трансляції програми замінити один рядок

іншим або зробити більш складні підстановки з урахуванням переданих

параметрів. Можливе завдання умов трансляції і нетрансляції ділянки

програми і навіть повторної трансляції тієї самої ділянки програми.

Головне тут те, що на вході макроасемблеру може бути текст про-

грами, дуже далекий за виглядом від програми мовою асемблеру, а на

виході обов’язково буде текст на чистому асемблері, що містить симво-

лічні аналоги команд системи машинних команд мікропроцесора. Таким

чином, обробка програми на асемблері з використанням макрозасобів

неявно здійснюється транслятором за дві фази (рис. 11.1). На першій

фазі працює частина компілятора, називана макроасемблером. На другій

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

формування об’єктного коду, що містить текст вихідної програми в ма-

шинному вигляді.

Page 318: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

318

1.1.2. Псевдооператори equ і =

До найпростіших макросів мови асемблеру можна віднести псевдо-

оператори equ і = (дорівнює).

Рис. 11.1. Обробка програми з використанням макрозасобів

Вони призначені для присвоєння деякому виразу символічного імені

або ідентифікатора. Згодом, коли в ході трансляції цей ідентифікатор

зустрінеться в тілі програми, макроасемблер підставить замість нього

відповідний вираз. Як вирази можуть бути використані константи, імена,

символічні імена і рядки в апострофах. Після присвоєння цим конструк-

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

но розміщення даної конструкції.

Синтаксис псевдооператора equ:

ім’я_ідентифікатора equ рядок або числовий_вираз

Синтаксис псевдооператора =:

ім’я_ідентифікатора = числовий_вираз

Незважаючи на зовнішню і функціональну подібність, псевдоопера-

тори equ і = відрізняються таким:

за допомогою equ ідентифікатору можна ставити у відповідність

як числові вирази, так і текстові рядки, а псевдооператор = може вико-

ристовуватися тільки з числовими виразами;

Вихідна програма, яка

містить макроси

Транслятор TASM.exe

1-а фаза трансляції: працює макроасемблер

2-а фаза трансляції: працює асемблер

Вихідна програма у внутрішньому подані компілятора (без макросів)

Об’єктний модуль

Page 319: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

319

ідентифікатори, визначені за допомогою =, можна перевизнача-

ти у вихідному тексті програми, а визначені з використанням equ – не

можна.

Асемблер завжди намагається обчислити значення рядка, сприйма-

ючи його як вираз. Для того щоб рядок сприймався саме як текст, необ-

хідно взяти його в кутові дужки: <рядок>. Кутові дужки є оператором

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

них рядок повинний трактуватися як текст, навіть якщо до нього входять

службові слова асемблеру або оператори.

Псевдооператор equ зручно використовувати для настроювання

програми на конкретні умови виконання і для заміни складних у позна-

ченні об’єктів, багаторазово використаних у програмі, більш простими

іменами і т.п.

ПРИКЛАДИ

;…

max equ 100

;...

mov eax, max+2

;...

Команда

mov eax, max+2

еквівалентна команді

mov eax, 100+2

У полі символів можуть бути задані імена, що визначені в іншому

псевдооператорі equ. Якщо ім’я визначене в equ після використання,

потрібно транслювати програму, застосовуючи кілька переглядів (про-

ходів). Кількість проходів при компіляції визначається ключем /m – чи-

сло переглядів.

ПРИКЛАД 1. Для трансляції фрагмента програми

;…

a equ b

b equ c

c equ 3

;…

mov eax, a

Page 320: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

320

;...

потрібні 2 перегляди, тобто в командному рядку необхідно задати ключ

/m2.

ПРИКЛАД 2. Нехай необхідно в програмі використовувати багато

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

m_1 db ‘Помилка в запису ідентифікатора’, 13, 10, 0

m_2 db ‘Помилка в запису числа’, 13, 10, 0

;...

m_N db ‘Помилка в запису виразу’, 13, 10, 0

Для спрощення запису позначимо загальні частини повідомлень m1

(помилка в запису) і m2 (13, 10, 0). Для цього використовуються опера-

тори

m1 equ < Помилка в запису >

m2 equ <13, 10, 0>

Кутові дужки в запису означають, що даний запис розглядається як

єдине ціле, а не складається з декількох елементів.

Тоді для завдання m_1, m_2,.., m_N необхідні такі оператори:

m_1 db m1, ‘ідентифікатора’, m2

m_2 db m1, ‘ числа’, m2

;...

m_N db m1, ‘ вираз’, m2

Для перевірки правильності введених макросів складемо програму

для формування рядків:

masm

.model small

.stack 256

.data

m1 equ < Помилка в запису >

m2 equ <13, 10, 0>

m_1 db m1, ‘ідентифікатора’, m2

m_2 db m1, ‘числа’, m2

m_3 db m1, ‘вираз’, m2

.code

main:

mov ax, @data

mov ds, ax

xor ax, ax

Page 321: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

321

mov ax, 4c00h

int 21h

end main

Для перегляду сформованих рядків увійдіть у режим DUMP і, вико-

ристовуючи CTRL+G, задайте перегляд області пам’яті, починаючи з

m_1. Ви побачите сформовані рядки.

Псевдооператор = зручно використовувати для визначення простих

абсолютних (тобто незалежних від місця завантаження програми в

пам’ять) математичних виразів. Головною умовою є те, щоб транслятор

міг обчислити ці вирази під час трансляції.

Значення, задане для імені, обчислюється на етапі трансляції і може

змінюватися в програмі. У виразі правої частини можна використовува-

ти змінні, визначені за допомогою =, у тому числі і попереднє значення

змінної лівої частини.

ПРИКЛАД.

;…

x = 5

max = 100

;...

mov eax, x

max = max – 10

mov edx, max+2

;...

Зазначимо, що остання команда еквівалентна команді

mov edx, 92.

У правій частині псевдооператора = можна використовувати мітки і

посилання на адреси – головне, щоб у результаті вийшов абсолютний

вираз.

11.1.3. Макрокоманди

Макровизначення (МВ) – послідовність рядків, що може містити

формальні параметри, причому після заміни формальних параметрів

Page 322: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

322

фактичними виходить синтаксично вірна ділянка програми (аналог фун-кції).

Макрокоманда (МК) – використовується для вказівки місця в про-грамі, куди підставляється група команд і фактичних параметрів (аналог команди call).

Макророзширення (МР) – це макровизначення, що виходить після заміни формальних параметрів фактичними, тобто це послідовність ко-манд, що підставляється в програму.

Синтаксис МВ такий: ім’я_макрокоманди macro [список_формальних_аргументів] тіло макровизначення endm МВ можуть розташовуватися: на початку вихідного тексту програми до сегментів коду і да-

них. Цей варіант варто застосовувати у випадках, якщо обумовлені вами МК актуальні тільки в межах однієї програми;

в окремому файлі. Цей варіант підходить при роботі над декі-лькома програмами однієї проблемної області. Щоб зробити доступними ці МВ у конкретній програмі, необхідно на початку вихідного тексту цієї програми записати директиву include ім’я_файла.

ПРИКЛАД. masm model smal1 include show. inc ; у цьомі місці буде вставлений текст файла show.inc ;… у макробібліотеці. Якщо у вас є універсальні МК, що викорис-

товуються практично у всіх ваших програмах, то їх доцільно записати в так звану макробібліотеку. Зробити актуальними МК з цієї бібліотеки можна за допомогою директиви include. Недолік цього і попереднього способів полягає у тому, що у вихідний текст програми включаються абсолютно всі МВ. Для виправлення ситуації можна використовувати директиву purge, за операнди якої через кому перелічуються імена МК, що не повинні включатися в текст програми.

ПРИКЛАД. include іомас.inc purge outstr, exit У даному випадку у вихідний текст програми перед початком ком-

піляції TASM замість рядка include iomac слід уставити рядок з файла

Page 323: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

323

iomac.inc. Але вставлений текст буде відрізнятися від оригіналу тим, що в ньому будуть відсутні МВ outstr і exit.

Для того щоб використовувати описане МВ у потрібному місці про-

грами, воно має бути активізованим за допомогою такої синтаксичної конструкції:

ім’я_макрокоманди список_фактичних_аргументів Результатом застосування даної синтаксичної конструкції у вихід-

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

МР формується компілятором і підставляється в програму замість МК. У листингу програми можна побачити команди МР.

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

а) рядок може складатися: з послідовності символів без пропусків, крапок, ком, крапок з

комою; з послідовності будь-яких символів, взятих у кутові дужки <...>.

У цій послідовності можна вказувати як пропуски, так і крапки, коми, крапки з комами. Ми згадували про них під час обговорення equ;

б) для того щоб указати, що деякий символ усередині рядка, який відповідає фактичному параметру, є власним символом, а не, наприклад, деяким роздільником або обмежуючою дужкою, застосовується спеціа-льний оператор “!”. Цей оператор ставиться безпосередньо перед описа-ним вище символом, і його дія еквівалентна узяттю даного символу в кутові дужки;

в) якщо потрібно обчислення в рядку деякого константного виразу, то на початку цього виразу ставиться знак “%”:

%константний_вираз У цьому випадку значення константний_вираз обчислюється і пі-

дставляється в текстовому вигляді відповідно до поточної системи чис-лення.

ПРИКЛАД. Нехай необхідно поміняти місцями слова a і b. Макрос

набуде такого вигляду: swapw macro a, b

push ax push bx mov ax, a mov bx, b

Page 324: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

324

mov a, bx mov b, ax pop bx pop ax

endm Допускається багаторазове перевизначення макросу в програмі. Діє

останнє визначення. ПРИКЛАД. Нехай необхідно в програмі обчислити значення мак-

симального елемента з двох заданих: max macro x, y, z push eax mov eax, x cmp eax, y jle m1 mov eax, y m1: mov z, eax pop eax endm Нехай у програмі необхідно багаторазово використовувати цей мак-

рос. При повторному його використанні буде помилка в зв’язку з повто-ренням мітки. Для забезпечення використання внутрішніх міток викори-стовується директива local мітка. У цьому випадку компілятор формує щоразу унікальну мітку. Директива local повинна бути записана відразу після заголовка МВ.

ПРИКЛАД 1. Скласти програму для визначення максимального

елемента для трьох чисел за допомогою макросів: masm .model small .stack 256 max macro x, y, z

local m1 push ax mov al, x cmp al, y jge m1 mov al, y

m1: mov z, al

Page 325: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

325

pop ax endm .data

x db 3 y db 5 z db 2 v db ?

.code main: mov ax, @data

mov ds, ax xor ax, ax max [x], [y], [v] max [v], [z], [v] mov ax, 4c00h int 21h

end main

ПРИКЛАД 2. Розташування макрокоманди в тілі програми. Про-грама вводить два 16-кових числа: masm model small .stack 256 init macro ;Макрос настроювання ds на сегмент даних

mov ax, @data mov ds, ax

endm outsc macro str ;Макрос виведення рядка на екран. ;На вході – виведений рядок. На виході – повідомлення на екрані. push ax ;збереження вмісту ах у стеку ;аргумент функції переривання при виведенні повідомлення на екран

mov ah, 09h mov dx, offset str ; виведення повідомлення через регістр dx int 21h pop ax ;відновлення регістра ах

endm clear macro rg ;очищення регістра rg

xor rg, rg endm getc macro ;введення символу mov ah,1h ;аргумент функції виведення символу int 21h

Page 326: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

326

endm ;макрос перетворення символу 16-ричного числа conv macro sub al, 30h ;двійкове подання в al cmp al, 9h ;якщо оп1<= оп2 fz=1

jle $+4 ;збільшення лічильника команд на 4 sub al, 7h endm exit macro ;макрос кінця програми mov ax, 4c00h int 21h endm .data message db ‘Введіть дві 16-кові цифри (прописні): $’ .code main: init

outsc message clear ax getc conv mov cl, 4h ;у лічильник занесли 4 shl al, cl ;зрушуємо вміст ах на 4 mov dl,al ;у dx перемістили ах getc conv add dl, al ;склали ах і dx, результат у dx mov dl, al exit

end main ПРИКЛАД 3. Розміщення макрокоманд в окремому файлі (на основі

попереднього прикладу 2): 1) Файл pf.asm masm model small include PF.inc .stack 256

.data message db ‘Введіть дві 16-кові цифри (прописні): $’

Page 327: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

327

.code main: init outsc message clear ax getc conv mov cl, 4h shl al, cl mov dl, al getc conv add dl, al exit end main

2) Файл pf.inc init macro ;Макрос настроювання ds на сегмент даних mov ax, @data mov ds, ax endm outsc macro str ;Макрос виведення рядка на екран. ;На вході – виведений рядок. На виході – повідомлення на екрані. push ax mov ah, 09h mov dx, offset str int 21h pop ax endm clear macro rg ;очищення регістра rg xor rg, rg endm getc macro ;введення символу mov ah, 1h int 21h endm conv macro ;макрос перетворення символу 16-кового числа

Page 328: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

328

sub al, 30h cmp al, 9h jle $+4 sub al, 7h endm exit macro ;макрос кінця програми mov ax, 4c00h int 21h endm

Запитання для самоперевірки

1. Для чого необхідні макрозасоби? 2. На якому етапі роботи програми використовуються макроко-

манди? 3. Яке призначення псевдооператорів equ і =? 4. Чим відрізняється макрокоманда від макророзширення? 5. Для чого необхідна директива local?

11.2. Макродирективи За допомогою макрозасобів ассемблеру можна не тільки частково

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

директив повторення WHILE, REPT, IRP, IRPC, які призна-чені для створення макросів і містять кілька однакових послідовностей рядків, що їдуть підряд. При цьому можлива часткова модифікація цих рядків;

директив керування процесом генерації МР EXITM і GOTO.

Вони призначені для керування процесом формування МР із набору ряд-

ків відповідного МВ. За допомогою цих директив можна як виключати

окремі рядки з МР, так і зовсім припиняти процес генерації. EXITM і

GOTO зазвичай використовуються разом з умовними директивами ком-

піляції, тому вони будуть розглянуті разом з ними.

Page 329: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

329

11.2.1. Директиви повторення

Директиви WHILE і REPT застосовують для повторення деякої пос-

лідовності рядків визначеної кількості разів. Ці директиви мають такий

синтаксис:

WHILE константний_вираз

послідовність_рядків

ENDM

REPT константний_вираз

послідовність рядків

ENDM

Послідовність повторюваних рядків в обох директивах обмежена

директивою ENDM.

При використанні директиви WHILE макрогенератор транслятора

буде повторювати послідовність рядків доти, поки значення констант-

ного_виразу не стане дорівнювати нулю. Це значення обчислюється

щоразу перед черговою ітерацією циклу повторення (тобто значення

константний_вираз повинне піддаватися зміні усередині значення пос-

лідовність_рядків у процесі макрогенерації).

Перед кожною ітерацією тіла МК асемблер обчислює констант-

ний_вираз. Слід уникати нескінченних циклів, бо це може призвести до

того, що асемблер вичерпає доступну пам’ять або припинить роботу.

ПРИКЛАД. Використання директиви WHILE:

WHILE 1

; операції не виконуються

ENDM

Директива REPT, подібно директиві WHILE, повторює послідов-

ність_рядків стільки разів, скільки це визначено значенням констант-

ний_вираз. Відмінність цієї директиви від WHILE полягає в тому, що

вона автоматично зменшує на одиницю значення константного_виразу

після кожної ітерації.

ПРИКЛАД 1. Код

REPT 4

shl ax, 1

ENDM

дасть у результаті таке:

Page 330: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

330

shl ax, 1

shl ax, 1

shl ax, 1

shl ax, 1

ПРИКЛАД 2. Нехай необхідно збільшити на 4 вміст регістра eах, не

змінюючи коду перенесення (біт С):

REPT 4

inc ax

ENDM

Таким чином, директиви REPT і WHILE зручно застосовувати для

«розмноження» у тексті програми послідовності однакових рядків без

внесення в ці рядки яких-небудь змін.

Для повторення тіла МК для кожного елемента в списку або кожно-

го символу в рядку можна використовувати директиви повторення IRP

і IRPC. Кожна з них вимагає завдання одного формального аргументу.

Наведемо синтаксис директиви IRP:

IRP формальний_аргумент, <рядок_симв._1, ..., рядок_симв._n>

послідовність_рядків

ENDM

Директива IRPC має такий синтаксис:

IRPC формальний_аргумент, рядок_символів

послідовність рядків

ENDM

В обох випадках “формальний_аргумент” – це аргумент, викорис-

товуваний у тілі МК. Кінець тіла МК закінчується директивою ENDM.

ПРИКЛАД.

IRP rg <ax, bx, cx, dx>

push rg

ENDM

дає таке

push ax

push bx

push cx

push dx

У синтаксисі директиви IRP “список_аргументів” складається зі

списку аргументів, розділених комами. Аргументами може бути будь-

Page 331: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

331

який текст (ідентифікатори, рядки, числа і т.д.). Форма кожного аргуме-

нту в списку аналогічна описаній вище для виклику загальної макроко-

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

слід брати в кутові дужки (< >).

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

ка. Рядок може містити будь-яку кількість символів.

ПРИКЛАД.

IRPC luc, 1379

db luc

ENDM

дає таке

db 1

db 2

db 3

db 4

Використовуйте директиву IRPC акуратно, оскільки асемблер поз-

начає кожен символ у рядку в МР “як є”, тому МК строкового повторен-

ня

IRPC char, grup

db char

ENDM

може не дати db ‘g’, ‘r’, ‘u’, ‘р’, а db g, r, u, p (де кожна буква інтерпре-

тується як ім’я ідентифікатора.

11.2.2. Директиви умовної компіляції

Існує два класи умовних директив: директиви умовного асемблю-

вання й умовні директиви генерації повідомлень про помилку. За

допомогою директив умовного асемблювання можна керувати кодом,

який буде асемблюватися в програмі за певних умов. Директиви генеру-

ють під час асемблювання повідомлення про помилки при настанні пев-

них подій. Асемблер виводить повідомлення про помилку на екран і у

файл лістинга і запобігає створенню об’єктного файла.

З цими директивами застосовуються директиви керування проце-

сом генерації МР EXITM і GOTO.

Директива

EXITM

Page 332: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

332

не має операндів, і її дія полягає в тому, що вона негайно припиняє про-

цес генерації МР, починаючи з того місця, в якому вона з’явилася в МВ.

Директива

GOTO ім’я_мітки

переводить процес генерації МВ в інше місце, припиняючи тим самим

послідовне розгортання рядків МВ. Мітка, на яку передається керування,

має спеціальний формат:

:ім’я_мітки

Дані директиви призначені для організації вибіркової трансляції

фрагментів програмного коду. Така вибіркова компіляція означає, що в

МР включаються не всі рядки МВ, а тільки ті, котрі задовольняють ви-

значені умови.

Те, які конкретно умови повинні бути перевірені, визначається ти-

пом умовної директиви. Введення в мову асемблеру цих директив знач-

но підвищує його ефективність. Усього існує 10 типів умовних директив

компіляції. Їх логічно попарно об’єднати в чотири групи:

IF і IFE – умовна трансляція за результатами обчислення логіч-

ного виразу;

IFDEF і IFNDEF – умовна трансляція за фактами визначення

символічного імені;

IFB і IFNB – умовна трансляція за фактами визначення фактич-

ного аргументу при виклику МК;

IFIDN, IFIDNI, IFDIF і IFDIFI – умовна трансляція за резуль-

татами порівняння рядків символів.

Умовні директиви компіляції мають загальний синтаксис і застосо-

вуються в складі такої синтаксичної конструкції:

IFxxx логічний_вираз_або_аргументи

фрагмент_програми_1

ELSE

фрагмент_програми_2

ENDIF

Виведення деяких фрагментів тексту програми – фраг-

мент_програми_1 і фрагмент_програми_2 – між директивами IFxxx,

ELSE і ENDIF приводить до їхнього вибіркового включення в об’єктний

модуль. Який саме з цих фрагментів – фрагмент_програми_1 або фра-

гмент_програми_2 – буде включений в об’єктний модуль, залежить від

конкретного типу умовної директиви, що задається значенням ххх і зна-

ченням умовної директиви логічний_вираз_або_ аргумент(и).

Page 333: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

333

Директиви IF і IFE

Синтаксис цих директив такий:

IF(E) логічний_вираз

фрагмент_програми_1

ELSE

фрагмент_програми_2

ENDIF

Обробка цих директив макроасемблером полягає в обчисленні логі-

чного виразу і включенні в об’єктний модуль фрагмент_програми_1

або фрагмент_програми_2, залежно від того, у якій директиві – IF або

IFE – цей вираз зустрівся.

Якщо в директиві IF логічний вираз є істинним, то в об’єктний мо-

дуль розміщується фрагмент_програми_1. Якщо логічний вираз поми-

лковий, то при наявності директиви ELSE в об’єктний код включається

фрагмент_програми_2.

Якщо директива ELSE відсутня, то вся частина програми між дире-

ктивами IF і ENDIF ігнорується й до об’єктного модуля нічого не вклю-

чається.

Директива IFE, аналогічно директиві IF, аналізує значення логічно-

го виразу. Але тепер для включення фрагмент_програми_1 в об’єктний

модуль потрібно, щоб логічний_вираз мав значення “неправда”.

Директиви IF і IFE дуже зручно використовувати при необхідності

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

ПРИКЛАД. Ідентифікатор test керує включенням коду (якщо іден-

тифікатор не визначений, то генерується відповідний блок коду). Іден-

тифікатор color має ненульове значення, якщо дисплей кольоровий, і

дорівнює 0, якщо дисплей монохромний.

Від цих значень залежить фактична генерація коду:

IFDEF test ;true, якщо test визначений

; перша частина блока коду, якщо test визначений

IF color ; true, якщо color 0

; блок коду color, якщо color 0

ELSE

; код для монохромного дисплея, якщо color = 0

ENDIF

; друга частина блока коду, якщо test визначений

Page 334: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

334

ELSE

; інший код, якщо test не визначений

ENDIF

test color Визначений 0 Визначений

не 0

Не визначений 0 Не визначений не

0

Код Блок коду 1 Блок коду 1 Інший код Інший код

Кольоровий

/моно

Блок коду

color

Блок коду 2 Блок коду 2

Якщо ідентифікатор test не визначений, то код не асемблюється ні

для кольорового дисплея (color), ні для монохромного, оскільки все це

включено в блок умовного асемблювання, яке виконується тільки при

визначеному ідентифікаторі test.

Директиви IFDEF і IFNDEF

Синтаксис цих директив такий:

IF(N)DEF символічне_ім’я

фрагмент_програми_1

ELSE

фрагмент_програми_2

ENDIF

Дані директиви дозволяють керувати трансляцією фрагментів про-

грами залежно від того, чи визначене в програмі деяке символічне_ім’я.

Директива IFDEF перевіряє, описане або ні в програмі символіч-

не_ім’я, і якщо це так, то в об’єктний модуль вводиться фраг-

мент_програми_1. У противному разі, за наявності директиви ELSE, в

об’єктний код міститься фрагмент_програми_2. Якщо ж директиви

ELSE немає (і символічне_ім’я в програмі не описане), то вся частина

програми між директивами IF і ENDIF ігнорується й в об’єктний модуль

не включається.

Якщо символічного імені в програмі немає, то транслюється фраг-

мент_програми_1. Якщо воно присутнє, то за наявності ELSE транслю-

ється фрагмент_програми_2. Якщо директива ELSE відсутня, а сим-

волічне_ім’я в програмі визначене, то частина програми, укладена між

IFNDEF і ENDIF, ігнорується.

Page 335: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

335

Директиви IFB і IFNB

Синтаксис цих директив такий:

IF(N)B аргумент

фрагмент_програми_1

ELSE

фрагмент_програми_2

ENDIF

Дані директиви використовуються для перевірки фактичних пара-

метрів, переданих у макрос. При виклику директив вони аналізують зна-

чення аргументу й залежно від того, дорівнює воно пропуску чи ні, тран-

слюється або фрагмент_програми_1, або фрагмент_програми_2.

Який саме фрагмент буде обраний, залежить від коду директиви.

Директива IFB перевіряє рівність аргументу пропуску. Як аргу-

мент можуть виступати ім’я або число. Якщо його значення дорівнює

пропуску (тобто фактичний аргумент при виклику МК не був заданий),

то вона транслюється і розміщується в об’єктному модулі фраг-

мент_програми_1. У противному разі, за наявності директиви ELSE, в

об’єктний код міститься фрагмент_програми_2. Якщо ж директива

ELSE відсутня, то при рівності аргументу пропуску вся частина програ-

ми між директивами IFB і ENDIF ігнорується й в об’єктний модуль не

включається.

Дія директиви IFNB протилежна дії директиви IFB. Якщо значення

аргументу в програмі не дорівнює пропуску, то транслюється фраг-

мент_програми_1. У противному разі, за наявності ELSE, в об’єктний

код міститься фрагмент_програми_2. Якщо ж директива ELSE відсут-

ня, то вся частина програми (при нерівності аргументу пропуску) між

директивами IFNB і ENDIF ігнорується й в об’єктний модуль не вклю-

чається.

Директиви IFIDN, IFIDNI, IFDIF і IFDIFI

Ці директиви дозволяють не просто перевірити наявність або зна-

чення аргументів МК, але і виконати ідентифікацію аргументів як рядків

символів.

Синтаксис цих директив такий:

IFIDN(I) аргумент_1, аргумент_2

фрагмент_програми_1

Page 336: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

336

ELSE

фрагмент_програми_2

ENDIF

IFDIF(I) аргумент_1, аргумент_2

фрагмент_програми_1

ELSE

фрагмент_програми_2

ENDIF

У цих директивах перевіряються аргумент_1 і аргумент_2 як ряд-

ки символів. Який саме код – фрагмент_програми_1 або фраг-

мент_програми_2 – буде транслюватися за результатами порівняння,

залежить від коду директиви. Парність цих директив дозволяє врахову-

вати розходження малих і великих букв. Так, директиви IFIDNI і IFDIFI

ігнорують це розходження, а IFIDN і IFDIF – враховують.

Директива IFIDN(I) порівнює символьні значення аргумент_1 і

аргумент_2. Якщо результат порівняння позитивний, то фраг-

мент_програми_1 транслюється і розміщується в об’єктному модулі. У

противному разі, за наявності ELSE, в об’єктний код міститься фраг-

мент_програми_2. Якщо ж директиви ELSE немає, то вся частина про-

грами між директивами IFIDN(I) і ENDIF ігнорується й в об’єктний

модуль не включається.

Якщо результат порівняння негативний (рядки не збігаються), тран-

слюється фрагмент_програми_1. У противному разі усе відбувається

аналогічно розглянутим директивам.

Ці директиви зручно застосовувати для перевірки фактичних аргу-

ментів МК.

TASM допускає включення умовних директив компіляції. Оскільки

включення використовується часто, TASM дає набір додаткових дирек-

тив формату ELSEIFxxx, що заміняють послідовність ELSE і IFxxx у

структурі.

ПРИКЛАД 1.

Ifxxx

;…

ELSE

Ifxxx

;…

Page 337: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

337

ENDIF

ENDIF

Цю послідовність умовних директив можна замінити еквівалентною

послідовністю додаткових директив:

Ifxxx

;…

ELSEIFxxx

;…

ENDIF

ПРИКЛАД 2. Написати макрос для визначення в програмі області

пам’яті довжиною не більш 20 і не менш 10 байт. Для обробки реакції на

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

EXITM і GOTO:

masm

model small

stack 256

deftab macro len

IF len GE 20 ;введення числа більше 20?

GOTO exit

ENDIF

IF len LT 10 ;введення числа менше 10?

:exit

EXITM

ENDIF

REPT len ;повторювати рядок стільки, скільки визначено len

db ‘@’

ENDM

ENDM

.data

deftab 14

deftab 10

.code

main:

mov ax, @data

mov ds, ax

mov ax, 4c00h

Page 338: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

338

int 21h

end main

Результат необхідно розглянути в середовищі td.exe, сегмент даних

– за адресою ds:0000.

11.2.3. Директиви генерації повідомлень про помилку ERRxx

У мові TASM є ряд директив, які називаються директивами гене-

рації користувальницької помилки. Вони призначені для виявлення

різних помилок у програмі, таких, як невизначені мітки або пропуск

параметрів макросу. Директиви генерації помилки користувача за прин-

ципом роботи можна розділити на два типи:

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

перевірки яких-небудь умов;

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

ревірки визначених умов.

Більшість директив генерації помилок має два позначення, хоча

принцип їхньої роботи однаковий. Друга назва відбиває їхню подібність

з директивами умовної компіляції. При подальшому обговоренні такі

парні директиви будуть наводитися в дужках.

Безумовна генерація помилки користувача

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

ся тільки одна директива — ERR (.ERR).

Дана директива, будучи вставлена в текст програми, призводить до

генерації помилки на етапі трансляції і до видалення об’єктного модуля.

Вона дуже ефективна при використанні з директивами умовної компі-

ляції або в тілі МК. Директиву .ERR можна використовувати тільки в

режимі MASM.

Умовна генерація помилки користувача

Набір умов, на які реагують директиви умовної генерації помилки

користувача, такий же, як і для директив умовної компіляції. Тому і кі-

лькість цих директив така ж. Використовувати більшість директив умов-

ної генерації помилки користувача можна як у МВ, так і в будь-якім міс-

ці програми.

Page 339: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

339

Директиви .ERRB (ERRIFB) і .ERRNB (ERRIFNB)

Синтаксис директив такий:

.ERRB (ERRIFB) <ім’я_формального_аргументу>

– генерація помилки користувача, якщо <ім’я_формального

_аргументу> пропущено;

.ERRNB (ERRIFNB) <ім’я_формального_аргументу>

– генерація помилки користувача, якщо <ім’я_формального

_аргументу> пропущено.

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

залежно від того, заданий чи ні при виклику макрокоманди фактичний

аргумент, що відповідає формальному аргументу в заголовку МВ з ім’ям

<ім’я_формального_аргументу>. За принципом дії ці директиви ціл-

ком аналогічні відповідним директивам умовної компіляції IFB і IFNB.

Їх звичайно використовують для перевірки завдання параметрів при ви-

клику макросу. Рядок ім’я_формального_аргументу повинний бути

взятий у кутові дужки.

Директиви .ERRDEF (ERRIFDEF) і .ERRNDEF

(ERRIFNDEF)

Синтаксис директив такий:

.ERRDEF (ERRIFDEF) символічне_ім’я

– якщо дане ім’я визначене до видачі цієї директиви в програмі, то

генерується помилка користувача;

.ERRNDEF (ERRIFNDEF) символічне_ім’я

– якщо зазначене символічне_ім’я не визначене до моменту обро-

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

Дані директиви генерують помилку трансляції залежно від того, ви-

значене чи ні деяке символічне_ім’я в програмі. Не забувайте про те,

що компілятор TASM за умовчанням формує об’єктний модуль за один

прохід вихідного тексту програми. Отже, директиви .ERRDEF

(ERRIFDEF) і .ERRNDEF (ERRIFNDEF) відстежують факт визначення

символічного_імені тільки в тій частині вихідного тексту, яка знаходить-

ся до цих директив.

ПРИКЛАД. Є така директива:

Page 340: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

340

ERRIFNDEF mmm «mmm не визначений!»

Якщо ідентифікатор mmm не визначений при виявленні помилки,

це призведе до генерації помилки:

User error: «mmm не визначений!»

Директиви .ERRDIF (ERRIFDIF) і .ERRIDN (ERRIFIDN)

Синтаксис директив такий:

.ERRDIF (ERRIFDIF) <рядок_1>, <рядок_2>

– директива, що генерує помилку користувача, якщо два рядки по-

символьно не збігаються.

Рядки можуть бути символічними іменами, числами або виразами і

повинні бути взяті в кутові дужки.

Аналогічно директиві умовної компіляції IFDIF, при порівнянні

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

.ERRIDN (ERRIFIDN) <рядок_1>, <рядок_2>

– директива, що генерує користувальницьку помилку, якщо рядки

посимвольно ідентичні. Одні і ті ж малі і великі букви сприймаються як

різні символи.

Для того щоб ігнорувати розходження малих і великих букв, існу-

ють аналогічні директиви:

.ERRIFDIFI <рядок_1>, <рядок_2>

– те ж, що і ERRIFDIF, але ігнорується розходження малих і вели-

ких букв при порівнянні <рядок_1> і <рядок_2>.

.ERRIFIDNI <рядок_1>, <рядок_2>

– те ж, що і ERRIFIDN, але ігнорується розходження малих і вели-

ких букв при порівнянні <рядок_1> і <рядок_2>.

Дані директиви, як і відповідні їм директиви умовної компіляції,

зручно застосовувати для перевірки переданих у макрос фактичних па-

раметрів.

Директиви .ERRE (ERRIFE) і .ERRNZ (ERRIF)

Синтаксис директив такий:

.ERRE (ERRIFE) константний_вираз

Page 341: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

341

– директива викликає помилку користувача, якщо констант-

ний_вираз помилковий (дорівнює нулю). Обчислення константно-

го_виразу повинне приводити до абсолютного значення, і цей вираз не

може містити компонентів, що є посиланнями вперед.

.ERRNZ(ERRIF) константний_вираз

– директива викликає помилку користувача, якщо констант-

ний_вираз є істинним (не дорівнює нулю). Обчислення константно-

го_виразу повинне привести до абсолютного значення і не може місти-

ти компонентів, що є посиланнями вперед.

11.2.4. Додаткове керування трансляцією

TASM дає можливість виводити текстове повідомлення під час тра-

нсляції директиви

display

і

%out.

З їхньою допомогою можна при необхідності стежити за ходом

трансляції.

ПРИКЛАД.

display ; неприпустимі аргументи макрокоманди

;...

%out ; неприпустиме ім’я регістра

У результаті обробки цих директив на екран будуть виведені тексти

повідомлень. Якщо ці директиви використовувати разом з директивами

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

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

11.2.5. Константні вирази в умовних директивах

У мові асемблеру існують оператори, що дозволяють сформувати і

«чисто логічний» результат. Це так звані оператори відносин, що озна-

чають відношення двох значень або константних виразів. У контексті

умовних директив разом з операторами відносин можна розглядати і

логічні оператори. Результатом роботи і тих, і інших може бути одне з

двох значень:

– істина – число, що містить двійкові одиниці у всіх розрядах;

– неправда – число, що містить двійкові нулі у всіх розрядах.

Page 342: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

342

Оператори, які можна застосовувати у виразах умовних директив і

які формують логічні результати, наведено в табл. 11.1.

Таблиця 11.1

Оператори відносин

Оператор відносини Синтаксис Результат

EQ (equal) – дорівнює вир_1 EQ

вир_2

Істина, якщо вир_1 = вир_2

NE (not equal) – не дорів-

нює

вир_1 NE

вир_2 Істина, якщо вир_1 вир_2

LT (less than) – менше вир_1 LT

вир_2

Істина, якщо вир_1 < вир_2

LE (less or equal) – менше

або дорівнює

вир_1 LE

вир_2

Істина, якщо вир_1 ≤ вир_2

GT (greater than) – більше вир_1 GT

вир_2

Істина, якщо вир_1 > вир_2

GE (greater or equal) – бі-

льше або дорівнює

вир_1 GE

вир_2

Істина, якщо вир_1 ≥ вир_2

Запитання для самоперевірки

1. Для чого необхідні макродирективи? 2. Як можна здійснити додаткове керування трансляцією? 3. Для чого необхідні константні вирази в директивах?

11.3. Процедури мови асемблеру

11.3.1. Загальна схема зв’язку модулів на асемблері

Найбільш істотні концепції модульного програмування можна

викласти у вигляді таких правил: поділ і підпорядкування. Поділити проблему на вузькі функціо-

нальні задачі, кожна з яких буде не залежною від інших; один вхід – один вихід. Модуль повинний мати тільки одну точ-

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

«KISS-принцип» (Keep It Simple, Stuiped – роби усе простіше,

Page 343: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

343

дурнику). Уникайте складності при кодуванні модуля. Використовуйте

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

кожен крок і спосіб його проектування;

приховання подробиць. Обмежуйте подробиці використання ре-

гістрів, структури локальних даних і т.д. для внутрішніх модулів. Не до-

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

шилася;

якщо модуль використовує особливу змінну, зробіть так, щоб

змінна була документованим параметром. Документуйте всі дії, щоб мо-

дуль мав глобальні дані;

плануйте виявлення помилок і дії, які мають бути початими при

виникненні помилки. Відповідальність за обробку виняткових ситуацій,

як відомо, повинна лягати на конкретні модулі. Звичайно модулі ниж-

нього рівня передають звіти про помилки у відповідний модуль. Відпо-

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

за модулями верхнього рівня.

У мові асемблеру для оформлення процедур як окремих об’єктів іс-

нують спеціальні директиви proc/endp і машинна команда ret. Процеду-

ри, як і МК, можуть бути активізовані в будь-якому місці програми.

Процедурам, як і МК, можуть бути передані деякі аргументи, що дозво-

ляє мати одну копію коду в пам’яті, змінювати її для кожного конкрет-

ного випадку використання, хоча по гнучкості використання процедури

уступають МК.

Варіанти розміщення процедур у програмі:

на початку програми (до першої команди, що виконується);

наприкінці (після команди, що повертає керування операційній

системі);

проміжний варіант – тіло процедури розташовується усередині

іншої процедури або процедури основної програми. У цьому випадку

необхідно передбачити обхід процедури за допомогою команди безумо-

вного переходу jmp;

в іншому модулі.

Вигляд процедури за умовчанням визначається тією моделлю

пам’яті, у якій розробляється програма. Для моделей tiny, small і

compact усі процедури є ближніми (near). Для моделей medium, large і

huge виклики процедур є далекими (far). Для оформлення процедур ви-

користовуються директиви proc і endp.

Структура процедури така:

Page 344: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

344

ім’я proc [near] [far]

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

ret

endp ім’я

Кожна процедура має унікальне ім’я, що і використовується при ви-

клику цієї процедури за допомогою команди call ім’я. Виклик процеду-

ри можна також здійснити за допомогою непрямої адресації. Командою

ret здійснюється повернення в перервану програму. Процедура повинна

бути частиною сегмента кодів. Вона може бути записана або в окремому

файлі (зовнішня), або в тім же, що і перервана програма (на початку се-

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

програми).

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

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

рез кожен(і) регістр(и). При стикуванні різномовних модулів використо-

вуються стандартні угоди про регістри.

Внутрішній пристрій модулів може удосконалюватися, вони взагалі

можуть записуватися на іншій мові, але в процесі їхнього об’єднання в

єдиний модуль цих особливостей не повинно бути помітно. Таким чи-

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

щав би транслятор про те, що деякий об’єкт (процедура, перемінна) по-

винний бути видимим поза цим модулем. І навпаки, потрібно повідоми-

ти транслятору, що деякий об’єкт знаходиться поза даним модулем. Це

дозволить транслятору правильно сформувати машинні команди, зали-

шивши деякі їх поля незаповненими. Пізніше, на етапі компонування,

програма TLINK або програма компонування мови високого рівня вико-

нує настроювання модулів і дозволяє усі зовнішні посилання в поєдну-

ваних модулях.

Для того щоб оголосити про подібний ряд видимих ззовні об’єктів,

програма повинна використовувати дві директиви TASM: extrn і publiс.

Директива extrn призначена для оголошення деякого імені зовніш-

нім відносно даного модуля. Це ім’я в іншому модулі повинне бути ого-

лошене в директиві public.

Директива public призначена для оголошення деякого імені, визна-

ченого в цьому модулі і видимого в інших модулях. Синтаксис цих ди-

ректив такий:

extrn ім’я: тип, ..., ім’я: тип

Page 345: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

345

public ім’я, ..., ім’я

Тут ім’я — ідентифікатор, визначений в іншому модулі. Як іденти-

фікатор можуть виступати:

імена змінних, визначених директивами типу db, dw і т.д.;

імена процедур;

імена констант, визначених операторами = і equ.

Тип визначається виглядом ідентифікатора. Указувати тип необхід-

но для того, щоб транслятор правильно сформував відповідну машинну

команду. Дійсні адреси будуть обчислені на етапі редагування, коли бу-

дуть дозволятися зовнішні посилання. Можливі значення типу визнача-

ються припустимими типами об’єктів для цих директив:

– якщо ім’я є ім’ям змінної, то тип може набувати таких значень:

byte, word, dword, pword, fword, qword і tbyte;

– якщо ім’я є ім’ям процедури, то тип може набувати значення near

або far;

– якщо ім’я є ім’ям константи, то тип повинний бути abs.

ПРИКЛАД. Покажемо принцип використання директив extrn і

public на схемі зв’язку двох модулів: модуля 1 і модуля 2.

1) Модуль 1 masm .model small .stack 256

.data ;…

.code my_pr_l proc

;… my_pr_l endp my_pr_2 proc

;… my_pr_2 endp

;повідомляємо процедуру my_pr_l видимої ззовні public my_pr_l start:

mov ax, @data ;...

end start

2) Модуль 2

Page 346: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

346

masm .model small .stack 256 .data

;… .code extrn my_pr_l ;повідомляємо процедуру my_pr_l зовнішньої start:

mov ax, @data ;...

call my_pr_l ; виклик my_pr_l з Модуля 1 end start

Розглянута нами схема зв’язку – це, фактично, зв’язок з керуван-

ня. Але не менш важливо організувати інформаційний обмін між моду-

лями.

11.3.2. Організація інтерфейсу з процедурою

Аргумент – це посилання на деякі дані, що потрібні для виконання

покладених на модуль функцій, які розміщені поза цим модулем. За ана-

логією з макрокомандами існують поняття формального і фактичного

аргументів. Формальний аргумент можна розглядати як елемент інтер-

фейсу модуля, а фактичний аргумент – це те, що фактично передається

на місце формального аргументу.

Змінна – це щось, розміщене в регістрі або комірці пам’яті, що мо-

же надалі піддаватися зміні.

Константа – це величина, значення якої ніколи не змінюється.

Існують такі варіанти передачі аргументів у модуль (процедуру):

через регістри;

через загальну область пам’яті;

через стек;

за допомогою директив extrn і public.

11.3.2.1. Передача аргументів через регістри

Передача параметрів через регістри є найбільш простим у реалізації

способом передачі даних, які стають доступними одразу після передачі

Page 347: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

347

керування процедурі. Використання цього способу стає доцільним при

невеликому обсязі передачі даних.

До обмежень на спосіб передачі аргументів через регістри слід від-

нести:

невелику кількість доступних для користувача регістрів;

необхідність постійно пам’ятати про те, яка інформація в якому

регістрі знаходиться;

обмеження розміру переданих даних розмірами регістра. Якщо

розмір даних перевищує 8/16/32 біти, то передачу даних за допомогою

регістрів здійснити не є можливо. У цьому випадку передавати потрібно

не самі дані, а їх указівники.

Такий спосіб передачі аргументів широко застосовується при ви-

клику функцій MS-DOS.

ПРИКЛАД. Написати програму підрахунку кількості сим-

волів у рядку і записати результат у регістр bx. Обмежити кі-

лькість регістрів.

masm

model small

stack 256

.data

string db ‘01234567$’

.code

main proc ;підрахунок символів у рядку

mov ax, @data

mov ds, ax

lea si, string ;у si – зсув рядка

call CountSymbol ;у bx – довжина рядка в упакованому вигляді

mov ax, 4c00h

int 21h

main endp

CountSymbol proc near ;підрахунок символів у рядку

push ax ;збереження вмісту використовуваних регістрів

push cx

cld ;очищення прапорця напрямку

mov cx, 100 ;максимальна довжина рядка

go:

lodsb ;завантажити байт із ланцюжка в регістр al

cmp al,’$’ ;чи досягли кінцевого символу?

Page 348: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

348

je endstr ;якщо оп1 = оп2, zf = 1

jcxz exit ;перехід за міткою при досягненні 0

inc bl ;збільшення лічильника кількості

loop go ;повторення циклу

endstr:

pop cx ;відновлення вмісту регістрів

pop ax

ret

exit: ret

CountSymbol endp

end main

11.3.2.2. Передача аргументів через загальну область пам’яті

Цей варіант передачі аргументів припускає, що викликана і викли-

кувана програми “умовилися” використовувати деяку область пам’яті як

загальну. Транслятор надає спеціальний засіб для організації такої обла-

сті пам’яті. Один з них – атрибут комбінування сегментів. Наявність

цього атрибута вказує укладачу (компоновщику – рос.) TLINK, як потрі-

бно комбінувати сегменти, що мають одне ім’я. Значення common

означає, що всі сегменти, які мають однакове ім’я в поєднуваних моду-

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

ративної пам’яті. Це означає, що вони будуть просто перекриватися в

пам’яті і, отже, спільно використовувати виділену пам’ять.

Недоліком цього способу в реальному режимі роботи мікропроце-

сора є відсутність засобів захисту даних від руйнування, тому що не мо-

жна проконтролювати дотримання правил доступу до цих даних.

ПРИКЛАД. Є 2 незалежних модулі (файли). Викликана процедура

формує рядок символів і передає її в загальну область пам’яті, а виклич-

на процедура main виводить рядок на екран:

1) Модуль pc.asm з викликаною процедурою

stk segment stack

db 256 dup (0)

stk ends

;адреса сегмента кратна 16 і розташування

;сегментів з одним ім’ям по одній адресі

cd segment para common ‘data’

buf db 15 dup (‘ ‘) ;буфер для збереження рядка

Page 349: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

349

cd ends

public pc ;поєднання сегментів з одним ім’ям

code segment

assume cs:code, es:cd ;прив’язка областей пам’яті до сегментів

pc proc far ;межсегментний зв’язок

cld ;перегляд уперед

mov si,0

mov buf[si], ‘P’

inc si

mov buf[si], ‘r’

inc si

mov buf[si], ‘i’

inc si

mov buf[si], ‘v’

inc si

mov buf[si], ‘e’

inc si

mov buf[si], ‘t’

inc si

mov buf[si], ‘!’

inc si

mov buf[si], ‘$’

ret

PC endp

code ends

2) Модуль main.asm із викличною процедурою.

stk segment stack

db 256 dup (0)

stk ends

cd segment para common ‘data’

buf db 15 dup (‘ ‘)

cd ends

extrn pc:far ;зовнішня процедура

code segment

assume cs:code, es:cd

main proc

call pc

Page 350: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

350

push ax

mov ah, 09h

lea dx, buf ;у dx – зсув джерела buf

int 21h

pop ax

mov ax, 4c00h

int 21h

main endp

code ends

end main

Зверніть увагу на особливість зборки об’єктного коду. Два файли

транслюються окремо, а об’єктний код збирається за допомогою коман-

ди «+» – main.obj + pc.obj.

Результат роботи програми необхідно розглянути в середовищі

td.exe. У вікні CPU буде тільки текст main.exe. Щоб перейти в процедуру

за адресою в рядку call <адреса>, слід натиснути F7, у результаті чого

відкриється друге вікно.

Структура сегментів повинна бути абсолютно ідентична (!!!) у всіх

модулях програми.

11.3.2.3. Передача аргументів через стек

Цей спосіб найчастіше часто використовується для передачі аргу-

ментів при виклику процедур. Суть його полягає в тому, що виклична

процедура самостійно заносить у стек передані дані, після чого робить

виклик викликуваної процедури.

Стек обслуговується трьома регістрами: ss, sp і bp. Мікропроцесор

автоматично працює з регістрами ss і sp у припущенні, що вони завжди

вказують на вершину стека. З цієї причини їхній вміст змінювати не ре-

комендується. Для здійснення довільного доступу до даних у стеку архі-

тектура мікропроцесора має спеціальний регістр ebp\bp (Base Point –

указівник бази). Так само як і для регістра esp\sp, використання ebp\bp

автоматично припускає роботу із сегментом стека. Перед використанням

цього регістра для доступу до даних стека його вміст необхідно прави-

льно ініціалізувати, що припускає формування в ньому адреси, яка б вка-

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

рекомендується включити додатковий фрагмент коду, який має свою

назву – пролог процедури.

Page 351: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

351

Код прологу складається усього з двох команд. Перша команда push

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

чення у викликуваній процедурі. Друга команда прологу mov bp, sp на-

нстроює bp на вершину стека. Кінець процедури також має бути оформ-

лений певним чином і містити дії, які б забезпечували коректне повер-

нення з процедури. Фрагмент коду, що виконує такі дії, має свою назву –

епілог процедури. Код епілогу повинний відновити контекст програми в

точці виклику викликуваної процедури з викличної програми. При цьому

слід відкоригувати вміст стека, забравши з нього непотрібні аргументи,

що стали зайвими. Це можна зробити декількома способами:

використовуючи послідовність з n команд pop xx. Найкраще це

робити у викличній програмі відразу після повернення керування з про-

цедури;

відкоригувавши регістр покажчика стека sp на величину 2*n,

наприклад, командою

add sp, NN

де NN=2*n; і n – кількість аргументів. Це також краще ро-

бити після повернення керування викличній процедурі; використовуючи команду ret n останньою командою у процеду-

рі, де n – кількість байт, на яку потрібно збільшити вміст регістра esp\sp

після того, як зі стека будуть зняті складові адреси повернення. Цей спо-

сіб аналогічний попередньому, але виконується автоматично мікропро-

цесором.

ПРИКЛАД. Скласти функцію для обчислення z = x + y. Параметри

передавати через стек.

.386

.model flat,stdcall

option casemap:none ; директива для відмінності прописних

;та рядкових літер

.code

start:

push dword ptr 2

push dword ptr 3

call AddPr

ret

AddPr proc

mov eax,[esp+8] ; eax = 2

add eax,[esp+4] ; eax = 5

Page 352: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

352

ret 8 ; esp = esp + 8 = 12

AddPr endp

end start

ПРИКЛАД. Скласти зовнішню функцію для обчислення z = x + y.

Параметри передавати через стек.

1. Головна програма – файл main.asm

masm

model small

.stack 100h

.data

extrn sum: far

public x, y

.data

x db 5

y db 3

z db ?

.code

main: mov ax, @data

mov ds, ax

call sum

mov [z], al

mov ax, 4c00h

int 21h

end main

2. Файл sum.asm

extrn x: byte, y: byte

public sum

stk segment stack

db 256 dup (0)

stk ends

code segment

sum proc far

assume ss:stk

push bp

mov bp, sp

mov al, x

add al, y

pop bp

Page 353: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

353

ret

sum endp

code ends

end

Результат необхідно розглянути в середовищі td.exe, сегмент стека

– за адресою ss:0000.

11.3.2.4. Використання директив extrn і public

Ці директиви вже згадувались вище, коли розглядались варіанти

взаємного розташування викличної програми і викликуваної процедури. Директиви extrn і рublіс також можна використовувати для обміну інфо-рмацією між модулями. Призначення і формати цих директив уже були розглянуті, тому зараз опишемо тільки порядок їхнього використання для обміну даними. Виділимо кілька варіантів їхнього застосування:

обидва модулі використовують сегмент даних викличної про-грами;

у кожного з модулів є свій власний сегмент даних; модулі використовують атрибут комбінування (об’єднання) сег-

ментів private у директиві сегментації segment. ПРИКЛАД. Дві процедури розташовані в різних модулях (файлах).

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

1. Файл main.asm. masm model small .stack 100h .data

extrn aib: far ;оголошення зовнішнього до модуля імені public a, b ;загальнодоступні змінні

.data a db ‘A’ b db ‘B’

.code main: mov ax, @data mov ds, ax call aib mov ax, 4c00h

Page 354: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

354

int 21h end main

2. Файл aib.asm. extrn a: byte, b: byte public aib code segment aib proc far ;міжсегментний перехід

assume cs:code ;передача аргументів через загальну область пам’яті mov dl, a push ax mov ah, 02h int 21h pop ax mov dl, b push ax mov ah, 02h int 21h pop ax ret aib endp code ends end

Відношення даних модулів таке:

Main aib

extrn aib: far extrn a: byte, b: byte

public a, b public aib

Таким чином, мітка, яка оголошена директивою public, стає досту-

пною й для інших модулів програми.

11.3.3. Повернення результату з процедури

Повернення результату з процедури організує програміст. Одер-

жання результату теж можна розглядати як передачу аргументів.

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

процедури:

1. З використанням регістрів. Обмеження тут ті ж, що і при переда-

чі даних, – це невелика кількість доступних регістрів і їхній фіксований

розмір. Функції DOS використовують саме цей спосіб. З розглянутих

Page 355: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

355

трьох варіантів даний спосіб є найбільш швидким, тому є сенс викорис-

товувати його для організації критичних за часом виклику процедур;

2. З використанням загальної області пам’яті. Цей спосіб зручний

при поверненні великої кількості даних, але вимагає уважності у визна-

ченні областей даних і докладного документування для усунення неод-

нозначностей;

3. З використанням стека. Тут, подібно передачі аргументів через

стек, також слід використовувати регістр bр. При цьому можливі такі

варіанти:

використання для аргументів тих комірок у стеку, що застосову-

валися для передачі аргументів у процедуру. Тобто передбачається за-

міщення вхідних аргументів, що стали непотрібними, вихідними даними;

попереднє розміщення в стек (поряд з переданими аргументами)

фіктивних аргументів з метою резервування місця. При використанні

цього варіанта не треба намагатися очистити стек командою ret. Цю

операцію доведеться робити у викличній програмі, наприклад, командою

pop.

Мова асемблеру не накладає ніяких обмежень на організацію про-цесу передачі даних і повернення значень між двома процедурами, а в більш загальному випадку – і між модулями, що представляють окремі файли. Найбільш швидкий спосіб такого обміну – використання регістрів. Але часто необхідно зв’язувати між собою не тільки програми, написані на асемблері, але і програми на різних мовах. У цьому випадку універсальним стає спосіб обміну даними з використанням стека.

Повернення значень у регістрах

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

Повернення значення в регістрі має сенс для часто викликуваних процедур. Це не вимагає спеціальної установки і попередньої підготовки буферів та ін. Більшість функцій MS-DOS повертає свої значення цим способом. Однак, якщо усі функції в програмі повертають свої дані че-рез регістри, то виникає необхідність ураховувати кількість доступних регістрів.

Page 356: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

356

Найчастіше регістри повинні використовуватися для невеликих, ча-

сто використовуваних викликуваних програм, що повертають небагато

значень, і для програм, що повертаються, значення яких повинні негайно

піддаватися обчисленням. Одним із прикладів цього випадку могла б

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

значення.

Повернення значень у загальній області

Повернення значень у загальній області необхідне для процедур.

Для цього використовується метод “стороннього ефекту”, що представ-

ляє простий засіб для повернення великої кількості даних.

Якщо замість параметра в регістрі або стеку передається адреса за-

гальної області, то очікувані в цій окремій області пам’яті значення, що

повертаються, стають більш очевидними.

Повернення значень у стек

Останнім способом повернення значень є повернення їх у стек. Ця

операція вимагає використання регістра bp для адресації стека (таким же

способом, як передача параметрів у стек). Значення, що повертаються у

стек, завантажуються в одну з комірок стека вище від адреси повернен-

ня. Якщо процедура викликається з параметрами, то для збереження

значення, що повертається, може бути використана одна з комірок. Як-

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

винна помістити в стек фіктивний аргумент, щоб відвести місце для зна-

чення, що повертається.

При поверненні значень у стек викликувана програма не повинна

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

процедура повинна використовувати для звертання до стека прості ін-

струкції pop (відновлення слова зі стека).

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

Page 357: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

357

Запитання для самоперевірки 1. Викладіть основні концепції модульного програмування. 2. Де можуть розміщатися процедури? 3. Для чого необхідні директиви extrn і public? 4. Як організується інтерфейс із процедурами? 5. Як повертається в головну програму результат роботи процеду-

ри?

Стислі висновки 1. Макрозасоби – це основні інструменти модифікації тексту про-

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

2. Псевдооператорами equ і = макрогенератор виконує найпрості-

ші дії, заміняючи в наступному тексті програми символічне ім’я з правої

частини цих операторів рядком з лівої.

3. Макрокоманда – рядок у вихідній програмі, якому відповідає

спеціальний блок – макровизначення. Макрокоманда може мати аргуме-

нти, за допомогою яких можна змінювати текст макровизначення. Мак-

рогенератор, зустрічаючи макрокоманду в тексті програми, коректує

текст відповідного макровизначення, виходячи з аргументів цієї макро-

команди, і вставляє його в текст програми замість даної макрокоманди.

Процес такого заміщення називається макрогенерацією.

4. Умовні директиви компіляції дозволяють не просто модифікува-

ти окремі рядки програми, але і, виходячи з визначених умов, керувати

включенням у завантажувальний модуль окремих фрагментів програми.

Ці директиви найбільш ефективні для організації роботи з аргументами,

переданими при макрогенерації в макровизначення з макрокоманди, хо-

ча окремі директиви є сенс застосовувати і поза макровизначенням в

будь-якім місці програми.

Page 358: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

358

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

умови в процесі трансляції програми і генерувати помилку за результа-

тами аналізу.

6. Мова асемблеру містить досить могутні засоби підтримки стру-

ктурного програмування. Ця технологія підтримується в основному за

допомогою механізму процедур і частково макрокоманд.

7. Гнучкість інтерфейсу між процедурами досягається за рахунок

розмаїтості варіантів передачі аргументів у процедуру і повернення ре-

зультатів. Для цього можуть використовуватися регістри, загальні облас-

ті пам’яті, стек, директиви extrn і public.

8. Засоби TASM підтримують зв’язок між мовами. Обмін даними

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

через стек. Для доступу до аргументів використовуються регістр bр (що

більш зручно) або директива arg.

9. Можна дозволити компілятору самому формувати коди прологу

й епілогу, указавши мову в директиві model. Крім того, указання мови

дозволяє задіяти символічні імена аргументів, переданих процедурі в

стеку, замість прямого використання регістра bр для доступу до них.

Тим самим підвищуються мобільність програм і стійкість їх до помилок.

10. Для повернення результату в програму мовою високого рівня

необхідно використовувати конкретні регістри. Через них можна переда-

ти як самі дані, так і покажчики.

Page 359: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

359

12. РОБОТА З КОНСОЛЛЮ

12.1. Робота з консоллю в середовищі MS-DOS

У більшості випадків програма повинна взаємодіяти з користува-

чем, одержуючи від нього дані за допомогою клавіатури і видаючи ре-

зультати своєї роботи на екран. Якими ж засобами мови виконуються

операції обміну з консоллю (консоль – клавіатура і монітор)? У мові

асемблеру власних засобів обміну з консоллю немає. Щоб виконати по-

дібну операцію, програма використовує можливості самого комп’ютера

(переривання BIOS) і ОС, у середовищі якої ця програма працює.

12.1.1. Функції BIOS для роботи з консоллю

BIOS (Basic Input Output System) являє собою сукупність програм

в ОП комп’ютера, однією з задач яких є усунення специфіки апаратних

компонентів комп’ютера для функціонуючого на ньому програмного

забезпечення, включаючи ОС. Обслуговування клавіатури і монітора виконують програми BIOS,

які називаються драйверами. Структурно драйвери складаються з ряду підпрограм, називаних функціями, кожна з яких виконує визначені дії. Звертання до функцій BIOS здійснюється аналогічно до звертання до функцій MS-DOS. Для роботи з клавіатурою й екраном BIOS містить два програмних переривання – 16h і 10h, звертання до яких є звертанням до драйверів цих пристроїв. Для виклику цих переривань, зазвичай, викори-стовується команда int – int 16h або int 10h. Для виконання визначеної операції в частині регістра аh указується номер функції. При необхідно-сті в інших регістрах може вказуватися додаткова (параметрична) інфо-рмація.

12.1.1.1. Функції BIOS для роботи з клавіатурою (переривання 16h)

Переривання 16h BIOS має функції для різних типів клавіатур: зви-

чайної – 84 клавіші і двох типів розширеної клавіатури – 101\102 і 122-клавішної.

Функціональні можливості клавіатури дозволяє визначити функція

09h:

Page 360: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

360

На вході ah = 09h.

На виході: al = бітове поле, яке використовується для позначення

таких функцій:

7 – резерв;

6 – підтримка клавіатури з 122 клавішами (і функцій 20h – 22h (int

16h));

5 – підтримка розширеної клавіатури з 101 – 102 клавішами (і фун-

кцій 10h – 12h (іnt 16h));

4 – підтримка функції 0ah (іnt 16h);

3 – підтримка функції 0306h (іnt 16h);

2 – підтримка функції 0305h (int 16h);

1 – підтримка функції 0304h (іnt 16h);

0 – підтримка функції 0300h (іnt 16h).

Перш ніж викликати цю функцію, необхідно упевнитися в тому, що

вона підтримується даною версією BIOS. Зробити це можна, викликав-

ши функцію 0c0h переривання int 15h.

На вході аh = c0h – одержати конфігурацію.

На виході:

а) cf =1 – BIOS не підтримує цю функцію;

в) cf = 0 – у разі успіху:

– es:bx – адреса конфігураційної таблиці в ОП (табл. 12.1);

– аh = стан (00h – успіх; 86h – функція не підтримується).

Якщо в результаті цього виклику 6-й біт другого байта властивостей

установлений, то BIOS підтримує функцію 09h переривання int 16h, за

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

Таблиця 12.1

Формат конфігураційної таблиці ОП

Зсув

Розмір

Опис

00h 2 байти Кількість байтів у цій таблиці

02h 1байт Модель BIOS

Page 361: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

361

Зсув

Розмір

Опис

03h 1байт Підмодель BIOS

04h 1 байт Видання BIOS:

0 – 1-а редакція, 1 – 2-а і т.д.

05h 1байт 1-й байт властивостей

06h 1 байт 2-й байт властивостей

07h 1 байт 3-й байт властивостей

08h 1байт 4-й байт властивостей

09h 1байт 5-й байт властивостей

ПРИКЛАД. Програма для визначення функціональних можливостей

клавіатури:

masm

model small

.stack 256

.486

.code

main:

mov ah, 0c0h

int l5h

push ds

push es

pop ds

xor ax, ax

mov al ,byte ptr [bx+6]

bt ax,6

pop ds

jnc exit ;функція 09h int 16h не підтримується

;функція 09h int 16h підтримується

mov ah,09h

int 16h ;аналізуємо al або ah

exit: ;вихід з програми

mov ax,4c00h ;пересилання 4c00h у регістр ax

int 21h ;виклик переривання з номером 21h

end main ;кінець програми з точкою входу main

Page 362: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

362

Системи BIOS різних виробників реалізують ці функції 0c0h int 15h

і 09h int 16h неоднозначно. Тому, якщо необхідно, закоментуйте коман-

ду jnc exit у наведеному вище прикладі.

Зчитування символу (00h, 10h, 20h int 16h)

На вході аh = 00h – зчитування символу з очікуванням (для 84-

клавішної клавіатури).

На виході:

– для звичайних клавіш (аh = скан-код BIOS; al = символ ASCII);

– для клавіш і комбінацій з розширеним ASCII-кодом (аh = розши-

рений ASCII-код; al = 0).

Функція 00h int 16h містить інформацію про черговий символ з

буфера клавіатури, і якщо її там немає, то МП очікує його появи, припи-

няючи виконання програми.

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

регістра al: якщо al 0, то натиснута клавіша клавіатури і al та ah міс-

тять відповідно символ ASCII і скан-код BIOS. У противному разі на

клавіатурі була натиснута одна з клавіш (або їхня комбінація), що відпо-

відає розширеному коду, і регістри al і аh містять відповідно нуль і роз-

ширений код клавіші.

Будь-який символ можна внести в буфер, якщо, утримуючи натис-

нутою клавішу Alt, набирати десятковий код символу на цифровій клаві-

атурі. У цьому випадку в ah формується нульовий скан-код, а в al зано-

ситься введений код символу ASCII.

Для розширених клавіатур (101/102 і 122 клавіші) необхідно вико-

ристовувати функції 10h або 20h int 16h, тому що більш ранні функції

не підтримують роботу з додатковими клавішами, уведеними до складу

цих клавіатур. При натисканні цих клавіш у регістр al заноситься код

0eh, а в регістр ah – розширений ASCII-код цих клавіш.

На вході ah = 10h, 20h – зчитування символу з очікуванням (для

101/102- і 122-клавішних клавіатур відповідно).

На виході:

– для звичайних клавіш (ah = скан-код BIOS; al = символ ASCII);

– для клавіш і комбінацій з розширеним кодом (ah = розширений

ASCII-код; al = 0);

Page 363: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

363

– для додаткових клавіш (ah = розширений ASCII-код; al = 0eh).

Для введення рядка символів дані функції необхідно використову-

вати в циклі.

ПРИКЛАД. Програма вводить 5 символів і зберігає їх у рядку str.

Використовуючи налагоджувач можна досліджувати вміст регістра ах

при натисканні різних клавіш і їхніх комбінацій.

masm

model small

.stack 256

.486

.data

string db 5 dup (0)

len_string = $ - string

adr_string dd string

.code

main:

mov ax, @data

mov ds, ax

mov cx, len_string

les di, adr_string

m1:

mov ah, 010h

int 16h

stosb

loop m1

exit: ; вихід із програми

mov ax,4c00h ; пересилання 4c00h у регістр ax

int 21h ; виклик переривання з номером 21h

end main ; кінець програми з точкою входу main

Перевірка наявності символу (0lh, llh, 21h int 16h)

На вході ah = 0lh – перевірка наявності символу (для 84-клавішної

клавіатури).

На виході:

а) якщо zf = 0, то ah і al містять:

– для звичайних клавіш (ah = скан-код BIOS; al = символ

ASCII);

Page 364: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

364

– для клавіш і комбінацій з розширеним ASCII-кодом (ah = ро-

зширений ASCII-код; al = 0);

в) якщо zf = 1, то буфер порожній.

Функція 0lh одержує інформацію про символ, не видаляючи його з

буфера клавіатури. Виключення складають натискання додаткових кла-

віш на розширених клавіатурах, не сумісних з 83\84-клавішними клавіа-

турами. У процесі перевірки функцією 0lh вони видаляються з буфера.

Тому при роботі з розширеними клавіатурами необхідно використовува-

ти функції llh і 21h.

На вході ah = 11h, 21h – перевірка наявності символу (для 101/102-

і 122-клавішних клавіатур відповідно).

На виході:

а) якщо zf = 0, то ah і al містять:

– для звичайних клавіш (ah = скан-код BIOS; al = символ ASCII);

– для клавіш і комбінацій з розширеним ASCII-кодом (ah = розши-

рений ASCII-код; al = 0);

– для додаткових клавіш (ah = розширений ASCII-код; al = 0eh);

в) якщо zf = 1, то буфер порожній.

Роботу з результатами виконання даної функції логічно починати з

аналізу прапорця zf (командами jz або jnz). Вміст регістра ax аналогіч-

ний вмісту ах у розглянутій вище функції 00h int 16h. Разом з функцією

00h дану функцію можна використовувати в програмах, керування якими

здійснюється з клавіатури.

Одержання стану прапорців клавіатури (02h, 12h, 22h int 16h)

BIOS надає функцію 02h для одержання стану світлових індикато-

рів клавіатури і деяких керуючих клавіш.

На вході ah = 02h – одержати стан прапорців клавіатури (для

84-клавішної клавіатури).

На виході: al = бітове поле, установлені біти якого відповідають

стану таких прапорців:

7 – режим вставки активний;

6 – індикатор CapsLock включений;

5 – індикатор NumLock включений;

Page 365: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

365

4 – індикатор ScrollLock включений;

3 – натиснута клавіша Alt (будь-яка клавіша Alt на 101-102-

клавішній клавіатурі);

2 – натиснута клавіша Ctrl (будь-яка клавіша Ctrl на 101-102-

клавішній клавіатурі);

1 – натиснута ліва клавіша Shift;

0 – натиснута права клавіша Shift.

Підтримка розширених клавіатур здійснюється функціями 12h і

22h BIOS.

На вході ah = 12h, 22h – одержати стан прапорців клавіатури (для

101/102- і 122-клавішних клавіатур).

На виході:

а) al = перше бітове поле, біти якого відповідають стану прапорців,

що повертаються в регістр al функцією 02h;

в) ah = друге бітове поле, біти якого відповідають наступному стану

прапорців:

7 – натиснута клавіша SysReq (SysRq);

6 – натиснута клавіша CapsLock;

5 – натиснута клавіша NumLock;

4 – натиснута клавіша Scrolllock;

3 – натиснута права клавіша Alt;

2 – натиснута права клавіша Ctrl;

1 – натиснута ліва клавіша Alt;

0 – натиснута ліва клавіша Ctrl.

Крім того, стан даних прапорців можна прочитати з ОП за адресами

0040h:0017h (al) і 0040h:0018h (ah).

ПРИКЛАД. Програма перевіряє наявність символу в буфері клавіа-

тури:

masm

model small

.stack 256

.486

.code

main: mov ax, @data

mov ds, ax

m1: mov ah, 01h ;перевіряємо наявність символу

int 16h

Page 366: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

366

jz exit ;буфер порожній

mov ah, 00h ;зчитуємо символ

int 16h

mov dl, al ;виводимо його засобами MS-DOS

mov ah, 02h

int 21h

jmp m1

exit: mov ax, 4c00h

іnt 21h

end main

Запис символу в буфер клавіатури (05h int 16h)

На вході:

а) ah = 05h – запис символу в буфер клавіатури:

– ch = скан-код;

– cl = символ ASCII.

На виході: al = стан:

– 00h – успішний запис;

– 0lh – помилка (буфер клавіатури заповнений).

За допомогою цієї функції можна здійснювати підтримку програм,

що очікують уведення з клавіатури.

Сам буфер клавіатури організований за принципом кільця, має роз-

мір 16 байт і займає в пам’яті діапазон адрес 0040h:001eh...0040h:003dh.

У комірці 0040h:001ah зберігається адреса початку буфера, а в комірці

0040h:001ch – адреса кінця. Одному символу в буфері відповідає слово,

у якому перший байт – скан-код клавіші, а другий – символ ASCII. Дос-

ліджувати дану функцію можна з використанням операції з’єднання ( | )

MS-DOS.

ПРИКЛАД.

1. Програма p1.asm заносіть символи в буфер клавіатури:

masm

model small

.stack 256

.486

.data

str db “Буфер клавіатури”,0

.code

Page 367: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

367

main:

mov ax, @data

mov ds, ax

lea di, str ; адреса рядка заноситься в регістр-приймач

xor cx, cx

m1: mov ah, 05h

mov cl, byte ptr [di]

jcxz exit

int 16h

inc di

jmp m1

exit: mov ax, 4c00h

int 21h

end main

2. Програма p2.asm перевіряє наявність символу в буфері клавіату-

ри: masm model small .stack 256 .486 .code main:

mov ax, @data mov ds, ax m1: mov ah, 01h ; перевіряємо наявність символу int 16h jz exit ; буфер порожній

mov ah, 00h ; витягаємо символ int 16h mov dl, al ; виводимо його засобами MS-DOS mov ah, 02h int 21h jmp m1 exit: mov ax, 4c00h int 21h end main

Розглянути результат можливо, з’єднавши файли p1.exe | p2.exe > p.txt. У файлі p.txt буде рядок str.

Page 368: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

368

12.1.1.2. Функції BIOS для роботи з екраном (переривання 10h)

Робота з екраном засобами BIOS здійснюється за допомогою набо-

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

Установка відеорежиму (00h int 10h)

Будь-який адаптер монітора підтримує кілька текстових і графічних

режимів. Переключення між цими режимами здійснюється за допомо-гою функції 00h int 10h.

На вході ah = 00h – установити відеорежим: – al = номер відеорежиму; – якщо біт 7 частини регістра al = 0, то екран очищається; – якщо al.7 = 1 – вміст екрана не змінюється. Номерів відеорежимів багато, нумерація режимів з високим розді-

ленням (SVGA) залежить від виробника відеоадаптера. При необхідності інформацію про нумерацію відеорежимів можна одержати з відповідних джерел.

Установка позиції курсора (02h int 10h)

Функція 02h дозволяє змінити позицію курсора і зробити її почат-

ковою для наступного виведення. Серед функцій MS-DOS немає подіб-ної функції, і функцію 02h int 10h BIOS можна використовувати в комбі-нації з функціями MS-DOS для організації форматованого виведення на екран.

На вході ah = 02h – установити позицію курсора: – bh = номер відеосторінки (залежить від використовуваного відео-

режиму); – dh = рядок (00h – верх); – dl = стовпчик (00h – ліва).

Одержання позиції курсора (03h int 10h) Функція 03h дозволяє одержати поточну позицію курсора. Анало-

гічно сказаному вище, серед функцій MS-DOS немає подібної функції і функцію 03h int 10h BIOS також можна використовувати в комбінації з функціями MS-DOS.

Page 369: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

369

На вході:

- ah = 03h — одержати позицію курсора;

- bh = номер відеосторінки (залежить від використовуваного ві-

деорежиму).

На виході:

- dh = рядок поточної позиції курсора (00h – верх);

- dl = стовпчик поточної позиції (00h – ліва);

- ch = номер початкового рядка курсора;

- cl = номер останнього рядка курсора.

Запис символу і його атрибута у відеопам’ять (09h int 10h)

Функція 09h призначена для запису ASCII-коду символу і його ат-

рибута безпосередньо у відеопам’ять, причому зробити це можна з кіль-

кістю повторень, заданих у регістрі сх.

На вході ah = 09h – запис символу і його атрибута в поточну пози-

цію курсора:

– bh = номер відеосторінки;

– al = ASCII-код символу;

– bl = байт-атрибут;

– cx = кількість повторень.

Для виведення одного символу вміст регістра cx має дорівнювати 1.

У текстовому режимі для cx > 1 виведення здійснюється до кінця поточ-

ного рядка, після чого переходять на інший рядок.

Кодування байта-атрибута в цій та іншій функціях здійснюється

відповідно до таблиць 12.2 і 12.3.

Таблиця 12.2

Кодування байта-атрибута

Номера бітів Значення

7 Миготливий символ

6 – 4 Колір фону

3 Символ яскравого кольору

2 – 0 Колір символу

Page 370: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

370

Таблиця 12.3

Кодування кольорів

Біти Колір Яскравий колір

000b Чорний Темно-сірий

001b Синій Світло-синій

010b Зелений Світло-зелений

011b Блакитний Світло-блакитний

100b Червоний Світло-червоний

101b Пурпурний Світло-пурпурний

110b Коричневий Жовтий

111b Світло-сірий Білий

Зчитування символу і його атрибута з відеопам’яті (08h int l0h)

У пам’яті відеоадаптера кожен символ поданий двома байтами, що

містять ASCII-код символу і його байт-атрибут. Функція 08h BIOS до-

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

пам’яті.

На вході:

– ah = 08h – зчитування символу і його атрибута в поточній позиції

курсора;

– bh = номер відеосторінки.

На виході:

– al = ASCII-код символу;

– ah = байт-атрибут.

ПРИКЛАД. Програма встановлює курсор у задану позицію.

masm

model small

.stack 256

.486

.code

main:

xor bh, bh

mov dh, 10

mov dl, 10

mov ah, 02h

int 10h ; установили позицію курсора (10,10)

Page 371: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

371

mov al, “a” ; записуємо символ і атрибут у відеопам’ять

mov bl, 10001100b ; атрибут – яскраво-червоний миготливий

mov cx, 5 ; повторити 5 разів

mov ah, 09h

int 10h

mov ah, 08h ; прочитаємо символ з поточної позиції відеопам’яті

int 10h

xor bh, bh ; з’ясуємо поточну позицію курсора

mov ah, 03h

int 10h ; установили позицію курсора (10,10)

exit: mov ax, 4c00h

int 21h

end main

Поточна позиція курсора після виконання функцій 08h і 09h зали-

шилася незмінною. Звідси випливає висновок про те, що при викорис-

танні цих функцій необхідно також піклуватися і про рух курсора функ-

цією 02h. BIOS надає функцію 0eh, що виводить символ у режимі теле-

тайпа, яка припускає автоматичне коректування поточної позиції курсо-

ра після виведення символу.

Запис символу у відеопам’ять (0ah int 10h)

Функція 0ah призначена для запису ASCII-коду символу з поточ-

ним значенням атрибута в даній позиції безпосередньо у відеопам’ять,

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

На вході:

– ah =0ah – запис символу в поточну позицію курсора;

– bh = номер відеосторінки;

– al = ASCII-код символу;

– cx = кількість повторень.

Аналогічно до функції 09h поточна позиція курсора не змінюється.

Запис символу в режимі телетайпа (0eh int 10h)

Функція 0eh виводить символ у поточну позицію курсора з автома-

тичним її зсувом (на відміну від функцій 09h і 0ah).

Page 372: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

372

На вході: – ah = 0eh – запис символу в поточну позицію курсора; – bh = номер відеосторінки; – al = ASCII-код символу; – cx = кількість повторень. Запис символу в останню позицію рядка автоматично переводить

курсор у першу позицію наступного рядка.

Виведення рядка (13h int 10h) Функція 13h з’явилася в BIOS комп’ютерів архітектури AT. На вході: 1) ah = 13h – виведення рядка; 2) al = режим запису: – біт 0 – після виведення курсора у кінець рядка; – біт 1 – кожен символ у рядку поданий двома байтами: байтом з

ASCII-кодом і байтом-атрибутом; – біт 2..7 – резерв; 3) bh = номер відеосторінки; 4) bl = байт-атрибут, якщо рядок містить тільки символи (al.1 = 0); 5) cx = кількість символів у рядку; 6) dh, dl = рядок і стовпець початку виведення рядка; 7) es:bp – адреса в пам’яті початку рядка. Уміст рядка для виведення може бути двох типів: з байтом-

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

Багато функцій BIOS працюють безпосередньо з відеопам’яттю. Че-рез те, що для відеопам’яті виділяється визначений діапазон адрес (для текстового режиму – це 0b800h:0000h), доступ до неї можна робити зви-чайними командами роботи з пам’яттю МП, у тому числі і ланцюжкови-ми.

Переміщення у вікні “нагору” (06h int 10h)

Функція 06h дозволяє визначити на екрані вікно, у якому можливо

прокрутити визначену кількість рядків нагору. При такому прокручуван-ні верхні рядки зникають і знизу додаються порожні.

На вході:

– ah = 06h – переміщення рядків у вікні “нагору”;

Page 373: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

373

– al = число рядків для заповнення знизу;

– bh = атрибут символів (колір) у рядку для заповнення;

– ch і cl = рядок і стовпець верхнього лівого кута вікна;

– dh і dl = рядок і стовпець нижнього правого кута вікна.

Рядки для заповнення знизу мають колір, визначений у bh. Якщо

вказати al = 0, то вікно очиститься і заповниться рядками з кольором,

заданим байтом-атрибутом у bh.

ПРИКЛАД. Програма виводить кілька рядків на екран, після чого

вона визначає вікно на екрані червоного кольору і прокручує його на

кілька рядків “нагору”:

masm

model small

.stack 256

.486

.data

string db “dfsh3453637869шогаерввапв”

len_string = $ - string

adr_string dd string

.code

main:

mov ax, @data

mov ds, ax

xor dx, dx

mov cx, 25

m1:

mov al, 1 ; після виведення – курсор у кінець рядка

xor bh, bh ; номер відеосторінки

mov bl, 7 ; атрибут

push cx

mov cx, len_string ; довжина виведеного рядка

les bp, adr_string ; адреса рядка – в es:bp

mov ah, 13h

int 10h

inc dh ; рядок початку виведення

inc dl ; стовпець початку виведення

pop cx

loop m1

Page 374: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

374

;визначаємо і прокручуємо вікно нагору

mov al, 4 ; 4 рядок

mov bh, 0

mov bh, 01000000b ; червоний фон

mov ch, 5

mov cl, 5

mov dh, 10

mov dl, 30

mov ah, 06h

int 10h

exit: ; вихід із програми

mov ax, 4c00h ; пересилання 4c00h у регістр ax

int 21h ; виклик переривання з номером 21h

end main ; кінець програми з точкою входу main

Функція 06h досить гнучко працює з курсором.

Переміщення у вікні вниз (07h int 10h)

Функція 07h дозволяє визначити на екрані вікно, у якому можливо

прокрутити визначену кількість рядків униз. При такому прокручуванні

нижні рядки зникають і зверху додаються порожні.

На вході:

– ah = 07h – переміщення рядків у вікні вниз;

– al = кількість рядків для заповнення зверху;

– bh = атрибут символів (колір) у рядку для заповнення;

– ch і cl = рядок і стовпець верхнього лівого кута вікна;

– dh і dl = рядок і стовпець нижнього правого кута вікна.

Рядки для заповнення зверху мають колір, визначений у bh. Якщо

вказати al = 0, то вікно очиститься і заповниться рядками з кольором,

заданим у bh. Структура байта атрибута аналогічна описаній вище.

12.1.2. Функції MS-DOS для роботи з консоллю (переривання 21h) Функції MS-DOS для роботи з консоллю зосереджені в оброблювачі

переривання int 21h. Вони являють собою набір засобів роботи з консо-

Page 375: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

375

ллю, що займає проміжне положення між програмами користувача і за-собами BIOS. Для досягнення більшої ефективності деякі з функцій BIOS можна комбінувати з функціями MS-DOS. Наприклад, при роботі з курсором. Серед функцій MS-DOS подібні засоби відсутні.

12.1.2.1. Функції MS-DOS для введення даних із клавіатури

Для введення даних із клавіатури можна використовувати два види

функцій: універсальну функцію 3fh (введенння з файлу) і групу спеціалі-зованих функцій MS-DOS введення з клавіатури.

Розглянемо другу групу функцій, в яку входить сім функцій, що від-різняються одна від одної такими характеристиками:

– очікуванням введення при відсутності символу в буфері або кла-віатури (перевіркою буфера на наявність символів для введення);

– кількістю символів, що вводяться; – наявністю луни при введенні, тобто дублюванням символу, що

вводиться з клавіатури, на екрані; – чутливістю до натискання клавіш Ctrl+C (код 03h).

Зчитування з луною символу з клавіатури (0lh int 21h) Функція 0lh дозволяє ввести один символ з клавіатури. Якщо сим-

волу немає, то функція очікує його введення. Символ, що вводиться, відображається на екрані (луна).

На вході ah = 0lh – читання символу з луною. На виході al = ASCII-код символу або 0. На виході функція поміщає в al ASCII-код символу або 0. Наявність

нуля в al говорить про те, що в буфері клавіатури знаходиться розшире-ний ASCII-код і необхідно повторити виклик функції для того, щоб про-читати його другий байт. Також функція 0lh перевіряє наявність у буфері символів натискання комбінації Ctrl+C (Ctrl+Break), при виявленні яких здійснюється виклик переривання int 23h.

Для введення декількох символів дану функцію необхідно викорис-товувати в циклі.

ПРИКЛАД: Програма вводить кілька символів функцією 01h:

masm

model small

.stack 256

Page 376: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

376

.486

.data

string db 5 dup (0)

len_string = $ - string

adr_string dd string

.code

main:

mov ax, @data

mov ds, ax

mov cx, len_string

les di, adr_string

m1:

mov ah, 01h

int 21h

cmp al, 0 ;розширений код?

jne m2

;обробляємо розширений код

;…

jmp m3

m2:

stosb ;формуємо рядок символів

m3:

loop m1

exit: ;вихід з програми

mov ax, 4c00h ;пересилання 4c00h у регістр ax

int 21h ;виклик переривання з номером 21h

end main ;кінець програми з точкою входу main

Перевіряючи роботу програми, замість уведення чергового символу

введіть комбінацію Ctrl+C і подивіться реакцію програми.

Пряме введення з луною символу з клавіатури (06h int 21h)

Функція 06h також дозволяє ввести один символ з клавіатури. Але

на відміну від функції 0lh вона не очікує введення при відсутності сим-

волу в буфері. Символ, що вводиться, відображається на екрані (луна).

На вході:

Page 377: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

377

– ah = 06h – читання символу з луною без очікування;

– dl = 0ffh – ознака того, що функція 06h використовується для вве-

дення;

– якщо dl = 0ffh, то функція використовується для виведення сим-

волу.

На виході:

– якщо zf = 0, то al = ASCII-код символу;

– якщо zf = 1, то символу в буфері немає.

Результати роботи цієї функції необхідно оцінювати, насамперед, за

значенням прапорця zf. Якщо zf = 0, то функція помістила в al ASCII-код

символу або 0. Наявність нуля в al говорить про те, що в буфері клавіа-

тури знаходиться розширений ASCII-код і необхідно повторити виклик

функцій, щоб прочитати його другий байт. Функція 06h не перевіряє

наявність у буфері символів натискання комбінації Ctrl+C (Ctrl+Break).

Зчитування без луни символу з клавіатури (07h int 21h)

Функція 07h аналогічна функції 0lh, за винятком того, що вводить

символ із клавіатури без чекання його введення, без луни і без перевірки

натискання комбінації Crl+C (Ctrl+Break).

На вході ah = 07h – читання символу без луни.

На виході al = ASCII-код символу або 0.

Наявність нуля в al говорить про те, що в буфері клавіатури знахо-

диться розширений ASCII-код і необхідно повторити виклик функції для

того, щоб прочитати його другий байт.

Зчитування без луни символу з клавіатури (08h int 21h)

Функція 08h аналогічна функції 0lh, за винятком того, що вводить

символ із клавіатури без відображення його на екрані (без луни).

На вході ah = 08h – зчитування символу без луни.

На виході al = ASCII-код символу або 0.

Page 378: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

378

Наявність нуля в al говорить про те, що в буфері клавіатури знахо-

диться розширений ASCII-код і необхідно повторити виклик функції для

того, щоб прочитати його другий байт. Функція робить перевірку натис-

кання комбінації Ctrl+C (Ctrl+Break), при наявності якого викликається

переривання int 23h.

Введення рядка символів із клавіатури (0ah int 21h)

Функція 0ah уводить рядок символів у буфер пам’яті спеціального

формату. Якщо символів у буфері клавіатури немає, то функція очікує

їхнього введення. Кінець введення – натискання клавіші Enter (0dh).

Формат буфера:

– перший байт буфера містить кількість символів для введення з

урахуванням символу 0dh, що завершує процес введення;

– другий байт містить реальну кількість введених символів, але вже

без урахування завершального символу 0dh;

– починаючи з третього байта міститься рядок уведених символів із

завершальним символом 0dh; максимальна довжина рядка –

254 символи.

На вході:

– ah = 0ah – введення рядка в буфер (до 254 символів);

– ds:dx – адреса буфера, перший байт якого повинний містити кіль-

кість символів для введення.

На виході: введено рядок, починаючи з третього байта буфера за

адресою в ds:dx; довжина рядка – в другому байті буфера.

Перед викликом функції 0ah у перший байт буфера необхідно помі-

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

нює нулю, то виклик функції ігнорується і програма продовжує вико-

нання без очікування введення рядка. Функція здійснює перевірку нати-

скання комбінації Ctrl+C (Ctrl+Break), при наявності якого викликається

переривання int 23h. Рядок, що вводиться, відображається на екрані.

Буфер введення для даної функції краще оформляти у вигляді структури.

ПРИКЛАД. Програма вводить рядок символів, але в буфері розмі-

щує тільки 10 символів. Кінець введення – натискання клавіші Enter.

masm

Page 379: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

379

model small

.stack 256

.486

buf_0ah struc

len_buf db 11 ;довжина buf_0ah

len_in db 0 ;дійсна довжина введеного слова (без урахування 0dh)

buf_in db 11 dup (20h) ;буфер для введення (з обліком 0dh)

ends

.data

buf buf_0ah <>

adr_buf dd buf

.code

main:

mov ax, @data

mov ds, ax

;уводимо 10 символів із клавіатури – одержання покажчика у вигляді

;сегментного складового зі зсувом, у dx – повна адреса структури

lds dx, adr_buf

mov ah, 0ah

int 21h

exit:

mov ax, 4c00h

int 21h

end main

Одержання стану клавіатури (0bh int 21h)

Функція 0bh перевіряє наявність у буфері символу для введення.

На вході ah = 0bh – перевірка стану клавіатури.

На виході:

– al = 0ffh – буфер клавіатури містить символ для введення;

– al = 0 – буфер клавіатури порожній.

Дана функція формує тільки логічний результат – є присутнім сим-

вол у буфері або буфер порожній, тому виклик функції 0bh необхідно

комбінувати з однією з функцій витягу символу з буфера введення. Ви-

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

ється з клавіатури, – типу командного МП. У процесі своєї роботи вони

Page 380: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

380

постійно очікують вводу користувачем керуючих команд, у зв’язку, з

чим періодично перевіряють вхідний буфер.

Функція робить перевірку натискання комбінації Ctrl+C

(Ctrl+Break), при наявності якого викликається переривання int 23h.

Введення з клавіатури з попереднім очищенням буфера

(0ch int 21h)

Функція 0ch виконує введення, попередньо очищаючи буфер клаві-

атури. Це зручно для запобігання читання з буфера символів, які там

залишилися, можливо, уведених помилково або випадково. Функція га-

рантує, що програма одержить саме ті дані, які ввів оператор. Функція

0ch виконує тільки очищення буфера, введення символу здійснює одна з

функції, номер якої вказується в al при виклику цієї функції.

На вході:

– ah = 0ch – введення з клавіатури з попереднім очищенням;

– al = номер функції (0lh, 06h, 07h, 08h, 0ah).

На виході – уміст функції, зазначеної в al при виклику функції.

Функція робить перевірку натискання комбінації Ctrl+C

(Ctrl+Break), при наявності якого викликається переривання int 23h.

12.1.2.2. Функції MS-DOS для виведення даних на екран

Для виведення даних на екран можна використовувати два види фу-

нкцій: універсальну функцію 40h (виведення у файл) і групу спеціалізо-

ваних функцій MS-DOS виведення на екран.

Розглянемо функції MS-DOS для виведення символів на екран. У

групу входять три функції.

Виведення символу на екран (02h int 21h)

Функція 02h дозволяє вивести один символ на екран.

На вході:

– ah = 02h – виведення символу;

– dl = символ для виведення.

Page 381: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

381

Функція 02h перевіряє наявність у клавіатурному буфері символів

натискання комбінації Ctrl+C (Ctrl+Break), при виявленні яких здійсню-

ється виклик переривання int 23h. У процесі виведення функція реагує на

керуючі символи, такі, як 0dh (повернення каретки), 0ah (переклад ряд-

ка), 08h (курсор назад на один символ), 07h (звуковий сигнал) і т.д.

Для того щоб вивести рядок, необхідно використовувати цикл.

ПРИКЛАД. Програма посимвольного виведення рядка функцією

02h:

masm

model small

.stack 256

.486

.data

string db “Рядок для виведення функцією 02h”

len_string = $ - string

.code

main:

mov ax, @data

mov ds, ax

mov cx, len_string

;адреса рядка, одержання ефективної адреси

lea si, string

mov ah, 02h

m1:

mov dl, byte ptr [si]

int 21h

inc si

loop m1

exit:

mov ax, 4c00h

int 21h

end main

Page 382: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

382

Пряме виведення символу на екран (06h int 21h)

Функція 06h виводить один символ на екран. Ця функція універса-

льна, тому що використовується і для введення і для виведення символу.

На вході:

– ah = 06h – виведення символу на екран;

– dl = символ для виведення (за винятком 0ffh).

Функція 06h не перевіряє наявність у буфері символів натискання

комбінації Ctrl+C (Ctrl+Break). Порядок використання даної функції

аналогічний порядку використання функції 02h.

Виведення рядка на екран (09h int 21h)

Функція 09h виводить рядок символів на екран. Рядок повинний

обов’язково закінчуватися символом $. Дану функцію зручно використо-

вувати для виведення на екран різних діагностичних повідомлень. Якщо

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

намічно, то краще використовувати або згадану вище функцію 40h, або

виводити їх у циклі, тіло якого містить одну з функцій 02h або 06h.

На вході:

– ah = 09h – виведення рядка на екран;

– ds:dx – адреса рядка для виведення з завершальним символом $.

Функція 09h перевіряє наявність у клавіатурному буфері символів

натискання комбінації Ctrl+C (Ctrl+Break), при виявленні яких здійсню-

ється виклик переривання int 23h. У процесі виведення функція реагує на

керуючі символи, такі, як 0dh (повернення каретки), 0ah (переклад ряд-

ка), 08h (курсор назад на один символ), 07h (звуковий сигнал) і т.д.

ПРИКЛАД. Програма виводить рядки на екран функцією 09h:

masm

model small

.stack 256

.486

.data

Page 383: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

383

string db “Рядок для виведення функції 09h $”

adr_string dd string

.code

main:

mov ax, @data

mov ds, ax

;виводимо рядок string на екран

lds dx, adr_string ;адреса рядка в ds:dx

mov ah, 09h

int 21h

exit: ;вихід із програми

mov ax, 4c00h ;пересилання 4c00h у регістр ax

int 21h ;виклик переривання з номером 21h

end main ;кінець програми з точкою входу main

Запитання для самоперевірки

1. Що розуміється під консоллю в середовищі MS-DOS?

2. Що являє собою драйвер?

3. У чому полягає відмінність функцій BIOS і MS-DOS для ро-

боти з консоллю?

12.2. Робота з консоллю в середовищі Windows

12.2.1. Асемблер у середовищі Windows

Програмування на асемблері під Win32 (так будемо коротко визна-

чати платформу ОС Windows, що працює з 32-розрядними додатками)

сприймається дуже не однозначно. Вважається, що написання додатків

занадто складне для застосування асемблеру.

На відміну від програмування під MS-DOS, де програми, написані

на мовах високого рівня, були схожі на свої аналоги, написані на асемб-

лері, додатки під Win32 мають більше особливостей. У першу чергу, це

пов’язано з тим, що звертання до сервісу ОС у Windows здійснюється за

допомогою виклику функцій, а не переривань, що було характерно для

MS-DOS. Тут немає передачі параметрів у регістрах при звертанні до

сервісних функцій і, відповідно, немає і безлічі результуючих значень,

що повертаються в регістри загального призначення і регістр прапорців.

Page 384: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

384

Отже, простіше запам’ятати і використовувати протоколи виклику фун-

кцій системного сервісу. З іншого боку, у Win32 не можна безпосередньо

працювати з апаратним рівнем, як програми для MS-DOS. Узагалі напи-

сання програм під Win32 стало значно простішим, і це обумовлено таки-

ми факторами:

– відсутністю startup коду, характерного для додатків і динамічних

бібліотек написаних під Windows 3.x;

– гнучкістю системи адресації до пам’яті;

– можливістю звертатися до пам’яті через будь-який регістр загаль-

ного призначення;

– відсутністю сегментних регістрів;

– наявністю великих обсягів віртуальної пам’яті;

– наявністю розвинутого сервісу ОС, що полегшує розробку додат-

ків;

– розмаїттям засобів створення інтерфейсу з користувачем (діалоги,

меню і т.п.).

Сучасний асемблер, наприклад, TASM 5.0 фірми Borland

International Inc. удосконалив засоби, що раніше були характерні тільки

для мов високого рівня. До таких засобів можна віднести МВ виклику

процедур, можливість уведення шаблонів процедур (опис прототипів) і

навіть об’єктно-орієнтовані розширення. Однак асемблер зберіг і такий

прекрасний інструмент, як МВ, що вводяться користувачем, повноцінно-

го аналога яких немає в жодній мові високого рівня.

Асемблер досить ефективно може бути використаний для створення

Windows-додатків з таких причин:

– асемблер дозволяє програмісту цілком контролювати створюва-

ний їм програмний код і оптимізувати його на свій розсуд;

– компілятори мов високого рівня розташовують у завантажуваль-

ний модуль програми надлишкову інформацію. Еквівалентні модулі, що

виконуються, вихідний текст яких написаний мовою асемблеру, мають

розмір у кілька разів менший;

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

апаратних ресурсів комп’ютера;

– додаток, написаний на асемблері, як правило, швидше завантажу-

ється в ОП комп’ютера;

– додаток, написаний мовою асемблеру, має, як правило, більш ви-

соку швидкість роботи і реакцію відповіді на дії користувача.

Page 385: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

385

Не можна забувати про те, що існує безліч прикладних задач, що

очікують своєї черги на комп’ютерну реалізацію. Не усі ці задачі вима-

гають застосування особливих засобів розробки. Багато прикладних за-

дач можуть бути виконані мовою асемблеру, не втрачаючи своїх особли-

востей, наприклад, віконних додатків Windows.

ОС MS-DOS і Windows підтримують дві зовсім різні ідеології про-

грамування. У чому різниця? Програма MS-DOS після свого запуску

повинна бути постійно активною. Якщо їй щось потрібно, наприклад,

одержати чергову порцію даних із пристрою введення-виведення, то во-

на сама повинна виконувати відповідні запити до ОС. При цьому про-

грама MS-DOS працює за визначеним алгоритмом, вона завжди знає, що

і коли їй слід робити.

У Windows усе навпаки. Програма пасивна. Після запуску вона че-

кає, коли їй приділять увагу ОС. ОС робить це посилкою спеціально

оформлених груп даних, називаних повідомленнями.

Повідомлення можуть бути різного типу; вони функціонують у сис-

темі досить хаотично, і додаток не знає, якого типу повідомлення надій-

де наступним. Звідси випливає, що логіка побудови Windows-додатка

повинна забезпечувати коректну і передбачувану роботу при надхо-

дженні повідомлень будь-якого типу. У чомусь можна провести анало-

гію між механізмом повідомлень Windows і механізмом переривань в

архітектурі МП Intel. Для забезпечення нормального функціонування

своєї програми програміст повинний вміти ефективно використовувати

функції інтерфейсу прикладного програмування (API, Application

Program Interface) ОС.

Windows підтримує два типи додатків:

– віконний додаток, який будується на базі спеціального набору

функцій API, що складають графічний інтерфейс користувача (GUI,

Graphic User Interface). Віконний додаток являє собою програму, за

допомогою якої здійснюється виведення на екран у графічному вигляді.

Першим результатом роботи віконного додатка є відображення на екрані

спеціального об’єкта – вікна. Після того як вікно відображене на екрані,

уся робота додатка спрямована на те, щоб підтримувати його в актуаль-

ному стані;

– невіконний додаток (консольний), який являє собою програму,

що працює в текстовому режимі. Робота консольного додатка нагадує

роботу програми MS-DOS. Але це лише зовнішнє враження. Консольний

додаток забезпечується спеціальними функціями Windows.

Page 386: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

386

12.2.2. Два підходи до забезпечення роботи з консоллю

в середовищі Win32

Як відомо, Windows підтримує роботу двох типів додатків – вікон-

них, які повною мірою використовують всі достоїнства графічного інте-

рфейсу, і консольних, працюючих винятково в текстовому режимі. Тому

не слід плутати поняття “консолі”, використовуване вище, з поняттям

“консольний додаток” Windows. У попередньому матеріалі під “консо-

ллю” малися на увазі засоби для введення інформації з клавіатури і ви-

ведення її на екран. Далі під терміном “консоль” ми будемо мати на ува-

зі або сам консольний додаток, або його видиму частину – вікно консо-

льного додатка.

Розглянемо порядок введення-виведення даних у консольний дода-

ток для Windows, написаний на асемблері. Це дуже актуально, оскільки

при програмуванні на асемблері необхідність написання консольного

додатка виникає більш часто, ніж віконного.

Системним програмістам потрібні ще більш зручні засоби для робо-

ти з текстовою інформацією. ОС Windows забезпечує вбудовану підтри-

мку консолей, що є інтерфейсами введення-виведення для додатків, які

працюють у текстовому режимі.

Консоль складається з одного вхідного і декількох екранних буфе-

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

мацію щодо окремої вхідної події консолі. Екранний буфер – двовимі-

рний масив, що містить символи, виведені у вікно консолі, і дані про

їхній колір.

Черга вхідного буфера містить інформацію про такі події:

натискання і відпускання клавіш;

маніпуляція мишкою – рух, натискання-відпускання кнопок;

зміна розміру активного екранного буфера, стан прокручування.

Для підтримки роботи консольних додатків API Win32 містить

більш сорока функцій, призначених для інтеграції в середовище

Windows програм, що працюють у текстовому режимі. Дані функції за-

безпечують два рівні доступу до консолі – високий і низький.

Page 387: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

387

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

зчитувати дані, отримані при введенні з клавіатури і збережені у вхідно-

му буфері консолі. Консольні функції виведення високого рівня дозво-

ляють додатку записати дані в пристрої стандартного виведення або по-

милки для того, щоб відобразити цей текст в екранному буфері консолі.

Функції високого рівня також підтримують перепризначення стандарт-

них дескрипторів введення-виведення керування режимами роботи кон-

солі.

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

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

відпускання кнопок мишки та про маніпуляції користувача з вікном кон-

солі, а також здійснити більший контроль над виведенням даних на ек-

ран.

Таким чином, API Win32 надає два різних підходи для забезпечен-

ня введення-виведення з консоллю; вибір потрібного залежить від гнуч-

кості і повноти контролю, якими хоче володіти додаток для забезпечен-

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

тоту процесу введення-виведення шляхом використання стандартних

дескрипторів введення-виведення, але при цьому не можливий доступ до

вхідного й екранного буферів консолі. Функції низького рівня вимага-

ють врахування більшої кількості деталей і обсягу коду, але це компен-

сується більшою гнучкістю.

Високорівневе і низькорівневе консольне введення-виведення не є

взаємовиключними, і додаток може використовувати будь-яку

комбінацію цих функцій.

З кожною консоллю пов’язані дві кодові таблиці – одна для введен-

ня, а друга – для виведення. Консоль використовує вхідну кодову таб-

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

чення. Аналогічним образом використовується кодова таблиця виве-

дення – для трансляції символьних значень, сформованих різними фун-

кціями виведення, у символ, відображуваний у вікні консолі. Для роботи

з кодовими таблицями додаток може використовувати пари – функції

SetConsoleCP і GetConsoleCP для вхідних кодових таблиць і функції

SetConsoleOutputCP і GetConsoleOutputCP для вихідних кодових таб-

лиць.

Page 388: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

388

Ідентифікатори кодових таблиць зберігаються в системному реєстрі

таким ключем: HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentContro1Set\ \Contro1\\N1s\\CodePage

12.2.3. Програма мінімального консольного додатка

Програма мінімального консольного додатка на асемблері може ма-

ти такий вигляд:

; програма мінімального консольного додатка Windows

.486

.model flat,STDCALL ; модель пам’яті flat,

; STDCALL – передача параметрів, як і у мові Сі (праворуч-ліворуч),

; викликувана процедура чистить за собою стек

%NOINCL ; заборонити виведення тексту файлів

include WindowCon.inc

; Оголошення зовнішніми використовуваних у даній програмі

; функцій Win32 (ASCII):

extrn AllocConsole:PROC

extrn SetConsoleTitleA:PROC

extrn ExitProcess:PROC

.data

TitleText db ‘Мінімальний консольний додаток Win32’,0

.code

start proc near ; точка входу в програму:

call AllocConsole ; запит консолі

; перевірити успіх запиту консолі

test eax, eax

jz exit : невдача

; виведемо заголовок вікна консолі SetConsoleTitle:

push offset TitleText

call SetConsoleTitle

; перевірити успіх висновку заголовка

Page 389: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

389

test eax, eax

jz exit ; невдача : ...

exit: ; вихід з додатка ; готуємо виклик VOID ExitProcess(UINT uExitCode) push 0 call ExitProcess start endp end start

Першою функцією консольного додатка повинна бути функція за-питу консолі АllocConsole.

BOOL AllocConsole (VOID); Для виклику функції АllocConsolе не потрібні ніякі параметри. У ра-

зі успіху функція АllocConsolе повертає ненульове значення, при невдачі – нуль. Виділена консоль являє собою типове для Windows вікно. Процес у конкретний момент часу може використовувати одну консоль. Якщо йому потрібно запустити ще одну консоль, то колишня повинна бути закрита або звільнена за допомогою функції FreeConsolе.

BOOL FreeConsole (VOID);

У випадку успіху функція FreeConsolе повертає ненульове значення,

при невдачі – нуль. При завершенні процесу консоль звільняється автоматично. У на-

шому випадку використаний саме цей варіант закриття консолі – функ-цією ExitProcess:

VOID ExitProcess (UINT uExitCode);

Функції ExitProcess передається код завершення процесу і всіх лан-

цюжків, що завершуються у цьому процесі. Проаналізувати цей код мо-жна за допомогою функцій GetExitCodeProcess і GetExitCodeThread. У загальному випадку в різних ланцюгах коду може бути кілька точок ви-ходу з викликом ExitProcess. Задаючи різні значення коду завершення, можна в такий спосіб ідентифікувати причину завершення процесу.

Вікно консолі може мати заголовок, для відображення якого приз-начена функція SetConsoleTitle:

Page 390: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

390

BOOL SetConso1eTit1e (LPCTSTR lpConsoleTitle); Функція SetConsoleTitle має один параметр – указівник рядка із за-

головком консолі, що закінчується нулем.

Запитання для самоперевірки 1. Які типи додатків підтримує середовище Windows? 2. Що розуміється під консоллю в середовищі Windows? 3. З чого складається консоль? 4. Які підходи використовуються для забезпечення введення-

виведення в середовищі Windows?

12.3. Високорівневе консольне введення-виведення

12.3.1. Функції API для забезпечення високорівневого консольного введення-виведення

Для високорівневого введення-виведення додатка найбільш зручно

використовувати функції консольного введення-виведення ReadConsole і WriteConsole. Ці функції забезпечують непрямий доступ до вхідного й екранного буферів. Фізично ці функції фільтрують записи вхідного бу-фера консолі (як потік символів), ігноруючи всі інші записи з розшире-ною інформацією про мишку, клавіатуру і зміну розмірів вікна консолі. Відфільтрований потік символів відображається у вікні консолі, почи-наючи з поточної позиції курсора.

Основні особливості пари функцій ReadConsole та WriteConsole: – консольні функції ReadConsole та WriteConsole підтримують на-

бори символів Unicode і ANSI; – ці функції можна використовувати тільки з трьома дескрипторами

стандартного введення-виведення. Функції високорівневого введення-виведення забезпечують простий

спосіб обміну (зчитування-запису) потоків символів з консоллю. Операція зчитування високого рівня реалізується функцією

ReadConsole, що одержує вхідні символи з буфера введення консолі і зберігає їх у зазначеному буфері.

BOOL ReadConso1e (HANDLE hConsoleInput, LPVOID lpBuffer, DWORD nNumberOfCharsToRead, LPDWORD lpNumberOfCharsRead,

Page 391: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

391

LPVOID lpReserved); Параметри цієї функції означають таке: – hConsoleInput – дескриптор вхідного потоку консолі; – lpBuffer – указівник рядка, у який будуть записані символи, що

вводяться; – nNumberOfCharsToRead – розмір буфера, зазначеного lpBuffer; – lpNumberOfCharsRead – кількість дійсно введених символів; – lpReserved – цей параметр не використовується, тому він повин-

ний задаватися як NULL. Операція запису високого рівня реалізується функцією

WriteConsole, що зчитує символи з зазначеного буфера і записує їх в екранний буфер, починаючи з поточної позиції курсора і просуваючи її відповідно до запису символів.

BOOL WriteConso1e (HANDLE hConsoleOutput, CONST VOID *1pBuffer, DWORD nNumberOfCharsToWrite, LPOWORD lpNumberOfCharsWritten, LPVOID lpReserved); Параметри цієї функції означають таке: – hConsoleOutput – дескриптор вихідного потоку консолі; – 1pBuffer – указівник виведеного рядка; – nNumberOfCharsToWrite – розмір буфера, зазначеного 1pBuffer; – 1pNumberOfCharsWritten – кількість дійсно виведених символів; – lpReserved – цей параметр не використовується, тому повинний

задаватися як NULL. Для своєї роботи ці і деякі інші консольні функції вимагають одер-

жання стандартних дескрипторів введення-виведення. Значення цих де-скрипторів надаються параметрам hConsoleInput і hConsoleOutput. За умовчанням стандартний дескриптор уведення зв’язаний з клавіатурою, стандартний дескриптор виведення – з екраном. Одержати стандартний дескриптор введення-виведення можна за допомогою функції GetStdHandlе:

HANDLE GetStdHandle (DWORD nStdHandle); На вхід функції GetStdHandlе повинне бути подано одне з таких

значень: – STD_INPUT_HANDLE = -10 – дескриптор стандартного вхідного

потоку;

Page 392: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

392

– STD_OUTPUT_HANDLE = -11 – дескриптор стандартного вихід-ного потоку;

– STD_ERROR_HANDLE = -12 – дескриптор стандартного потоку помилок.

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

Додаток може змінювати такі властивості високорівневого консоль-ного введення-виведення:

– луна-контроль символів, що вводяться на екран з активного ек-ранного буфера;

– введення рядка, закінчення операції, зчитування якої відбувається при натисканні клавіші Enter;

– автоматична обробка деяких символів, що вводяться з клавіатури: переведення каретки, натискання клавіш Ctrl+C і т.д.;

– автоматична обробка деяких символів, виведених на екран: пере-ведення рядка і каретки, повернення на один символ і т.д.

Функція SetConsoleCursorPosition призначена для зазначення пози-ції, з якої починається виконання операцій зчитування-запису у вікно консолі:

BOOL SetConso1eCursorPosition (HANDLE hConsoleOutput, COORD dwCursorPosition); Параметрами цієї функції є стандартний дескриптор виведення

hConsoleOutput, отриманий функцією GеtStdHаndlе, і указівник структу-ри COORD з координатами нової позиції курсора:

COORD struc

x dw 0 у dw 0

ends За умовчанням колірне оформлення вікна консолі – чорний фон, бі-

лий текст. Внести розмаїтість у зовнішній вигляд вікна консолі допомо-же функція SetConsoleTextAttribute, за допомогою якої можна змінити установки кольору за умовчанням для тексту і фону:

BOOL SetConso1eTextAttribute (HANDLE hConsoleOutput, WORD wAttributes);

Page 393: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

393

Перший параметр — без коментарів, другий визначає колір тексту і фону. Другий параметр формується як логічне “АБО” таких значень:

– FOREGROUND_BLUE = 0001h – синій текст; – FOREGROUND_GREEN = 0002h – зелений текст; – FOREGROUND_RED = 0004h – червоний текст; – FOREGROUND_INTENSITY = 0008h – текст підвищеної яскраво-

сті; – BACKGROUND_BLUE = 0010h – блакитний фон; – BACKGROUND_GREEN = 0020h – зелений фон; – BACKGROUND_RED = 0040h – червоний фон; – BACKGROUND_INTENSITY = 0080h – фон підвищеної яскравос-

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

вдання чорного – компоненти не задаються зовсім.

12.3.2. Приклад програми консольного введення-виведення Для демонстрації використання функцій високорівневого введення-

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

ПРИКЛАД. Програма введення-виведення в консоль зі зміною ат-

рибутів виведеного тексту.

.486

.model flat, STDCALL ;модель пам’яті flat, ;STDCALL – передача параметрів така ж, як і у Сі (праворуч-ліворуч), ; викликувана процедура очистить за собою стек %NOINCL ;заборонити виведення тексту файлів, що включаються include WindowCon.inc ;Оголошення зовнішніми використовувані у програмі функції Win32 (ASCII): extrn AllocConsole :PROC extrn SetConsoleTitleA :PROC extrn GetStdHandle :PROC extrn SetConsoleCursorPosition :PROC extrn SetConsoleTextAttribute :PROC extrn ReadConsoleA :PROC

Page 394: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

394

extrn WriteConsole :PROC extrn ExitProcess :PROC ;макровизначення типів SSHORT equ <dw 0> ;структура для встановлення положення курсора в консолі: Coord struc

xx SSHORT yy SSHORT

Coord ends .data

con Coord <> dIn dd 0 ; дескриптор введення консолі dOut dd 0 ; дескриптор виведення консолі NumWri dd 0 ; кількість дійсно введених-виведених символів TitleText db 80 dup (0), 0

.code Start proc near ; точка входу в програму: call AllocConsole ; запит консолі ; перевірити успіх запиту консолі test eax, eax jz exit ; невдача ; одержимо стандартні дескриптори введення-виведення push STD_OUTPUT_HANDLE call GetStdHandle mov dOut, eax ; dOut – дескриптор виведення консолі push STD_INPUT_HANDLE call GetStdHandle mov dIn, eax ; dIn – дескриптор введення консолі ; введемо рядок, установимо курсор у позицію (2, 6) mov con.xx, 2 mov con.yy, 6 push con push dOut call SetConsoleCursorPosition cmp eax, 0 jz exit ; якщо неуспіх push 0 push offset NumWri ; кількість дійсно введених символів push 80 ; розмір буфера TitleText для введення

Page 395: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

395

push offset TitleText push dIn call ReadConsole ; зчитування ім’я вхідного файла cmp eax, 0 jz exit ; якщо неуспіх ; виведемо введений рядок у заголовок вікна консолі: push offset TitleText call SetConsoleTitle ; перевірити успіх виведення заголовка test eax, eax jz exit ; невдача ; виведемо рядок у вікно консолі з різних позицій і кольорами ; установимо курсор у позицію (2, 5) mov ecx, 10 ; рядок виведемо 10 разів mov bl, 10000001b ; початкові атрибути m1:

push ecx inc con.xx inc con.yy push con push dOut call SetConsoleCursorPosition cmp eax, 0 jz exit ; якщо неуспіх ; визначимо атрибути виведених символів ; будемо одержувати циклічні зсуви xor eax, eax rol bl, 1 mov al, bl push eax push dOut call SetConsoleTextAttribute cmp eax, 0 jz exit ; якщо неуспіх ; вивести рядок push 0 push offset NumWri ; дійсна кількість виведених на екран символів push NumWri ; довжина рядка для виведення на екран push offset TitleText ; адреса рядка для виведення на екран push dOut call WriteConsoleA

Page 396: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

396

cmp eax, 0 jz exit ; якщо неуспіх

pop ecx loop m1 exit: ; вихід з додатка ; готуємо виклик VOID ExitProcess (UINT uExitCode) push 0 call ExitProcess start endp end start

Кожен консольний процес має свій власний список функцій-

оброблювачів, що викликаються системою, коли відбуваються визначені

події, наприклад, при активному вікні консолі користувач натискає ком-

бінації клавіш Ctrl+C, Ctrl+Break або Ctrl+Close. При запуску консоль-

ного додатка список функцій-оброблювачів містить тільки задану за

умовчанням функцію-оброблювач, яка викликає функцію ExitProcess.

Консольний процес може додавати або видаляти додаткові функції-

оброблювачі, викликаючи функцію SetConsoleCtrl Handler.

BOOL SetConso1eCtr1Handler

(PHANDLER_ROUTINE HandlerRoutine,

BOOL Add);

Дана функція має два параметри:

а) HandlerRoutine – указівник визначеної додатком функції

HandlerRoutine, що повинна бути додана або вилучена;

б) Add – логічне значення, що означає:

1 – функція повинна бути додана,

0 – функцію необхідно видалити.

Функція HandlerRoutine – це визначена додатком функція зворот-

ного виклику. Консольний процес використовує цю функцію, щоб обро-

бити натискання клавіш керування. Насправді HandlerRoutine – іденти-

фікатор-заповнювач для визначеного додатком імені функції.

BOOL WINAPI Hand1erRoutine (DWORD dwCtrlType);

Page 397: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

397

Параметр DwCtrlType визначає тип сигналу керування, одержува-

ного оброблювачем. Цей параметр може набувати одного з таких зна-

чень:

– CTRL_C_EVENT = 0 – сигнал, що імітує натискання клавіш

Ctrl+C; він може бути отриманий із двох джерел: з клавіатури або як

сигнал, згенерований функцією GenerateConsoleCtrlEvent;

– CTRL_BREAK_EVENT = 1 – сигнал, що імітує натискання клавіш

Ctrl+Break; він може бути отриманий із двох джерел: з клавіатури або як

сигнал, згенерований функцією GenerateConsoleCtrl Event;

– CTRL_CLOSE_EVENT = 2 – сигнал, який система посилає всім

процесам, підключеним до даного консольного додатка, коли користувач

його закриває (вибираючи пункт Close у системному меню вікна консолі

або натискаючи на кнопки завершення задачі в діалоговому вікні мене-

джера задач);

– CTRL_LOGOFF_EVENT = 5 – сигнал, що посилається всім кон-

сольним процесам, коли користувач завершує роботу в системі (цей сиг-

нал не вказує, який саме користувач завершує роботу);

– CTRL_SHUTDOWN_EVENT = 6 – сигнал, який система посилає

всім консольним процесам при підготовці до вимикання машини.

Функція HandlerRoutine повинна повернути логічне значення:

1 – якщо вона обробляє конкретний сигнал керування;

0 – якщо для обробки отриманої події буде використовуватися ін-

ша функція-оброблювач HandlerRoutine зі списку функцій-оброблювачів

для цього процесу (тобто включена в цей список раніш даної функції).

Кожен консольний процес може визначити кілька функцій

HandlerRoutine, що зв’язуються в ланцюжок. Спочатку цей список міс-

тить тільки задану за умовчанням функцію оброблювача, що викликає

функцію ExitProcess і, як результат, приводить до завершення поточного

консольного додатка. Консольний процес додає або видаляє додаткові

функції оброблювача, викликаючи функцію SetConsoleCtrlHandler, яка

не включається до списку функцій-оброблювачів інших процесів. Коли

консольний процес приймає кожний із сигналів керування, то виклика-

ється остання зареєстрована функція-оброблювач; якщо вона не повер-

тає керування, то воно передається наступному (попередньому) зареєст-

рованому оброблювачу і т.д., доти, поки один з оброблювачів знову не

Page 398: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

398

поверне керування. Якщо жоден з оброблювачів цього не зробив, то ви-

кликається оброблювач, заданий за умовчанням.

Установка оброблювачів для сигналів CTRL_CLOSE_EVENT,

CTRL_LOGOFF_EVENT і CTRL_SHUTDOWN_EVENT дає процесу

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

шення додатка. Функція HandlerRoutine користувача може бути викли-

кана для того, щоб виконати такі дії:

– викликати функцію ExitProcess для завершення процесу;

– повернути 0 – це означає, що завершення додатка повиний вико-

нати оброблювач, заданий за умовчанням;

– повернути 1 – у цьому випадку ніякі інші функції-оброблювачі не

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

хідність завершення процесу; система також відображає діалогове вікно,

якщо процес не відповідає визначеному часу (5 секунд для

CTRL_CLOSE_EVENT і 20 секунд для CTRL_LOGOFF_EVENT і

CTRL_SHUTDOWN_EVENT); процес може використовувати функцію

SetProcessShutdownParameters, щоб заборонити системі відображати

останнє діалогове вікно; у цьому випадку система просто завершує про-

цес, коли HandlerRoutine повертає істину або коли минає визначений

період часу.

12.3.3. Програма обробки подій Нижче наведений приклад оброблювача подій користувача – вве-

дення комбінації Ctrl+C або Ctrl+Break. За основу взята попередня про-грама.

ПРИКЛАД. Програма демонструє використання оброблювача подій

користувача.

.486

.model flat,STDCALL ; модель пам’яті flat, ;STDCALL – передача параметрів як у мові Сі (праворуч-ліворуч), ;викликувана процедура чистить за собою стек

%NOINCL ; заборонити виведення тексту файлів, що включаються include WindowCon.inc ;Оголошення зовнішніми використовувані у програмі

;функції Win32 (ASCII):

Page 399: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

399

extrn AllocConsole:PROC extrn SetConsoleTitleA:PROC extrn GetStdHandle:PROC extrn SetConsoleCursorPosition:PROC extrn SetConsoleTextAttribute:PROC extrn ReadConsoleA:PROC extrn WriteConsoleA:PROC extrn MessageBeep:PROC extrn SetConsoleCtrlHandler:PROC extrn ExitProcess:PROC

;макровизначення типів SSHORT equ <dw 0> ;структура для встановлення положення курсора в консолі: Coord struc

xx SSHORT yy SSHORT

Coord ends .data

con Coord <> dIn dd 0 ; дескриптор введення консолі dOut dd 0 ; дескриптор виведення консолі NumWri dd 0 ; кількість дійсно введених-виведених символів TitleText db 80 dup (0),0 Text_CTRL_C db “Натиснуті CTRL+C” Len_Text_CTRL = $ - Text_CTRL_C Text_BREAK db “Натиснуті CTRL+BREAK” Len_BREAK = $ - Text_BREAK

.code CtrlHandler proc

arg @@dwCtrlType: DWORD uses ebx, edi, esi ; ці регістри обов’язково повинні зберігатися

; аналізуємо тип сигналу керування cmp @@dwCtrlType, CTRL_C_EVENT je h_CTRL_C_EVENT cmp @@dwCtrlType, CTRL_BREAK_EVENT je h_CTRL_BREAK_EVENT jmp h_default h_CTRL_C_EVENT: ; при натисканні CTRL+C виводимо повідомлення і звук:

Page 400: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

400

; установимо курсор inc con.xx inc con.yy push con push dOut call SetConsoleCursorPosition cmp eax, 0 jz exit ; якщо неуспіх ; вивести рядок push 0 push offset NumWri ; дійсна кількість виведених на екран символів push Len_Text_CTRL ; довжина рядка для виведення на екран push offset Text_CTRL_C ; адреса рядка для виведення на екран push dOut call WriteConsoleA cmp eax, 0 jz exit ; якщо неуспіх ; і звук: ; BOOL MessageBeep(UINT uType); push 0FFFFFFFFh call MessageBeep cmp eax, 0 jz exit ; якщо неуспіх ;повертаємо ознаку обробки mov eax, 1 jmp exit_CtrlHandler h_CTRL_BREAK_EVENT: ; при натисканні CTRL+BREAK виводимо повідомлення і звук: ; установимо курсор inc con.xx inc con.yy push con push dOut call SetConsoleCursorPosition cmp eax,0 jz exit ; якщо неуспіх ; вивести рядок push 0 push offset NumWri ; дійсна кількість виведених на екран символів push Len_BREAK ; довжина рядка для виведення на екран

Page 401: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

401

push offset Text_BREAK ; адреса рядка для виведення на екран push dOut call WriteConsoleA cmp eax, 0 jz exit ; якщо неуспіх ; і звук: ;BOOL MessageBeep(UINT uType); push 0FFFFFFFFh call MessageBeep cmp eax, 0 jz exit ; якщо неуспіх ; повертаємо ознаку обробки mov eax, 1 jmp exit_CtrlHandler h_default: mov eax, 0ffffffffh ; повертаємо 1 ;все інше не обробляємо exit_CtrlHandler: ret CtrlHandler endp start proc near ; точка входу в програму call AllocConsole ; запит консолі ; перевірити успіх запиту консолі test eax, eax jz exit ; невдача ; працюємо ... ; одержимо стандартні дескриптори введення-виведення push STD_OUTPUT_HANDLE call GetStdHandle mov dOut,eax ; dOut – дескриптор виведення консолі push STD_INPUT_HANDLE call GetStdHandle mov dIn, eax ; dIn – дескриптор введення консолі ; установимо функцию-оброблювач сигналів керування push TRUE push offset cs: CtrlHandler call SetConsoleCtrlHandler cmp eax, 0 jz exit ; якщо неуспіх

Page 402: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

402

; уведемо рядок ; установимо курсор у позицію (2, 6) mov con.xx, 2 mov con.yy, 6 push con push dOut call SetConsoleCursorPosition cmp eax, 0 jz exit ; якщо неуспіх push 0 push offset NumWri ; кількість дійсно введених символів push 80 ; розмір буфера TitleText для виведення push offset TitleText push dIn call ReadConsole ; зчитуємо ім’я вхідного файла cmp eax, 0 jz exit ; якщо неуспіх ; виведемо введений рядок у заголовок вікна консолі: push offset TitleText call SetConsoleTitle ; перевірити успіх виведення заголовка test eax, eax jz exit ; невдача ; виведемо рядок у вікно консолі з різних позицій і кольорами ; установимо курсор у позицію mov ecx, 10 ; рядок виведемо 10 разів mov bl, 10000001b ; початкові атрибути m1:

push ecx inc con.xx inc con.yy push con push dOut call SetConsoleCursorPosition cmp eax, 0 jz exit ; якщо неуспіх ; визначимо атрибути виведених символів ; виконання циклічного зсуву xor eax, eax

Page 403: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

403

rol bl, 1 mov al, bl push eax push dOut call SetConsoleTextAttribute cmp eax, 0 jz exit ; якщо неуспіх ; вивести рядок push 0 push offset NumWri ; дійсна кількість виведених на екран символів push NumWri ; довжина рядка для виведення на екран push offset TitleText ;а дреса рядка для виведення на екран push dOut call WriteConsoleA cmp eax, 0 jz exit ; якщо неуспіх

pop ecx loop m1 exit: push 0 call ExitProcess start endp end start

Стосовно цієї програми можна зробити два зауваження. Перше сто-

сується функції HandlerRoutine, яка у нашій програмі називається

CtrlHandler. Як зазначалося, ця функція є функцією зворотного виклику.

Її виклик виробляється при виникненні визначених подій неявно – із си-

стеми Windows.

Друге зауваження стосується порядку налагодження додатків, що

містять обумовлені користувачем функції зворотного виклику. Перше,

що потрібно зробити в процесі покрокового виконання програми в нала-

годжувачі, – визначити адресу процедури зворотного виклику. Це можна

зробити, з’ясувавши, яке значення буде поміщено в стек при виконанні

таких команд:

;...

Page 404: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

404

; установимо функцію-оброблювач сигналів керування

push TRUE

push offset cs: CtrlHandler

call SetConsoleCtrlHandler

cmp eax, 0

jz exit ; якщо неуспіх

;...

Після цього, зробивши активним вікно налагоджувача CPU (вибра-

вши в меню команду View CPU), необхідно установити указівник

мишки у вікно з командами процесора і натиснути праву кнопку мишки.

У контекстному меню слід вибрати пункт Goto... У результаті цих дій

налагоджувач відобразить діалогове вікно, у яке необхідно внести адре-

си програми-оброблювача CtrlHandler. У верхній частині вікна команд

відобразиться перша команда процедури CtrlHandler. Слід встановити на

ньому курсор і натиснути клавішу F4. Програма почне виконуватися за

своїм алгоритмом. При натисканні користувачем керуючих комбінацій

клавіш, які дозволені функцією HandlerRoutine, керування буде передано

цій функції.

Запитання для самоперевірки

1. Яка різниця у використанні функцій ReadConsole та

WriteConsole?

2. Перелічіть функції для організації високорівневого консольно-

го введення-виведення.

3. Які властивості високорівневого консольного введення-

виведення може змінювати Windows-додаток?

4. Які функції є оброблювачами подій у консольному Windows-

додатку?

Page 405: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

405

12.4. Низькорівневе консольне введення-виведення Низький рівень консольного введення-виведення в порівнянні з ви-

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

Розглянемо низькорівневе введення-виведення на прикладі роботи з

вхідним буфером і буферами екрана.

Для роботи з ними існують різні групи команд. Так, для роботи з

вхідним буфером використовуються функції низькорівневого введення-

виведення – WriteConsoleInput та ReadConsoleInput.

12.4.1. Робота з мишкою в консолі

Велике достоїнство консольних додатків – убудована засобами

Windows підтримка мишки. Вона реалізується за допомогою функції

ReadConsoleInput. Важливо відзначити, що ця функція використовуєть-

ся для одержання інформації не тільки про події мишки, але і про події

клавіатури.

BOOL ReadConsoleInput (HANDLE hConsoleInput,

PINPUT_RECORD lpBuffer,

DWORD nLength,

LPDWORD lpNumberOfEventsRead);

Параметри цієї функції:

– hConsoleInput – стандартний дескриптор введення, отриманий фу-

нкцією GetStdHandle;

– lpBuffer – указівник буфера, у який записується інформація про

дію миші. Ця область пам’яті має структуру, називану INPUT_

RECORD; Її формат розглянутий нижче (можливе групове читання ін-

формації з вхідного буфера, тому не тільки указівник lpBuffer може вка-

Page 406: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

406

зувати на масив структур; інформація про те, скільки подій буде зчиту-

ватися в цей масив структур, визначається параметром nLength);

– nLength – розмір вхідних записів буфера, на які вказує указівник

lpBuffer;

– lpNumberOfEventsRead – визначає змінну, в яку записується дійсне

число прочитаних записів вхідного буфера.

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

INPUT_RECORD. Її опис мовою Сі має такий вигляд:

typedef struct _INPUT_RECORD {

WORD EventType;

union {

KEY_EVENT_RECORD KeyEvent;

MOUSE_EVENT_RECORD MouseEvent;

WINDOW_BUFFER_SIZE_RECORD

WindowBufferSizeEvent;

MENU_EVENT_RECORD MenuEvent;

FOCUS EVENT RECORD FocusEvent;

} Event;

} INPUT_RECORD;

У цій структурі перше поле EventType розміром у слово містить тип

події, а друге поле Event є об’єднанням різних структур. Поля якої зі

структур будуть заповнені, визначить тип події, тобто перше поле, що

може набувати значень:

– KEY_EVENT = 0001h – поле Event містить структуру

KEY_EVENT_RECORD з інформацією щодо події клавіатури;

– MOUSE_EVENT = 0002h – поле Event містить структуру

MOUSE_EVENT_RECORD з інформацією щодо руху мишки або натис-

кання кнопки;

– WINDOM_BUFFER_SIZE_EVENT = 0004h – поле Event містить

структуру WINDOW_ BUFFER_SIZE_RECORD з інформацією щодо

нового розміру екранного буфера;

– MENU_EVENT = 0008h – поле Event містить структуру

MENU_EVENT_RECORD (ця подія використовується усередині

Windows і повинна ігноруватися);

Page 407: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

407

– FOCUS_EVENT = 0010h – поле Event містить структуру

FOCUS_EVENT_RECORD (ця подія використовується усередині

Windows і повинна ігноруватися).

Для обробки події миші структура MOUSE_EVENT_RECORD має

такий вигляд:

typedef struct _MOUSE_EVENT_RECORD {

COORD dwMousePosition;

DWORD dwButtonState;

DWORD dwControlKeyState;

DWORD dwEventFlags;

} MOUSE_EVENT_RECORD;

Структура INPUT_RECORD для обробки подій мишки в програмі

на асемблері повинна мати такий вигляд:

INPUT_RECORD struc

EventType dw 0

dwMousePosition struc

x dw 0

у dw 0

ends

dwButtonState dw 0

dwControlKeyState dw 0

dwEventFlags dw 0

ends

Поле EventType для події мишки містить значення MOUSE_EVENT

= 0002h, а поля структури MOUSE_EVENT_RECORD відповідно озна-

чають таке:

а) dwMousePosition – координати мишки у вікні консолі (у символь-

них координатах);

б) dwButtonState – стан кнопок мишки в момент виникнення події;

при натисканні кнопок установлюються такі біти:

– якщо встановлений біт 0 поля dwButtonState, то в момент на-

стання події була натиснута ліва кнопка мишки;

Page 408: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

408

– якщо встановлений біт 1 поля dwButtonState, то в момент на-

стання події була натиснута права кнопка мишки;

– якщо встановлений біт 2 поля dwButtonState, то в момент на-

стання події була натиснута середня кнопка мишки;

в) dwControlKeyState – поле описує стан керуючих клавіш клавіату-

ри в момент настання дії мишки (якщо одночасно натиснуто кілька кла-

віш, то значення в цьому полі є результатом операції логічного додаван-

ня перерахованих нижче значень):

– RIGHT_ALT_PRESSED = 0001h – натиснута права клавіша Alt;

– LEFT_ALT_PRESSED = 0002h – натиснута ліва клавіша Alt;

– RIGHT_CTRL_PRESSED = 0004h – натиснута права клавіша Ctrl;

– LEFT_CTRL_PRESSED = 0008h – натиснута ліва клавіша Ctrl;

– SHIFT_PRESSED = 0010h – натиснута будь-яка клавіша SHIFT;

– NUMLOCK_ON = 0020h – індикатор NumLock включений;

– SСРОLLLОСК_0N = 0040h – індикатор ScrollLock включений;

– CAPSLOCK_ON = 0080h – індикатор CapsLock включений;

– ENHANCED_KEY = 0100h – натиснута клавіша розширеної кла-

віатури (101 і 102 клавіші): Ins, Del, Home, End, Page Up, Page Down, ,

, , , / або Enter;

– dwEventFI ags – поле містить одне з двох значень:

– MOUSE_MOVED = 0001h – переміщення мишки;

– DOUBLE_CLICK = 0002h – подвійне натискання мишки.

ПРИКЛАД. Програма обробляє натискання клавіш мишки. При на-

тисканні лівої клавіші на екрані сеансу MS-DOS виводиться текст “На-

тиснута ліва клавіша мишки!!”, при натисканні правої – виведення з до-

датка

.486

.model flat,STDCALL

include ..\Tasm32\WindowConA.inc

extrn AllocConsole:PROC

extrn SetConsoleTitleA:PROC

extrn CharToOemA:PROC

extrn SetConsoleCursorPosition:PROC

extrn GetStdHandle:PROC

extrn ReadConsoleInput:PROC ; функція підтримки мишки

extrn WriteConsoleA:PROC

Page 409: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

409

extrn MessageBoxA:PROC extrn ExitProcess:PROC SSHORT equ <dw 0> Coord struc ; структура для установлення положення курсо-ра в консолі

xx SSHORT yy SSHORT

Coord ends INPUT_RECORD struc ;структура для обробки подій мишки:

EventType dw 0 dw 0

struc ; позиція мишки x_M dw 0 y_M dw 0 ends dwButtonState dd 0 ; стан кнопок мишки під час

; виникнення події = 0 – ліва натиснута, = 1 – права, = 2 – середня dwControlKeyState dd 0 ; стан керуючих клавіш

; клавіатури в момент натискання dwEventFlags dd 0

ends .data

INPUT_RECORD_buf INPUT_RECORD <> n_record dd 0 ; кількість записів, що повертаються ; про події мишки con Coord <> dIn dd 0 ; дескриптор введення консолі dOut dd 0 ; дескриптор виведення консолі NumWri dd 0 ; кількість дійсно введених-виведених символів TitleText db ‘Робота з мишкою в консолі’,0 Text_Out db ‘Натиснута ліва клавіша мишки’,0 Len_Text = $ - Text_Out

.code

start proc near ; точка входу в програму:

call AllocConsole ; запит консолі

Page 410: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

410

test eax, eax ; перевірити успіх запиту консолі

jz exit ; невдача

call GetStdHandle, STD_OUTPUT_HANDLE

mov dOut, eax ; dOut – дескриптор виведення консолі

call GetStdHandle, STD_INPUT_HANDLE

mov dIn, eax ; dIn – дескриптор введення консолі

; виведемо рядок у заголовок вікна консолі:

call SetConsoleTitle, offset TitleText

test eax, eax ; перевірити успіх виведення заголовка

jz exit ; невдача

call CharToOem, offset Text_Out, offset Text_Out

cycl:

; майже нескінченний цикл до натискання правої кнопки мишки

mov INPUT_RECORD_buf.EventType, 0

call ReadConsoleInputA, dIn, offset INPUT_RECORD_buf, 1, offset n_record

cmp eax, 0

jz exit ; якщо неуспіх

cmp INPUT_RECORD_buf.EventType, MOUSE_EVENT

jne cycl

; яка дія мишки відбулася?

; натиснута ліва кнопка?

bt INPUT_RECORD_buf.dwButtonState , 0

jc left_but

;натиснута права кнопка?

bt INPUT_RECORD_buf.dwButtonState , 1

jc exit

jmp cycl

left_but:

; при натисканні лівої кнопки мишки виведемо рядок у вікно консолі

mov ax, INPUT_RECORD_buf.x_M

mov con.xx, ax

mov ax, INPUT_RECORD_buf.y_M

mov con.yy, ax

call SetConsoleCursorPosition, Out, con

cmp eax, 0

jz exit

Page 411: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

411

call WriteConsoleA, dOut, offset Text_Out, Len_Text, offset NumWri, 0

cmp eax, 0

jz exit

jmp cycl

exit:

call ExitProcess, 0

start endp

end start

API Win32 також має функцію Mouse_Event, що дозволяє генерува-

ти події, що відповідають реальним рухам мишки. Тим самим API Win32

надає механізм для створення навчальних і демо-версій програм. Формат

цієї функції такий:

VOID mouse_event (DWORD dwFlags,

DWORD dx,

DWORD dy, DWORD dwData, DWORD dwExtraInfo)

12.4.2. Робота з клавіатурою консолі

Функції роботи з текстом високого рівня не дають інших можливос-тей роботи з клавіатурою, окрім примітивного введення тексту. При роз-робці програм текстового режиму часто потрібна інформація про стан керуючих клавіш, про факт утримання клавіші, що може свідчити корис-тувача повторити введення деякого символу або просто про бажання одержати тривіальний скан-код клавіші. Ці й інші події клавіатури дос-тупні програмі за допомогою описаної вище функції ReadConsoleInput.

Події клавіатури генеруються при натисканні будь-якої клавіші.

Процес їхньої обробки аналогічний обробці подій мишки. У першу чергу

заповнюється екземпляр структури INPUT_RECORD. При цьому в полі

EventType міститься значення KEY_EVENT = 0001h. Це означає, що

об’єднання Event містить структуру KEY_EVENT_RECORD з інформа-

цією про стан клавіатури. Зазначена структура містить такі поля:

typedef struct _KEY_EVENT_RECORD {

BOOL bKeyDown;

Page 412: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

412

WORD wRepeatCount;

WORD wVirtualKey Code;

WORD WVirtualScanCode;

union {

WCHAR UmcodeChar;

CHAR AsciiChar;

} uChar;

DWORD dwControlKeyState;

} KEY_EVENT_RECORD, *PKEY_EVENT_RECORD;

Той же код у перекладі на мову асемблеру:

KEY_EVENT_RECORD struc

BkeyDown db 0

WRepeatCount dw 0

WirtualKeyCode dw 0

WVirtualScanCode dw 0

union

UnicodeChar dw 0

AsciiChar db 0

ends

dwControlKeyState dd 0

ends

Поля цієї структури означають:

– BKeyDown – містить 1 (істина), якщо клавіша була натиснута, і 0

(неправда), якщо клавіша була відпущена;

– WrepeatCount – містить кількість повторних кодів при утриманні

клавіші в натиснутому стані;

– Wvirtual KeyCode – містить віртуальний код клавіші, що ідентифі-

кує дану клавішу не залежним від пристрою способом;

– WVirtualScanCode – містить віртуальний скан-код даної клавіші,

що являє собою апаратно-залежне значення, яке згенеровано апаратними

засобами клавіатури;

– об’єднання AsciiChar і UnicodeChar – містить або ASCII-код кла-

віші, або Unicode;

Page 413: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

413

– DwControlKeyState – містить стан керуючих клавіш (це поле міс-

тить такі ж значення, як і аналогічне поле в структурі, що описує дії

мишки: RIGHT.ALT PRESSED, LEFT_ALT_PRESSED, RIGHT_CTRL

PRESSED, LEFT_CTRL PRESSED, SHIFT_PRESSED, NUMLOCK_ON,

SCROLLLOCK_ON, CAPSLOCK_ON, ENHANCED_KEY).

Однократному натисканню клавіші реально відповідають дві дії –

натискання і відпускання клавіші. У зв’язку з цим програма виводить два

повідомлення. На практиці цього можна уникнути, аналізуючи поле

bKeyDown:

– bKeyDown = l, коли клавіша натиснута;

– bKeyOown = 0, коли клавіша відпущена.

ПРИКЛАД. Програма для обробки подій клавіатури. Вихід із про-

грами – натискання будь-якої кнопки мишки.

.486

.model flat,STDCALL ; модель пам’яті flat,

; STDCALL – передача параметрів як у мові Сі (праворуч-ліворуч),

; викликувана процедура чистить за собою стек

%NOINCL ; заборонити виведення тексту файлів

include WindowCon.inc

; Оголошення зовнішніми функцій

extrn AllocConsole:PROC

extrn SetConsoleTitleA:PROC

extrn SetConsoleCursorPosition:PROC

extrn GetStdHandle:PROC

extrn ReadConsoleInputA:PROC

extrn WriteConsoleA:PROC

extrn ExitProcess:PROC

SSHORT equ <dw 0>

; структура для установлення положення курсора в консолі:

Coord struc

xx SSHORT

yy SSHORT

Coord ends

; структура INPUT_RECORD для обробки подій мишки і клавіатури:

Page 414: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

414

INPUT_RECORD struc

EventType dw 0

dw 0

BkeyDown db 0

db 5 dup (0)

WRepeatCount dw 0

WVirtualKeyCode dw 0

WVirtualScanCode dw 0

AsciiChar db 0

db 2 dup (0)

dwControlKeyState dd 0

ends

.data

INPUT_RECORD_buf INPUT_RECORD <>

db 0ffh

; кількість записів, що повертаються, про події миші

n_record dd 0

con Coord <>

dIn dd 0 ; дескриптор введення консолі

dOut dd 0 ; дескриптор введення консолі

NumWri dd 0 ; кількість дійсно введених-виведених символів

db 0ffh

TitleText db “Робота з клавіатурою і мишкою в консолі”, 0

adr_Text dd 0 ; адреса рядка для виведення на екран

len_Text dd 0 ; довжина рядка для виведення на екран

Text_Out db “натиснута і відпущена клавіша клавіатури – правий Alt!”, 0

Len_Text_Out = $ - Text_Out

.code

Start proc near ; точка входу в програму:

;запит консолі

call AllocConsole

; перевірити успіх запиту консолі

test eax, eax

jz exit ;невдача

; одержимо стандартні дескриптори введення-виведення

push STD_OUTPUT_HANDLE

call GetStdHandle

mov dOut, eax ; dOut – дескриптор виведення консолі

Page 415: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

415

push STD_INPUT_HANDLE

call GetStdHandle

mov dIn, eax ; dIn – дескриптор введення консолі

; виведемо рядок у заголовок вікна консолі:

push offset TitleText

call SetConsoleTitle

test eax,eax ; перевірити успіх виведення заголовка

jz exit ; невдача

cycl:

; нескінченний (при бажанні) цикл до натискання будь-якої кнопки миш-

ки

mov INPUT_RECORD_buf.EventType, 0

push offset n_record

push 1

push offset INPUT_RECORD_buf

push dIn

call ReadConsoleInputA

cmp eax, 0

jz exit ; якщо неуспіх

cmp INPUT_RECORD_buf.EventType, MOUSE_EVENT

jne key

jmp exit

key:

cmp INPUT_RECORD_buf.EventType, KEY_EVENT

jne cycl

; яка подія клавіатури відбулася?

cmp INPUT_RECORD_buf.dwControlKeyState, RIGHT_ALT

_PRESSED

jne cycl

mov len_Text, Len_Text_Out

mov adr_Text, offset Text_Out

; виводимо рядок у вікно консолі:

; установимо курсор у поточну позицію мишки

inc con.xx

inc con.yy

push con

push dOut

call SetConsoleCursorPosition

Page 416: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

416

cmp eax, 0

jz exit ; якщо неуспіх

push 0

push offset NumWri ; дійсна кількість

; виведених на екран символів

Push dword ptr len_Text ; довжина рядка для виведення на екран

push dword ptr adr_Text ; адреса рядка для виведення на екран

push dOut

call WriteConsoleA

cmp eax, 0

jz exit ; якщо неуспіх

jmp cycl

exit: ; вихід з додатка

; готуємо виклик VOID ExitProcess (UINT uExitCode)

push 0

call ExitProcess

start endp

end start

12.4.3. Вікно консолі й екранний буфер Для того щоб легко зрозуміти співвідношення понять «вікно консо-

лі» і «екранний буфер консолі», уявіть собі офісний календар, на якому поточне число відзначається квадратною рамкою, закріпленою на про-зорій целофановій стрічці, і який переміщується уздовж неї. Тепер уяви-мо, що вміст листка календаря поза цією рамкою невидимий, тобто до-ступний тільки через віконце, утворене рамкою. Для того щоб побачити вміст усього листка календаря, необхідно рухати рамку. У контексті цієї асоціації листок календаря – це екранний буфер, а площа усередині рам-ки – вікно консолі, тобто видима частина екранного буфера.

Можлива підтримка декількох екранних буферів, пов’язаних з да-ною консоллю, але тільки один з них може піддаватися відображенню у вікні консолі – його називають активним екранним буфером. Інші ек-ранні буфери, якщо вони були створені, є неактивними.

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

Page 417: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

417

бити екранний буфер активним, використовується функція SetConsoleActiveScreenBufrer. Функція CreateConsoleScreenBuffer має показаний нижче формат. HANDLE CreateConso1eScreenBuffer (DWORD dwDesiredAccess, DWORD dwShareMode, CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwFlags, LPVOID lpScreenBufferData);

Параметри функції: а) dwDesiredAccess – визначає бажаний тип доступу до екранного

буфера консолі; цей параметр може бути або одним з наступних значень або їх комбінацією:

– GENERIC_READ = 80000000h – запитується доступ по зчитуван-ню до екранного буфера консолі для того, щоб дозволити процесу зчита-ти дані з буфера;

– GENERIC_WRITE = 40000000h – запитується доступ для запису до екранного буфера консолі для того, щоб дозволити процесу записати дані в буфер;

– dwShareMode – визначає можливість поділу цього екранного бу-фера консолі; нульове значення цього параметра вказує, що буфер не може бути розділений, ненульовий стан цього буфера може бути одним з таких значень або їх комбінацією:

– FILE_SHARE_READ – інші операції відкриття можуть бути вико-нані для екранного буфера консолі з доступом для зчитування;

– FILE_SHARE_WRITE – інші операції відкриття можуть бути ви-конані для екранного буфера консолі з доступом для запису;

– lpSecurityAttributes – указівник структури SECURITY_ATTRIBU-TES, що визначає, чи може дескриптор, який повертається функцією CreateConsoleScreenBuffer, успадковуватися дочірніми процесами; якщо lpSecurityAttributes = NULL, то дескриптор не може бути успадкований;

– dwFlags – визначає тип створюваного екранного буфера консолі; у даний час підтримується тільки один такий тип — CONSOLE_TEXTMODE_ BUFFER = 1;

– lpScreenBufferData — зарезервований і має дорівнювати NULL. Функція CreateConsoleScreenBuffer формує дескриптор створеного

екранного буфера, який потім використовується функціями для доступу до цього буфера.

Для того щоб зробити буфер активним, використовують функцію SetConsoleActiveScreenBuffer:

Page 418: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

418

BOOL SetConsoleActiveScreenBuffer (HANDLE hConsoleOutput); Функція має єдиний параметр – hConsoleOutput – дескриптор ек-

ранного буфера, створеного функцією CreateConsoleScreenBuffer. Як уже відзначалося, консоль може мати багато екранних буферів. Функція SetConsoleActiveScreenBuffer визначає, який з них буде відображений. Додаток може робити запис у неактивний екранний буфер і потім вико-ристовувати функцію SetConsoleActiveScreenBuffer для відображення вмісту буфера. Зчитування і запис у неактивний екранний буфер здійс-нюється функціями низькорівневого введення-виведення – WriteConsoleOutput та WriteConsoleOutputCharacter і ReadConsoleOutput та ReadConso1eOutputCharacter, яким при виклику передається дескрип-тор потрібного екранного буфера, отриманого попередньо функцією CreateConsoleScreenBuffer.

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

BOOL GetConso1eScreenBufferInfo (HANDLE hConsoleOutput, PCONSOLE_SCREEN_BUFFER_INFO

lpConsoleScreenBufferInfo); Параметрами цієї функції є: – hConsoleOutput — дескриптор екранного буфера, створеного фун-

кцією CreateConsoleScreenBuffer; дескриптор повинний мати тип досту-пу GENERIC_READ;

– lpConsoleScreenBufferInfo – указівник структури CONSOLE_ SCREEN_BUFFER_ INFO, у яку розміщується інформація про екранний буфер.

Структура CONSOLE_SCREEN_BUFFER_INFO має такий вигляд: typedef struct _CONSOLE_SCREEN_BUFFER_INFO {

; розмір екранного буфера в стовпцях і рядках COORD dwSize;

; координати стовпця і рядка курсора в екранному буфері COORD dwCursorPosition;

; колір фону і тексту, з якими записуються і відображаються ; символи в екранному буфері функціями WriteFi1e\WriteConso1e ; і ReadFile\ReadConso1e

Page 419: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

419

WORD wAttributes; ; визначає структуру SMALL_RECT, що містить координати ; лівого верхнього і нижнього правого кутів екранного буфера, ; видимого у вікні консолі на екрані дисплея

SMALL_RECT srWindow; ; визначає максимальний розмір вікна консолі з урахуванням ; поточного розміру екранного буфера і шрифту

COORD dwMaxliTiumWindowSize; } CONSOLE_SCREEN_BUFFER_INFO; Параметр srWindow містить координати видимої частини екранного

буфера. Керуючись діями користувача (виконуючого прокручування вікна або зміну його розміру) по відношенню до вікна консолі додаток може змінювати значення в структурі SMALL_RECT і передавати її на вхід функції SetConsoleWindowInfo, яка встановлює поточний розмір і позицію вікна консолі відносно екранного буфера.

BOOL SetConso1eWindowInfo (HANDLE

hConsoleOutput, BOOL bAbsolute, CONST SMALL_RECT *1pConso1eWindow); Параметрами цієї функції є: – hConsoleOutput – дескриптор екранного буфера, створеного функ-

цією CreateConsoleScreenBuffer; дескриптор повинний мати тип доступу GENERIC_WRITE;

– bAbsolute – визначає порядок використання координат у структурі, зазначеній параметром lpConsoleWindow; якщо bAbsolute = l (істина), то координати визначають нові лівий верхній і нижній правий кути вікна; якщо bAbsolute = 0 (неправда), – то координати відповідають зсуву щодо поточних координат кутів вікна;

– lpConsoleWindow – указівник на структуру SMALL_RECT, у яку записується інформація про нові координати екранного буфера.

Структура SMALL_RECT має такий вигляд: typedef struct _SMALL_RECT {

SHORT Left; //х – координата верхнього лівого кута SHORT Top; //у – координата верхнього лівого кута SHORT Right; //х – координата нижнього правого кута SHORT Bottom; //у – координата нижнього правого кута

} SMALL_RECT;

Page 420: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

420

При роботі з функцією SetConsoleWindowInfo слід мати на увазі, що вона повертає помилку (нульове значення), якщо координати видимої частини екранного буфера виходять за його дійсні межі. Максимально припустимий розмір вікна для даної консолі можна одержати за допомо-гою функції GetConsole-ScreenBufrerInfo. Таким чином, обидві ці функ-ції можна використовувати для перегортання екранного буфера.

Для закриття екранного буфера використовується функція CloseHandle, яка передає дескриптор екранного буфера, що закриваєть-ся.

BOOL C1oseHand1e (HANDLE hObject); Для того щоб завершити розгляд перелічимо ті з них, що залишили-

ся поза розглядом (табл. 12.4.).

Таблиця 12.4

Функції підтримки консольного додатка

Функція

Призначення

FillConsoleOutputAttribute

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

FillConsoleOutputCharacter Запис символу в екранний буфер певну кількість разів по зазначених координатах

FlushConsoleInputBuffer Запис на диск вхідного буфера консолі. Усі вхідні записи у вхідному буфері консолі

GenerateConsoleCtrlEvent Посилка сигналу, визначеного цією функ-цією, що спільно використовує консоль

GetConsoleCursorInfo Надання інформації про розмір і видимість курсора для зазначеного екранного буфера

GetConsoleMode

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

GetConsoleTitle Зчитування рядка з області заголовка для поточного вікна консолі

GetLargestConsoleWindow-

Size

Повертає розмір найбільшого можливого вікна консолі, заснованого на поточному шрифті і розмірі зображення

Page 421: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

421

Закінчення табл. 12.4

GetNumberOfConsoleInput

Events

Повертає кількість непрочитаних записів введення у вхідному буфері пульта

GetNumberOfConsoleMous

eButtons

Повертає число кнопок на миші, викорис-товуваних поточною консоллю

Зчитування даних із вхідного буфера кон-солі без їхнього видалення

ScrollConsoleScreenBuffer

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

SetConsoleCursorInfo Установка розміру і видимості курсора для зазначеного екранного буфера консолі

SetConsoleMode Установка режиму вхідного буфера консо-лі або режиму виведення екранного буфера консолі

SetConsoleScreenBufferSIz

e

Зміна розміру зазначеного екранного бу-фера консолі

SetStdHandle

Установка деякого дескриптора як дескри-птора стандартного введення, стандартного введення або пристрою помилки. Може використовуватися при переспрямуванні введення-виведення

12.5. Аналіз функцій BIOS

Для дослідження програми переривань BIOS необхідно знайти по-

чаткову адресу обробника переривань і виконати трасування команд, які

дозволять увійти в BIOS (за адресою сегмента F000:). За командою уста-

новки прапорця переривання STI знаходитиметься обробник необхідно-

го переривання, який закінчуватиметься командою повернення з перери-

вання IRET. Необхідно скопіювати команди обробника переривань та

дослідити його роботу.

Розглянемо 3 способи входу в обробник переривань. Для ОС

Windows XP необхідно перезавантажитися із завантажувальної дискети

або завантажувального CD.

Page 422: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

422

Спосіб 1. При використання цього способу часто відбувається за-

висання системи, тому що, по-перше, на початку дослідження в одну із

комірок прописуємо команду int (тим самим змінюємо зміст системної

пам’яті), по-друге, виконуємо трасування (виконання) команд у систем-

ній пам’яті.

Порядок дій такий:

1. У командній стрічці файлового менеджера, наприклад FAR, total

commander або ін. набрати ім’я програми debug:

c:/debug

2. У відповідь на запрошення програми debug ввести команду a:

_a <Enter>

3. Програма debug висвітить адресу сегмента та зміщення, напри-

клад:

179E: 0100.

4. У цьому же рядку в продовження ввести номер переривання, на-

приклад:

179E: 0100 int 10 <Enter>

5. Програма debug виведе рядок нової адреси, наприклад: 179E:

0102 у відповідь на яке обходимо натиснути <Enter>.

6. По команді u можна проглянути вміст пам’яті, починаючи з адре-

си CS:100, як наведено нижче:

7. Ввести команду трансляції із зсуву, вказаного в попередній відпо-

віді програми debug: _ t =179E:0100

_a 179E:0100 int 10 179E:0102 _t=179E:100

AX=0000 BX=0000 CX=0000 DX=0000 SP=FFE8 BP=0000 SI=0000 DI=0000 DS=179E ES=179E SS=179E CS=D470 IP=0007 NV UP DI PL NZ NA PO NC

D470:0007 FB STI _u D470:0007 FB STI D470:0008 84E4 TEST AH,AH D470:000A 7414 JZ 0020

Page 423: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

423

D470:000C 3D024F CMP AX,4F02 D470:000F 740A JZ 001B D470:0011 80FC4F CMP AH,4F D470:0014 740A JZ 0020 D470:0016 EA0C00E10F JMP 0FE1:000C D470:001B 53 PUSH BX D470:001C 50 PUSH AX D470:001D 8BC3 MOV AX,BX D470:001F 3D5050 CMP AX,5050 D470:0022 257F7F AND AX,7F7F D470:0025 83F803 CMP AX,+03 … D470:005B FF60FF JMP [BX+SI-01] D470:005E 04EF ADD AL,EF D470:0060 40 INC AX D470:0061 FF00 INC WORD PTR [BX+SI] D470:0063 FF00 INC WORD PTR [BX+SI] D470:0065 FF80EF01 INC WORD PTR [BX+SI+01EF] _u D470:0069 CF IRET

8. Послідовно давати команду трасування t (записувати порядок

виконання команд) доти, поки керування не передаватиметься за адре-

сою сегмента F000:. 9. Проглянути програму за допомогою команди u доти, поки не зу-

стрінеться команда IRET. 10. Скопіювати ті частини програми, які виконувалися у файл та

проаналізувати команди обробника переривань.

Спосіб 2. Спосіб дослідження обробника переривань полягає в ко-

піюванні у вільну область пам’яті програми обробника переривань і про-

ведення аналізу його роботи в цій області:

1. У командній стрічці файлового менеджера, наприклад FAR, total

commander або ін. набрати ім’я програми debug:

c:/debug

2. У відповідь на запрошення програми debug ввести команду a:

_a 7000:0 <Enter>,

де адреса сегмента та зміщення 7000:0 і є початковою адресою вільної

області пам’яті.

Page 424: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

424

3. Ввести команду int з номером переривання, яке досліджується та

натиснути <Enter>, наприклад:

_a 7000:0 <Enter>

7000:0000 int 8 >Enter>

7000:0002 <Enter>

4. Програма debug виведе номер наступної вільної адреси, у відпо-

відь на яке натиснути на <Enter>.

5. По команді u можна проглянути вміст пам’яті.

6. Ввести команду трансляції із зсуву, вказаного в попередній відпо-

віді програми debug: _ t = 100

8. Послідовно давати команду трасування t, як наведено на

рис. 12.1, доти, поки управління не передаватиметься за адресою сегмен-

та F000: … .

9. Проглянути програму за допомогою команди u доти, поки не зу-

стрінеться команда IRET.

Спосіб 3.

1. У відповідь на запрошення програми debug ввести нульову адре-

су – адресу таблиці векторів переривань:

_ d 0:0

Рис. 12.1. Вікно програми debug після введення команди INT 8

Page 425: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

425

2. У зв’язку з тим, що кожен вектор переривань займає в пам’яті 4

байта, то для того, щоб прочитати номера адрес сегмента та зміщення

необхідно прорахувати по 4 байта на кожне переривання. Наприклад,

переривання int 8 розміщується в пам’яті на початку третього рядка та

відображається як 46 07 13 02. Вікно програми debug із таблицею векто-

рів переривань наведено на рис. 12.2.

Причому, адреси сегмента та зміщення розміщуються у зворотному

порядку, наприклад, для int 8 – 0213: 0746.

3. По команді u можна проглянути вміст пам’яті, наприклад, для

int8:

_ u 0213: 0746.

4. Ввести команду трансляції із зсуву, вказаного в попередній відпо-

віді програми debug:

_ t =0213: 0746

5. Послідовно давати команду трасування t доти, поки керування не

передаватиметься за адресою сегмента F000: … .

6. Проглянути програму за допомогою команди u доти, поки не зу-

стрінеться команда IRET.

Запитання для самоперевірки

1. У чому полягають відмінності високого і низького рівнів консо-

льного введення-виведення?

2. Які функції підтримують роботу з мишею і клавіатурою при ни-

зькорівневому консольному введенні-виведенні?

3. Що розуміється під екранним буфером консолі?

Рис. 12.2. Вікно програми debug з таблицею векторів переривань

Page 426: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

426

Стислі висновки

1. У мові асемблеру власних засобів обміну з консоллю немає. Для

виконання обміну програма використовує переривання BIOS і MS-DOS.

2. Обслуговування клавіатури і монітора виконують програми

BIOS – драйвери, що складаються з функцій, кожна з яких виконує пев-

ні дії.

3. Для роботи з клавіатурою й екраном BIOS містить два програм-

них переривання – 16h і 10h. Для виклику переривань використовується

команда int 16h або int 10h. Для виконання визначеної операції в регістрі

аh указується номер функції.

4. Функції MS-DOS для роботи з консоллю зосереджені в оброб-

лювачі переривання int 21h. Це набір засобів, які займають проміжне

положення між програмами користувача і засобами BIOS. Деякі функції

BIOS можна комбінувати з функціями MS-DOS.

5. Звертання до сервісу Windows здійснюється за допомогою ви-

клику функцій, а не переривань. Однак у Win32 не можна безпосередньо

працювати з апаратним рівнем.

6. MS-DOS і Windows підтримують дві різні ідеології програму-

вання. MS-DOS після свого запуску повинна бути постійно активною, і

для одержання чергової порції даних із пристрою вводу-виводу вона

повинна виконувати відповідні запити до ОС. У Windows програма че-

кає, коли ОС приділить їх увагу посилкою повідомлень.

7. Логіка побудови Windows-додатка повинна забезпечувати корек-

тну і передбачувану роботу при надходженні повідомлень будь-якого

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

використовувати функції API Win32.

8. Windows підтримує віконний і невіконний (консольний) дода-

ток. Консольний додаток забезпечується функціями Windows.

9. Під консоллю в Windows розуміється або сам консольний дода-

ток, або вікно консольного додатка.

10. Консоль складається з одного вхідного і декількох екранних бу-

ферів. Вхідний буфер – черга, кожен запис якої містить інформацію що-

Page 427: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

427

до окремої вхідної події консолі. Екранний буфер – двовимірний масив,

що містить символи, виведені у вікно консолі, і дані про їхній колір.

11. Для підтримки роботи консольних додатків API Win32 містить

функції, що надають два рівні доступу до консолі –високий і низький.

12. Консольні функції введення високого рівня дозволяють додатку

зчитати дані, отримані при введенні з клавіатури і збережені у вхідному

буфері консолі. Консольні функції виведення високого рівня дозволяють

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

для того, щоб відобразити цей текст в екранному буфері консолі.

13. Консольні функції низького рівня дозволяють додаткам одер-

жати детальну інформацію про введення з клавіатури, події натискання-

відпускання кнопок мишки і про маніпуляції користувача з вікном кон-

солі, а також здійснити більший контроль над виведенням даних на ек-

ран.

14. Функції високого рівня забезпечують простоту процесу введен-

ня-виведення шляхом використання стандартних дескрипторів введення-

виведення, але при цьому неможливий доступ до вхідного й екранного

буферів консолі. Функції низького рівня вимагають урахування більшої

кількості деталей і обсягу коду, але це компенсується більшою гнучкіс-

тю.

15. З кожною консоллю пов’язані дві кодові таблиці: 1) вхідна – для

трансляції введення з клавіатури у відповідне символьне значення і вихі-

дна; 2) для трансляції символьних значень, які формуються різними фу-

нкціями виведення, у символ, відображуваний у вікні консолі.

Page 428: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

428

ДОДАТОК 1

СИСТЕМА КОМАНД МП І8086

Таблиця Д1.1

Система команд МП і8086 у компактній формі

Мнемокод Операнд nВ nТ Мнемокод Операнд nВ nТ

MOV r , r 2 2 SBW – 1 5

r, m 2 – 4 8 + E CWD – 1 5

m, r 2 – 4 9 + E SHL r 2 2

ac, m 3 11 SAL m 2– 4 15 + E

m, ac 3 11 SHL r, CL 2 8 + 4N

r, d 2 – 3 4 SAR m, CL 2 – 4 20 + E+

m, d 3 – 6 10 + E + 4N

r, sr 2 2 ROL

sr, г 2 2 ROR

m, sr 2 – 4 9 + E RCL

sr, m 2 – 4 8 + E RCR

PUSH r 1 10 JMP6) disp 2 – 3 15

m 2 – 4 16 + E r 2 11

sr 1 10 m 2 – 4 18 + E

PUSHF – 1 10 JMP7) addr 5 15

POP r 1 8 m 2 – 4 24 + E

m 2 – 4 17 + E Jcond disp 2 8/4

sr 1 8 CALL6) disp 3 19

POPF – 1 8 r 2 16

XCHG r, г 2 4 m 2 – 4 21 + E

XLAT – 1 11 CALL7) addr 5 28

IN P, ac 2 10 m 4 37 + E

ac, [DX] 1 8 RET6) – 1 8

OUT P, ac 2 10 d 3 12

[DX], ac 1 8 RET7) – 1 12

LEA r, m 3 – 4 2 + E d 3 18

LDS r, m 3 – 4 16 + E LOOP disp 2 17/5

LES r, m 3 – 4 16 + E LOOPZ disp 2 18/6

INC r 1 2 LOOPNZ

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 429: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

429

Закінчення табл. Д1.1

Мнемокод Операнд nВ nТ Мнемокод Операнд nВ nТ

DEC m 2 – 4 15 + E JCXZ

NEC r 2 3 INT 1 52

NOT m 2 – 4 16 + E type 2 51

ADD r, r 2 3 INT0 1 53/4

ADC r, m 2 – 4 9 + E IRET 1 24

SUB m, r2) 2 – 4 16 + E REP 1 6

SBB r, d 3 – 4 4 MOVS 1 18

CMP ac, d 2 – 3 4 CMPS8) 2 9 + 13

AND1) m, d 3 – 6 17 + E SCAS8) 1 15

OR1) 2 9 + 15

XOR1) LODS8) 1 12

TEST1) 2 9 + 13

Согг3) – 1 4 STOS8) 1 11

Flag4) – 1 2 2 9 + 10

MUL5) r/m 2 – 4 133 WAIT 1 3

IMUL5) r/m 2 – 4 154 NOP 1 3

DIV5) r/m 2 – 4 162 HLT 1 2

IDIV5) r/m 2 – 4 184 ESC r 2 2

AAM – 2 83 m 2 – 4 8 + E

AAD – 2 60 LOCK 1 2

1) Логічні команди (на відміну від наведених у цьому ж рядку ари-

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

(тобто при w = 1) вказується однобайтний безпосередній операнд d.

2) Команда TEST не має варіанта m, r з часом виконання 16 + Е,

тому що він був би еквівалентний більш короткому варіанту r, m.

3) Согг – команди корекції при додаванні і відніманні: DAA, DAS,

AAA, AAS.

4) Flag використовується для позначення команд керування прапо-

рцями CLC, STC, CMC, CLI, STI, CLD, STD.

5) Для команд множення і ділення зазначено час виконання при ро-

боті з операндами максимально припустимої довжини, розміщеними в

регістрах.

6) Команда здійснює внутрішньосегментний перехід, виклик або

Page 430: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

430

повернення.

7) Команда здійснює міжсегментний перехід, виклик або повернен-

ня.

8) Задано час виконання одного циклу ланцюгової команди, що має

префікс повторення.

Позначення:

г – загальний регістр;

sr – сегментний регістр;

m – адреса комірки пам'яті, що вказується в мнемокоді відповідно

до використовуваного способу адресації;

d – безпосередній операнд;

ас – акумулятор АХ чи AL;

р – адреса 8-розрядного порту вводу-виводу;

disp – зміщення при адресації відносно IP;

addr – указівник адреси при міжсегментних переходах і викликах;

type – тип (вектор) переривання;

cond – умови в команді умовних переходів.

Для кожного варіанта команди зазначено число байтів у форматі nB

і число тактів синхронізації nT, необхідне для виконання команди. Зна-

чення Е, що дорівнює числу тактів і що потрібне для обчислення ефек-

тивної адреси ЕА, слід брати з табл. Д1.2 відповідно до зазначеного в

команді способу адресації.

Таблиця Д1.2

Адресація Спосіб обчислення ЕА

Позначення Число тактів Е (ЕА)

Пряма Disp disp 6

Непряма [BX], [BP], [SI], [DI] [r] 5

Базова чи індек-

сна

[BX, BP, SI, DI] +

disp [r]disp 9

Базова індексна:

без зсуву [BP + DI], [BX + SI] [r][r] 7

[BP + SI], [BX + DI] 8

зі зсувом [BP + DI ] + disp [r]disp[r] 11

[BX + SI ] + disp 11

[BP + SI ] + disp 12

[BX + DI ]+ disp 12

Page 431: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

431

Вплив команд на прапорці ілюструє табл. Д1.3, в яку включені

тільки ті команди, що цей вплив здійснюють. Знак питання відповідає

випадкам, коли стан прапорця після виконання команди довільний (на-

приклад, залежить від конкретних значень операндів). Примітка. "+" – результат операції впливає на прапорець; "–" – не впли-

ває; 1 – встановлює в "1"; 0 – встановлює в "0"; Г – інвертує; ? – не визначений.

У табл. Д1.2 використовуються такі позначення: disp 8/16 – змі-

щення у форматі команди, що складається з одного чи двох байтів; d

8/16 – одна- чи двобайтова константа; sbr – ім'я підпрограми; diff – різ-

ниця між адресою переходу і вмістом указівника команд IP (при адреса-

ції відносно IP); label – мітка до переходу. Приклад ланцюгових команд:

MOVSB – пересилання байтів, MOVSW – пересилання слів.

Таблиця Д1.3

Операції Команди Прапорці

OF CF AF SF ZF PF

Додавання ADD, ADC, SUB, SBC + + + + + +

Віднімання CMP, NEG, CMPS, SCAS + + + + + +

INC, DEC + – + + + +

Множення MUL, IMUL + + ? ? ? ?

Ділення DIV, IDIV ? ? ? ? ? ?

Десяткова корекція DAA, DAS ? + + + + +

AAA, AAS ? + + ? ? ?

AAM, AAD ? ? ? + + +

Логічні AND, OR, XOR, TEST 0 0 ? + + +

Зсув SHL, SHR1) + + ? + + +

SHL, SHR2) ? + ? + + +

SAR 0 + ? + + +

ROL, ROR, RCL, RCR1) + + – – – –

ROL, ROR, RCL, RCR2) ? + – – – –

Відновлення прапор-

ців

POPF, IRET + + + + + +

SAHF + + + + + +

Керув. прапорцем С STC – 1 – – – –

CLC – 0 – – – –

CMC – Г – – – –

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 432: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

432

Зведена система команд МП i8086 наведена в табл. Д1.4.

Таблиця Д1.4

Зведена система команд МП i8086 Мне-

мон.

Операнди Ознаки Символічне позначення

операції

Зміст операції

1. Загальні пересилання

MOV

MOV

MOV

MOV

dst, src

dst, data

dst, sreg

sreg, src

(dst)← (src)

(dst)← (data)

(dst) ← (sreg)

(sreg) ← (src)

Пересилання даних

PUSH

PUSH

src

sreg

(stack) ← (src)

(stack) ← (sreg)

Запис у стек

POP dst – (dst) ← (stack) Обмін

POP sreg – (sreg) ← (stack) Перекодування

2. Ввід-вивід

IN

OUT

A, port

роrt, A

(AL чи АХ) ← (роrt)

port ← (AL чи АХ)

Введення

Виведення

3. Пересилання вмісту регістра ознак

LAHF – (АН) ← (FLAGS) мол. б. Завантаження мол.

байта FLAGS в АН

SAHF – (FLAGS) мол.б. ← (АН) Завантаження АН

у мол. байт FLAGS

PUSHF – (stack) ← (FLAGS) Завантаження

FLAGS у стек

POPF – (FLAGS) ← (stack) Завантаження

FLAGS зі стека

4. Додавання

ADD

ADD

dst, src

dst, data

A, C, O, P, S, Z

A, C, O, P, S, Z (dst) ← (dst) + (src)

(dst) ← (dst) + (data)

Додавання

без переносу

ADC

ADC

dst, src

dst, data

A, C, O, P, S, Z

A, C, O, P, S, Z (dst) ← (dst) + (src) + (CF)

(dst) ← (dst) + (data) + (CF)

Додавання з пере-

носом

INC dct A, O, P, S, Z (dst) ← (dst) + 1 Збільшення

ААА

DAA

A, C

A, C, P, S, Z Десят. корекція Апри додаванні (неупак.

формат). Те ж саме при упакованому форматі

8. Логічні операції

NOT dst O = 0, C = 0

S, P, Z

(dst) ← 0FFH- (dst)

(dst) ← 0FFFFH – (dst)

Інверсія

AND

AND

dst, src

dst, data

O = 0, C = 0

S, P, Z

(dst) ← (dst) ٨ (src)

(dst) ← (dst) ٨ data

Логічна операція І

ОR

OR

dst, src

dst, data

O = 0, C = 0

S, P, Z

(dst) ←( dst) ٧ (src)

(dst) ← (dst) ٧ data

Логічна операція

АБО

Page 433: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

433

Продовження табл. Д1.4 Мне-мон.

Операн-ди

Ознаки Символічне позначення операції

Зміст операції

XOR XOR

dst, src dst, data

O = 0, C = 0 S, P, Z

(dst) ← (dst) + src) (dst) ← (dst) + data

Логічна операція ВИКЛЮЧНЕ АБО

5. Віднімання

SUB SUB

dst, src dst, data

A,

C, O, P, S, Z

A, C, O, P, S, Z

(dst) ← (dst) – (src) (dst) ← (dst) – (data)

Віднімання без пози-ки

SBB SBB

dst, src dst, data

A, C, O, P, S, Z

A, C, O, P, S, Z (dct) ← (dst)- (src) – (CF) (dct) ← (dct) – (data) – (CF)

Віднімання з позикою

DEC dst A, O, P, S, Z (dst) ← (dst) – 1 Від’ємне збільшення

NEG dst – (dst) ← FFH – (dct) + 1 (dst) ← FFFFH – (dst) + 1

Одержання дод. коду (зі зміною знака)

CMP CMP

dst, src dst, data

A, C, O, P, S, Z

A, C, O, P, S, Z (dst) – (src)

(dst) – (data) Порівняння

AAS A, C Корекція неупакова-ної десяткової цифри при виднімання

DAS A, C, O, P, S, Z Корекція упакованого десяткового числа при виднімання

6. Множення

MUL src (DX) ≠ 0

CF = 1, OF = 1 (DX, AX) ← (AX) (src) Множення чисел

без знака

IMUL src (DX) ≠ 0 чи

ОFFFFH

CF = 1, OF = 1

(DX, AX) ← (AX) (src) Множення чисел зі знаком

ААМ Десяткова корекція неупакованих цифр

в АН і АL при множенні

7. Ділення

DIV src – (AL) ← (AX)/(src) (AH) ← (MOD) (AX, src)

Ділення без знака двобайтового АН на однобайтовий src

DIV src – (AX) ← (DX, AX) / (src) (DX) ← (MOD) ((DX,

AX), (src))

Ділення без знака 4-байтового DX, AX на двобайтовий src

IDIV src – (AL) ← (AX)/(src) (AH) ← (MOD) (AX, src)

Ділення зі знаком двобайтового АХ на однобайтовий src

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 434: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

434

Продовження табл. Д1.4 Мне-

мон.

Операн-

ди

Ознаки Символічне позначення опе-

рації

Зміст операції

IDIV src – (AX) ← (DX, AX) / (src)

(DX) ← (MOD) ((DX, AX),

(src))

Ділення зі знаком

4-байтового DX, AX

на двобайтовий src

AAD P, S, Z Корекція AL ділення

двох неупакованих

десятк. цифр

СВ – (AL) < 0 (AH) = 0FFH

(AL) ≥ 0 (AH) = 00H

Перетворення байта

на слово

CWD – (AX) < 0 (DX) = 0FFFFH

(AX) ≥ 0 (DH) = 0000H Перетворення слова

на подвійне слово

8. Логічні операції

NOT dst О = 0, С = 0

S, P, Z

B

W

(dst) ← 0FFH- (dst)

(dst) ← 0FFFFH – (dst)

AND

AND

dst, src

dst, data

O = 0, C = 0

S, P, Z

B, W

B, W

(dst) ← (dst) ٨ (src)

(dst) ← (dst) ٨ data

ОR

OR

dst, src

dst, data

O = 0, C = 0

S, P, Z

B, W

B, W

(dst) ←( dst) ٧ (src)

(dst) ← (dst) ٧ data

XOR

XOR

dst, src

dst, data

O = 0, C = 0

S, P, Z

B, W

B, W

(dst) ← (dst) + src)

(dst) ← (dst) + data

TEST

TEST

dst, src

dst, data

O = 0, C = 0

S, P, Z

B, W

B, W

(dst) ٨ (src)

(dst) ٨ (data)

9. Зсув

CHL/

CAL

dst, cnt C, P, S, Z Логіч./ ариф. зсув

вліво на cnt розрядів

SHR dst, cnt C, P, S, Z Логічний зсув впра-

во на cnt розрядів

SAR dst, cnt C, P, S, Z Ариф. зсув вправо

на cnt розрядів

ROL dst, cnt C, P, S, Z Циклічний зсув вліво

без переносу

ROR dst, cnt C, P, S, Z Циклічний зсув

вправо без переносу

RCL dst, cnt C, P, S, Z Циклічниц зсув вліво

через перенос

Page 435: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

435

Продовження табл. Д1.4 Мне-

мон.

Операнди Ознаки Символічне позначен-

ня операції

Зміст операції

RCR dst, cnt C,P,S,Z Циклічний зсув вправо

через перенос

10. Безумовний перехід

CALL addr – (IP) ← (IP) + addr Виклик програми за

адр. addr CALL src – (IP) ← (src) Виклик програми за

адр. в src RET – Повернення з підп-

рогр. JMP addr – (IP) ← (IP) + addr Перехід за адресою

addr JMP src – (IP) ← (src) Перехід за адресою в

src

11. Умовний перехід за значенням прапорця JC addr 8 – (IP) ← (IP) + addr 8

якщо (СF) = 1 Перехід при переносі

JNС addr 8 – якщо (СF) = 0 Перехід при відсут-

ності переносу JS addr 8 – якщо (SF) = 1 Перехід при

від’ємному результа-

ті JNS addr 8 – якщо (SF) = 0 Перехід при додат-

ному результаті JE, JZ addr 8 – якщо (ZF) = 1 Перехід якщо дорів-

нює/ при нульовому

результаті JNE, JNS

addr 8 – якщо (ZF) = 0 Перехід якщо не до-

рівнює/ при ненульо-

вому результаті JO addr 8 – якщо (OF) = 1 Перехід при наявно-

сті переповнення JNO addr 8 – якщо (OF) = 0 Перехід при відсут-

ності переповнення

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 436: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

436

Закінчення табл. Д1.4 Мне-

мон.

Операнди Ознаки Символічне позначення

операції

Зміст операції

JP, JPE addr 8 – якщо (PF) = 1 Перенос при пар-

ності

JNP, JPO

addr 8 – якщо (PF) = 0 Перенос при не-

парності

JBE, JNA

addr 8 – якщо (СF) v (ZF) = 1 Перехід при мен-

ше

чи дорівнює/ не

більше

JA, JNBE

addr 8 – якщо (СF) v (ZF) = 0 Перехід при біль-

ше/ не менше та

не дорівнює

12. Керування циклами

LOO

P

JCXZ

addr 8

addr 8

(CX) < (CX) – 1,

(IP) ←(IP) + addr 8

якщо (CX) <> 0

якщо CX = 0

Циклічний пере-

хід

за адресою

13. Установка значення ознаки

CLC CF ← 0 Установка CF у 0

CMC CF ← 1 – CF Інвер. ознаки CF

STC CF ← 1 Уст. CF у 1

CLD DF ← 0 Уст. DF у 0

STD DF ← 1 Уст. DF у 1

CLI IF ← 0 Уст. IF у 1

STI IF ← 1 Уст. IF у 0

14. Інші команди

HLT Зупинка

WAIT Переведення у

стан очікування

NOP Відсутність опе-

рації

Page 437: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

437

У табл. Д1.4 прийняті такі позначення:

B – байт, W – слово, D – подвійне слово;

dst і src – операнди (один з них повинен бути регістром);

data – позначення безпосереднього операнда, що повинно бути ви-

разом типу NUMBER;

cnt – число розрядів, на яке здійснюється зсув операнда dst; якщо в

поле cnt записується CL, число зсувів дорівнює вмісту регістра CL;

reg – будь-який регістр АХ...DI в операціях над словами чи будь-

який однобайтовий регістр в операціях над байтами;

sreg – будь-який сегментний регістр CS...ES;

FLAGS – регістр ознак:

С – переносу,

Р – паритету,

А – дод. переносу,

Z – нуля,

S – знака,

О – переповнення.

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 438: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

438

ДОДАТОК 2

Таблиця Д2.1

ТАБЛИЦІ КОДУВАННЯ СИМВОЛІВ

Базова таблиця кодування ASCII

0 NUL 27 ESC 48 0 75 K 102 f

1 SOH 28 FS 49 1 76 L 103 g

2 STX 29 GS 50 2 77 M 104 h

3 ETX 30 RS 51 3 78 N 105 i

4 EOT 31 US 52 4 79 O 106 j

5 ENQ 32 Пропуск 53 5 80 P 107 k

6 ACK 33 ! 54 6 81 Q 108 l

7 BEL 34 " 55 7 82 R 109 m

8 BS 35 # 56 8 83 S 110 n

9 HT 36 $ 57 9 84 T 111 o

10 LF 37 % 58 : 85 U 112 p

11 VT 38 & 59 ; 86 V 113 q

12 FF 39 ' 60 < 87 W 114 r

13 CR 40 ( 61 = 88 X 115 s

14 SO 41 ) 62 > 89 Y 116 t

15 SI 42 * 63 ? 90 Z 117 u

16 DLE 43 + 64 @ 91 [ 118 v

17 DC1 44 , 65 A 92 \ 119 w

18 DC2 45 - 66 B 93 ] 120 x

19 DC3 46 . 67 C 94 ^ 121 y

20 DC4 47 / 68 D 95 _ 122 z

21 NAK 32 Пропуск 69 E 96 ` 123 {

22 SYN 33 ! 70 F 97 a 124 |

23 ETB 34 " 71 G 98 b 125 }

24 CAN 35 # 72 H 99 c 126 ~

25 EM 36 $ 73 I 100 d 127 DEL

26 SUB 37 % 74 J 101 e

Page 439: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

439

Таблиця Д2.2

Кодування Windows (cp-1251)

128 Ђ 156 њ 183 · 210 Т 240 р

129 Ѓ 157 ќ 184 ё 211 У 241 с

130 , 158 ћ 185 № 212 Ф 242 т

131 ѓ 159 џ 186 є 213 Х 243 у

132 „ 160 187 » 214 Ц 244 ф

133 … 161 Ў 188 j 215 Ч 245 х

134 † 162 ў 189 S 216 Ш 246 ц

135 ‡ 163 J 190 s 217 Щ 247 ч

136 È 164 ¤ 191 ї 218 Ъ 248 ш

137 ‰ 165 Ґ 192 А 219 Ы 249 щ

138 Љ 166 ¦ 193 Б 220 Ь 250 ъ

139 < 167 § 194 В 221 Э 251 ы

140 Њ 168 Ё 195 Г 222 Ю 252 ь

141 Ќ 169 © 196 Д 223 Я 253 э

142 Ћ 170 Є 197 Е 224 а 254 ю

143 Џ 171 « 198 Ж 225 б 255 я

144 ђ 172 ¬ 199 З 226 в

145 ‘ 173 - 200 И 227 г

146 ’ 174 ® 201 Й 228 д

147 “ 175 Ї 202 К 229 е

148 ” 176 203 Л 230 ж

149 • 177 204 М 231 з

150 – 178 I 205 Н 232 и

151 — 179 i 206 О 233 й

152 ~ 180 ґ 207 П 234 к

153 ™ 181 µ 208 Р 235 л

154 љ 182 ¶ 209 С 236 м

Page 440: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

440

Таблиця Д2.3

Кодування КОИ-8

128 155 ⌡ 182 ╤ 209 я 236 Л

129 │ 156 ° 183 ╥ 210 р 237 М

130 ┌ 157 ² 184 ╦ 211 с 238 Н

131 ┐ 158 185 ╧ 212 т 239 О

132 └ 159 186 ╨ 213 у 240 П

133 ┘ 160 - 187 ╩ 214 ж 241 Я

134 ├ 161 Ё 188 ╪ 215 в 242 Р

135 ┤ 162 ╒ 189 ╫ 216 ь 243 С

136 ┬ 163 ё 190 ╬ 217 ы 244 Т

137 ┴ 164 ╓ 191 ё 218 з 245 У

138 ┼ 165 ╔ 192 ю 219 ш 246 Ж

139 ▀ 166 ╕ 193 а 220 э 247 В

140 ▄ 167 ╖ 194 б 221 щ 248 Ь

141 █ 168 ╗ 195 ц 222 ч 249 Ы

142 ▌ 169 ╘ 196 д 223 ъ 250 З

143 ▐ 170 ╙ 197 е 224 Ю 251 Ш

144 ░ 171 ╚ 198 ф 225 А 252 Э

145 ▒ 172 ╛ 199 г 226 Б 253 Щ

146 ▓ 173 ╜ 200 х 227 Ц 254 Ч

147 ⌠ 174 ╝ 201 и 228 Д 255 Ъ

148 ■ 175 ╞ 202 й 229 Е

149 ∙ 176 ╟ 203 к 230 Ф

150 √ 177 ╠ 204 л 231 Г

151 ≈ 178 ╡ 205 м 232 Х

152 ≤ 179 Ё 206 н 233 И

153 ≥ 180 ╢ 207 о 234 Й

154 181 ╣ 208 п 235 К

Page 441: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

441

Таблиця Д2.4

ДОСТ-альтернативне кодування (cp-866)

128 А 155 Ы 182 ╢ 209 ╤ 236 ь

129 Б 156 Ь 183 ╖ 210 ╥ 237 э

130 В 157 Э 184 ╕ 211 ╙ 238 ю

131 Г 158 Ю 185 ╣ 212 ╘ 239 я

132 Д 159 Я 186 ║ 213 ╒ 240 Ё

133 Е 160 а 187 ╗ 214 ╓ 241 ё

134 Ж 161 б 188 ╝ 215 ╫ 242 Є

135 З 162 в 189 ╜ 216 ╪ 243 є

136 И 163 г 190 ╛ 217 ┘ 244 Ї

137 Й 164 д 191 ┐ 218 ┌ 245 ї

138 К 165 е 192 └ 219 █ 246 Ў

139 Л 166 ж 193 ┴ 220 ▄ 247 ў

140 М 167 з 194 ┬ 221 ▌ 248 ∙

141 Н 168 и 195 ├ 222 ▐ 249 °

142 О 169 й 196 − 223 ▀ 250

143 П 170 к 197 ┼ 224 р 251 √

144 Р 171 л 198 ╞ 225 с 252 №

145 С 172 м 199 ╟ 226 т 253 ¤

146 Т 173 н 200 ╚ 227 у 254 ■

147 У 174 о 201 ╔ 228 ф 255

148 Ф 175 п 202 ╩ 229 х

149 Х 176 ░ 203 ╦ 230 ц

150 Ц 177 ▒ 204 ╠ 231 ч

151 Ч 178 ▓ 205 ═ 232 ш

152 Ш 179 │ 206 ╬ 233 щ

153 Щ 180 ┤ 207 ╧ 234 ъ

154 Ъ 181 ╡ 208 ╨ 235 ы

Page 442: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

442

Додаток 3

ВАРІАНТИ ЗАДАЧ

Тип 1

1. Задано масиви А і В по N = 11 елементів. Навести алгоритм та

програму сформування масиву С за правилом: якщо Аi > Вi, то

Сi = Аi + Вi; інакше – Сi = Аi – Вi.

2. Задано масиви А і В по N = 12 елементів. Навести алгоритм та

програму сформування масиву С за правилом: якщо Аi > Вi, то

Сi = Вi – Аi; інакше – Сi = Аi + Вi.

3. Задано масиви А і В по N = 13 елементів. Навести алгоритм та

програму сформування масиву С за правилом: якщо Аi ≥ Вi, то

Сi = Аi + Вi; інакше – Сi = Аi – Вi.

4. Задано масиви А і В по N = 14 елементів. Навести алгоритм та

програму сформування масиву С за правилом: якщо Аi ≥ Вi, то

Сi = Вi – Аi; інакше – Сi = Аi + Вi.

5. Задано масиви А і В по N = 15 елементів. Навести алгоритм та

програму сформування масиву С за правилом: якщо Аi < Вi, то

Сi = Аi + Вi; інакше – Сi = Аi – Вi.

6. Задано масиви А і В по N = 10 елементів. Навести алгоритм та

програму сформування масиву С за правилом: якщо Аi < Вi, то

Сi = Вi – Аi; інакше – Сi = Аi + Вi.

7. Задано масиви А і В по N = 11 елементів. Навести алгоритм та

програму сформування масиву С за правилом: якщо Аi ≤ Вi, то

Сi = Аi + Вi; інакше – Сi = Аi – Вi.

8. Задано масиви А і В по N = 12 елементів. Навести алгоритм та

програму сформування масиву С за правилом: якщо Аi ≤ Вi, то

Сi = Вi – Аi; інакше – Сi = Аi + Вi.

Тип 2

9. Задано масив А з N = 20 елементів. Навести алгоритм та програму

визначення кількості елементів масиву А, які задовольняють умові L <

Ai ≤ M, де L = 2 та M = 10.

Page 443: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

443

10. Задано масив А з N = 25 елементів. Навести алгоритм та програ-

му визначення кількості елементів масиву А, які задовольняють умові L

≤ Ai < M, де L = 3 та M = 15.

11. Задано масив А з N = 30 елементів. Навести алгоритм та програ-

му визначення кількості елементів масиву А, які задовольняють умові L

< Ai < M, де L = 4 та M = 18.

12. Задано масив А з N = 35 елементів. Навести алгоритм та програ-

му визначення кількості елементів масиву А, які задовольняють умові L

≤ Ai ≤ M, де L = 5 та M = 20.

13. Задано масив А з N = 40 елементів. Навести алгоритм та програ-

му визначення кількості елементів масиву А, які задовольняють умові L

≥ Ai > M, де L = 6 та M = 22.

14. Задано масив А з N = 45 елементів. Навести алгоритм та програ-

му визначення кількості елементів масиву А, які задовольняють умові L

> Ai ≥ M, де L = 7 та M = 24.

15. Задано масив А з N = 50 елементів. Навести алгоритм та програ-

му визначення кількості елементів масиву А, які задовольняють умові L

> Ai > M, де L = 8 та M = 28.

16. Задано масив А з N = 55 елементів. Навести алгоритм та програ-

му визначення кількості елементів масиву А, які задовольняють умові L

≥ Ai ≥ M, де L = 9 та M = 30.

Тип 3

17. Задано масив А з N = 30 елементів. Навести алгоритм та програ-

му сформування масиву В з перших 8 позитивних елементів масиву А.

18. Задано масив А з N = 40 елементів. Навести алгоритм та програ-

му сформування масиву В з перших 9 негативних елементів масиву А.

19. Задано масив А з N = 50 елементів. Навести алгоритм та програ-

му сформування масиву В з перших 10 елементів масиву А, які дорівню-

ють нулю.

20. Задано масив А з N = 25 елементів. Навести алгоритм та програ-

му сформування масиву В з останніх 11 позитивних елементів масиву А.

21. Задано масив А з N = 35 елементів. Навести алгоритм та програ-

му сформування масиву В з останніх 12 негативних елементів масиву А.

22. Задано масив А з N = 45 елементів. Навести алгоритм та програ-

му сформування масиву В з останніх 13 елементів масиву А, які дорів-

нюють нулю.

Page 444: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

444

Тип 4

23. Задано масив А з N = 22 елементів. Навести алгоритм та програ-

му сформування масиву В з елементів масиву А, які задовольняють умові

Аi > Е при Е = 5.

24. Задано масив А з N = 33 елементів. Навести алгоритм та програ-

му сформування масиву В з елементів масиву А, які задовольняють умові

Аi < Е при Е = 10.

25. Задано масив А з N = 44 елементів. Навести алгоритм та програ-

му сформування масиву В з елементів масиву А, які задовольняють умові

Аi ≥ Е при Е = 11.

26. Задано масив А з N = 55 елементів. Навести алгоритм та програ-

му сформування масиву В з елементів масиву А, які задовольняють умові

Аi ≤ Е при Е = 12.

Тип 5

27. Задано масив А з N = 40 елементів. Навести алгоритм та програ-

му визначення суми та кількості елементів масиву А, які задовольняють

умові Аi > Е при Е = – 10.

28. Задано масив А з N = 50 елементів. Навести алгоритм та програ-

му визначення суми та кількості елементів масиву А, які задовольняють

умові Аi ≥ Е при Е = – 11.

29. Задано масив А з N = 60 елементів. Навести алгоритм та програ-

му визначення суми та кількості елементів масиву А, які задовольняють

умові Аi < Е при Е = – 12.

30. Задано масив А з N = 70 елементів. Навести алгоритм та програ-

му визначення суми та кількості елементів масиву А, які задовольняють

умові Аi ≤ Е при Е = – 13.

Тип 6

31. Задано масиви А і В по N = 20 елементів. Навести алгоритм та

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

Аi > Ві.

32. Задано масиви А і В по N = 30 елементів. Навести алгоритм та

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

Аi ≥ Ві.

33. Задано масиви А і В по N = 40 елементів. Навести алгоритм та

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

Аi < Ві.

Page 445: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

445

34. Задано масиви А і В по N = 50 елементів. Навести алгоритм та

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

Аi ≤ Ві.

Тип 7

35. Задано масиви А і В по N = 30 елементів. Навести алгоритм та

програму сформування масиву С за правилом: якщо Аi + Вi > 0, то

Сj = Ві.

36. Задано масиви А і В по N = 35 елементів. Навести алгоритм та

програму сформування масиву С за правилом: якщо Аi + Вi ≥ 0, то

Сj = Ві.

37. Задано масиви А і В по N = 40 елементів. Навести алгоритм та

програму сформування масиву С за правилом: якщо Аi + Вi < 0, то

Сj = Ві.

38. Задано масиви А і В по N = 45 елементів. Навести алгоритм та

програму сформування масиву С за правилом: якщо Аi + Вi ≤ 0, то

Сj = Ві.

39. Задано масиви А і В по N = 50 елементів. Навести алгоритм та

програму сформування масиву С за правилом: якщо Аi – Вi > 0, то

Сj = Aі.

40. Задано масиви А і В по N = 55 елементів. Навести алгоритм та

програму сформування масиву С за правилом: якщо Аi – Вi ≥ 0, то

Сj = Aі.

41. Задано масиви А і В по N = 60 елементів. Навести алгоритм та

програму сформування масиву С за правилом: якщо Аi – Вi < 0, то

Сj = Aі.

42. Задано масиви А і В по N = 65 елементів. Навести алгоритм та

програму сформування масиву С за правилом: якщо Аi – Вi ≤ 0, то

Сj = Aі.

Тип 8

43. Задано масив А з N = 20 елементів. Навести алгоритм та програ-

му визначення мінімального з позитивних елементів масиву А.

44. Задано масив А з N = 30 елементів. Навести алгоритм та програ-

му визначення мінімального з негативних елементів масиву А.

45. Задано масив А з N = 40 елементів. Навести алгоритм та програ-

му визначення максимального з позитивних елементів масиву А.

Page 446: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

446

46. Задано масив А з N = 50 елементів. Навести алгоритм та програ-

му визначення максимального з негативних елементів масиву А.

Тип 9

47. Задано масив А з N = 80 елементів. Структура масиву

А: X1,Y1;X2,Y2; … . Навести алгоритм та програму визначення кількості

пар, для яких виконується умова Хi > Yi.

48. Задано масив А з N = 70 елементів. Структура масиву

А: X1,Y1;X2,Y2; … . Навести алгоритм та програму визначення кількості

пар, для яких виконується умова Хi ≤ Yi.

49. Задано масив А з N = 60 елементів. Структура масиву А:

X1,Y1;X2,Y2; … . Навести алгоритм та програму визначення кількості

пар, для яких виконується умова Хi = Yi.

50. Задано масив А з N = 50 елементів. Структура масиву А:

X1,Y1;X2,Y2; … . Навести алгоритм та програму визначення кількості

пар, для яких виконується умова Хi < Yi.

Тип 10

51. Задано масив А з N = 40 елементів. Навести алгоритм та програ-

му визначення суми елементів масиву А, для яких біти 2 та 10 збігають-

ся.

52. Задано масив А з N = 35 елементів. Навести алгоритм та програ-

му визначення суми елементів масиву А, для яких біти 3 та 12 збігають-

ся.

53. Задано масиви А і В по N = 30 елементів. Навести алгоритм та

програму сформування масиву С за правилом: якщо у елементів Аі та Ві

біти 4 та 9 збігаються, то Сі = Аi + Вi.

54. Задано масив А з N = 28 елементів. Навести алгоритм та програ-

му формування масиву В з елементів масиву А, у яких 0, 2 та 5 біти ма-

ють нулі.

Page 447: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

447

ЛІТЕРАТУРА

1. Главчев М.І., Клименко А.М., Рисований О.М., Філоненко А.М./

За ред. О.М. Рисованого: Цифрові пристрої та мікропроцесори. Органі-

зація та програмування: Навч. посіб. – Х.: ХВУ, 2001. – 327 с.

2. Григорьев В.Л. Программирование однокристальных микропро-

цессоров. – М.: Энергоатомиздат, 1987. – 288 с.

3. Гук М., Юров В. Процессоры Pentium 4, Athlon и Duron. – СПб.:

Питер, 2001. – 512 с.

4. Зубков С.В. Assemler для DOS, Windows и Unix . – М.: ДМК

Пресс; СПб.: Питер, 2006. – 608 с..

5. Ирвин Кип. Язык ассемблера для процессоров Intel, 3-е издание.:

Пер. с англ. – М.: Издат. дом “Вильямс”, 2002. – 616 с.

6. Моделі та структури даних у системах автоматизованого керу-

вання/ Фурман І.О., Краснобаєв В.А., Далека В.Д., Корольова Н.А., Ри-

сований О.М.: Підручник для ВНЗ. – К., 2004. – 253 с.

7. Микропроцессоры и микропроцессорные системы. Кн. 1: Архи-

тектура и функционирование/ Кравец В.А., Рысованый А.Н., Домнин

Ф.А., Зыков И.С., Скороделов В.В., Шеин А.Н.: Учеб. пособ. –Х.: ХВУ,

2000. – 282 с.

8. Микропроцессоры и микропроцессорные системы. Кн. 2: Про-

граммирование, разработка устройств и систем. Кравец В.А., Дом-

нин Ф.А., Скороделов В.В., Зиков И.С., Рысованый А.Н.: Учеб. пособ. –

ХВУ, 2000. – 350 с.

9. Мікропроцесорні пристрої. Проектування тестових програм вуз-

лів персонального комп’ютера/За ред. В.О. Кравця, О.М. Рисованого:

Навч. посіб. – Х.: ХВУ, 2001. – 226 с.

10. Пирогов В.Ю. Ассемблер под Windows. – СПб.: БХВ-Петербург,

2003.

11. Пирогов В.Ю. Ассемблер. Учебный курс. – СПб.: БХВ-

Петербург, 2003.

12. Подбельский В.В. Язык С++: Учеб. пособ. – М.: Финансы и ста-

тистика, 2004.

Page 448: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

448

13. Проектування тестових програм вузлів персонального

комп’ютера. Кравець В.О., Колибін Ю.М., Качанов П.О., Домнін І.Ф.,

Заполовський М.Й., Рисований О.М./ За ред. В.О. Кравця,

О.М. Рисованого: Навч. посіб. – Х.: НТУ “ХПІ”, 2001. – 225 с.

14. Рудаков П.И., Финогенов К.Г. Программируем на языке асемб-

лера IBM PC: В 4-х частях – М.: Энтрон, 1995. – 164 с.

15. Рисований О.М., Кавун С.В., Грушенко М.В., Калачова В.В.,

Осієвський С.В. Комп’ютерні системи / За ред. М.Ф. Пічугіна: Навч.

посіб. – МОУ, Х.: ХУПС, 2005. – 328 с.

16. Рисований О.М., Грушенко М.В. Цифрові пристрої і мікропро-

цесори. Архітектура і програмне забезпечення: Навч. посіб. – Х.: ХУПС,

2005. – 384 с.

17. Рогожина С.І., Рисований О.М., Федорченко В.М. Системне

програмування та операційні системи. Частина II. Навч. посіб. – Х.:

ХУПС, 2007 р. – 200 с.

18. Цифрові пристрої та мікропроцесори. Організація та функціону-

вання / За ред. О.М. Рисованого: Навч. посіб. – Х.: ХВУ, 2002. – 328с.

19. Юров В. ASSEMBLER: Практикум – СПб.: Питер, 2001.

20. Юров В. ASSEMBLER: Спец. Справочник. – СПб.: Питер, 2004.

21. Юров В. ASSEMBLER: Учебник – СПб.: ПИТЕР, 2004.

Page 449: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

449

Навчальне видання

КРАВЕЦЬ Валерій Олексійович

РИСОВАНИЙ Олександр Миколайович

Системне програмування

Програмування на мові асемблеру

Навчальний посібник

Роботу до видання рекомендував В.Д. Дмитрієнко

Редактори В.М. Баранов

Л.Л. Яковлева

План 2007 р., поз. №1/ Підписано до друку .07. Формат 60х84 1/16. Папір офсет.№2. Друк – ризографія. Гарнітура Times New Roman. Ум. друк. арк. 23,5. Обл.-вид. арк. 25,8. Наклад 100 прим. Зам №. Ціна договірна.

Видавничий центр НТУ’’ХПІ’’61002, Харків, вул. Фрунзе, 21. Свідоцтво про державну реєстрацію ДК № 116 від 10.07.2000 р.

Друкарня НТУ’’ХПІ’’. 61002, Харків, вул. Фрунзе, 21.

Page 450: МІНІСТЕРСТВО ОБОРОНИ УКРАЇНИblogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/2015/12/SP...Масиви ..... 230 8.1.1. Загальні відомості

450