514

Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів
Page 2: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

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

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

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

СИСТЕМНЕ

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

Асемблер під Win32 API

Рекомендовано Міністерством освіти і науки України як навчальний посібник для студентів вищих навчальних закладів напрямку

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

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

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 3: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

2

ББК 32.973-018.1 Р54 УДК 004.42

Рецензенти:

І.О. Фурман, д-р техн. наук, проф., академік АН Вищої школи України, Харківський національний технічний університет

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

Г.Ф. Кривуля, д-р техн. наук, проф., Харківський державний технічний університет радіоелектроніки;

Г.І. Загарій, д-р техн. наук, проф., Українська державна академія

залізничного транспорту.

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

Рисований О.М.

Р54 Кравець В.О., Рисований О.М. Системне програмування. Асемблер під Win32 API. Навч. посібник. – Х.: НТУ “ХПІ”, 2008. – 512 с.

ISBN 978-966-593-548-7

Розглянуто широке коло питань, починаючи з основ програмування на асемблері з використанням базової системи команд та закінчуючи використан-ням сучасних технологій обробки даних, таких, як ММХ, SSE, SSE2, SSE3. Тео-ретичний матеріал підкріплено багатою кількістю прикладів програмного коду від самих коротких програм до програм середньої складності. Всі програми про-тестовані за допомогою налагоджувача OllyDbg.

Призначено для студентів спеціальностей: 7.091501 “Комп’ютерні системи та мережі”, 7.091502 “Системне програмування”, 7.091503 “Спеціалізовані комп’ютерні системи”. Також може бути корисним для спеціалістів.

Іл. 163. Табл. 36. Бібліогр. 27 назв.

ББК 32.973-018.1 ISBN 978-966-593-7 © В.О. Кравець, О.М. Рисований, 2008

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 4: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

3

ЗМІСТ

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

1.1. Типи даних МП PENTIUM ........................................................... 11 1.2. Регістри МП PENTIUM ................................................................ 14 1.3. Організація пам’яті МП PENTIUM .............................................. 24 1.4. Способи адресації МП Intel .......................................................... 33

2. ЕТАПИ СТВОРЕННЯ ПРОГРАМИ НА МОВІ АСЕМБЛЕРУ . 47

2.1. Підготовка тексту програми .......................................................... 47 2.2. Асемблювання програми ................................................................ 48 2.3. Компонування програми ................................................................ 49 2.4. Налагодження програми ................................................................ 52

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

3.1. Директиви асемблеру ........................................................................... 53 3.1.1. Директиви MODEL, DATA, CONST, STACK, CODE .......... 53 3.1.2. Директиви SEGMENT та ENDS ......................................... 56 3.1.3. Директиви PROC та ENDP ................................................... 58 3.1.4. Директива ASSUME .............................................................. 58 3.1.5. Директива ORG .................................................................. 59 3.1.6. Директиви визначення даних DB, DW, DD, DF, DP, DQ, DT ......................................................................................... 59 3.1.7. Директиви символьних констант: = , EQU, TEXTEQU ....... 61 3.1.8. Директива END .................................................................... 63 3.1.9. Директива LABEL ..................................................................... 63

3.2. Оператори мови асемблеру ............................................................. 63 3.3. Лабораторна робота “Подання даних” ......................................... 68

4. ОПЕРАЦІЇ ПЕРЕСИЛАННЯ ДАНИХ ........................................... 79

4.1. Команди пересилання даних загального призначення ................ 79 4.2. Організація роботи зі стеком ......................................................... 83 4.3. Команди пересилання, що працюють з акумулятором ............... 88 4.4. Команди пересилання бітів умов .................................................. 92

5. АРИФМЕТИЧНІ ТА ЛОГІЧНІ ОПЕРАЦІЇ ................................. 95

Page 5: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

4

5.1. Арифметичні операції ..................................................................... 95 5.2. Логічні операції .............................................................................. 118 5.3. Лабораторна робота “Програмування арифметичних виразів” . 123

6. ОРГАНІЗАЦІЯ РОЗГАЛУЖЕНЬ В ПРОГРАМАХ ..................... 134

6.1. Команди обробки бітів та байтів .................................................. 134 6.2. Команди передачі керування ......................................................... 136

7. ПРОЦЕДУРИ ..................................................................................... 155

7.1. Організація процедур та їх дослідження ..................................... 155 7.2. Windows АРІ-подібні процедури ................................................. 163 7.3. Непрямий виклик процедур ......................................................... 165 7.4. Використання загальних змінних у процедурах ......................... 170 7.5. Лабораторна робота “Передача параметрів через таблицю адресів” ........................................................................ 185 7.6. Лабораторна робота “API-подібні процедури ” .......................... 188 7.7. Лабораторна робота “Зовнішні процедури” ............................... 190

8. ОРГАНІЗАЦІЯ ВВЕДЕННЯ – ВИВЕДЕННЯ В WIN32 ............. 200

8.1. Загальні відомості ........................................................................ 200 8.2. Набір символів і функції Windows API ....................................... 202 8.3. Типи даних Windows ..................................................................... 203 8.4. Дескриптори консолі ..................................................................... 204 8.5. Функції консолі Win32 ................................................................. 205 8.6. Виведення повідомлень ................................................................ 209 8.7. Виведення чисел ............................................................................ 217 8.8. Введення з консолі ........................................................................ 225 8.9. Лабораторна робота “Масиви” ..................................................... 228

9. РЯДКИ ................................................................................................ 232

9.1. Обробка рядків .............................................................................. 232 9.2. Лабораторна робота “Рядки” ........................................................ 251

10. ЛОГІЧНІ СТРУКТУРИ ВИСОКОГО РІВНЯ ........................... 254

10.1. Директива IF ............................................................................... 254 10.2. Логічні структури .REPEAT та .WHILE .............................. 263 10.3. Лабораторна робота “Директиви умовного асемблювання” ... 270 10.4. Лабораторна робота “Двовимірні масиви” ............................... 277

Page 6: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

5

11. МАКРОВИЗНАЧЕННЯ ................................................................. 279 11.1. Введення в макровизначення ..................................................... 279 11.2. Булеві вирази ............................................................................... 282 11.3. Оператори в макровизначеннях ................................................. 286 11.4. Оператор заміни .......................................................................... 287 11.5. Оператор виразу .......................................................................... 289 11.6. Оператор виділення тексту ........................................................ 290 11.7. Оператор виділення символу ..................................................... 291 11.8. Додаткові макровизначення і директиви .................................. 291 11.9. Лабораторна робота “Макроси” ................................................ 295

12. ФАЙЛИ ............................................................................................. 301

12.1. Створення файлів ........................................................................ 301 12.2. Лабораторна робота “Файли” ................................................... 306

13. СТРУКТУРИ ................................................................................... 309 13.1. Організація структур ..................................................................... 309 13.2. Лабораторна робота “Структури” ................................................ 314 14. ДИНАМІЧНІ БІБЛІОТЕКИ ......................................................... 319 14.1. Створення динамічних бібліотек та їх використання ................. 319 14.2. Угорська нотація ............................................................................ 323 14.3. Лабораторна робота “Dll-файли” ................................................. 324 15. СПІВПРОЦЕСОР ТА ЙОГО ВИКОРИСТАННЯ ..................... 326

15.1. Типи даних співпроцесора ......................................................... 327 15.2. Архітектура співпроцесора ........................................................ 328 15.3. Система команд математичного співпроцесора ....................... 332

15.3.1. Команди передачі даних ....................................................... 333 15.3.2. Команди порівняння ............................................................. 337 15.3.3. Арифметичні команди .......................................................... 345 15.3.4. Трансцендентні команди ...................................................... 361 15.3.5. Команди маніпуляції константами ...................................... 364 15.3.6. Команди керування ............................................................... 365

15.4. Лабораторна робота “Обробка даних у співпроцесорі” .......... 366 16. ММХ-РОЗШИРЕННЯ .................................................................... 372

16.1. ММХ-команди передачі даних .................................................. 374

Page 7: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

6

16.2. Арифметичні ММХ-команди ..................................................... 376 16.2.1. Команди додавання ............................................................... 376 16.2.2. Команди віднімання .............................................................. 383 16.2.3. Команди множення ................................................................ 386

16.3. ММХ-команди пакування та розпакування даних ................... 387 16.4. ММХ-команди порівняння ......................................................... 395 16.5. Логічні ММХ-команди ............................................................... 398 16.6. Команди зсуву ............................................................................. 398 16.7. ММХ-команди в Pentium ІІІ ....................................................... 401 16.8. ММХ-команди в Pentium IV ....................................................... 403 16.9. Лабораторна робота “ММХ-команди” ...................................... 405

17. SSE-РОЗШИРЕННЯ ....................................................................... 418

17.1. Команди пересилання даних ...................................................... 421 17.2. Арифметичні команди ................................................................ 426

17.2.1. Команди додавання ............................................................... 426 17.2.2. Команди віднімання .............................................................. 427 17.2.3. Команди паралельного і скалярного множення .................. 429 17.2.4. Команди паралельного і скалярного ділення ...................... 430 17.2.5. Додаткові арифметичні команди .......................................... 431

17.3. Команди порівняння ................................................................... 435 17.4. Команди перетворення ............................................................... 441 17.5. Логічні команди ........................................................................... 443 17.6. Команди керування станом ........................................................ 445 17.7. Команди розпаковування даних ................................................. 446 17.8. Команди керування кешуванням ............................................... 448 17.9. Лабораторна робота “SSE-команди” ......................................... 449

18. SSE2-РОЗШИРЕННЯ ..................................................................... 452

18.1. Команди передавання даних ...................................................... 455 18.1.1. Обмін 128-bit кодами між оперативною пам’яттю (ОЗП) та регістрами xmm ..................................................................... 455 18.1.2. Обмін 64-розрядними кодами між ОЗП і регістрами xmm ....................................................................... 455 18.1.3. Використання масок ............................................................. 456

18.2. Арифметичні операції ................................................................. 457 18.2.1. Паралельні операції з упакованими числами ...................... 457 18.2.2. Арифметичні операції зі скалярними числами ................... 459

18.3. Команди порівняння ................................................................... 461

Page 8: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

7

18.3.1. Порівняння без зміни стану розрядів EFLAGS ................ 461 18.3.2. Команди порівняння, які змінюють регістр EFLAGS ...... 462

18.4. Логічні операції ........................................................................... 463 18.5. Команди розпаковування і розподілення даних ...................... 464 18.6. Команди перетворення форматів даних ................................... 465

18.6.1. Групові перетворення форматів даних ............................... 465 18.6.2. Перетворення формату одного числа .................................. 468

18.7. Керуванням кешем ..................................................................... 469 18.8. Операції з цілими числами. Нові можливості інструкцій MMX ..................................................... 470 18.9. Лабораторна робота “SSE2-команди” ...................................... 471

19. SSE3-РОЗШИРЕННЯ .................................................................... 473 19.1. Перетворення чисел з плаваючою крапкою (x87) в цілі числа 473 19.2. Дублювання даних ...................................................................... 473 19.3. Завантаження невирівняних змінних ........................................ 474 19.4. Одночасне додавання/віднімання .............................................. 474 19.5. Горизонтальне додавання/віднімання ....................................... 475 19.6. Синхронізація потоків ................................................................ 476 19.7. Використання SSE3 в розробці і оптимізації програм ............ 477

19.7.1. Розрахункові завдання, що використовують x87 FPU ....... 477 19.7.2. Обчислення з комплексними числами ................................ 479 19.7.3. Кодування відео .................................................................... 479 19.7.4. Векторні операції .................................................................. 480

20. ОСНОВИ СТВОРЕННЯ ВІКНА ОС WINDOWS ..................... 481

20.1. Створення вікна ........................................................................... 481 20.2. Обробка повідомлень .................................................................. 485 20.3. Перемалювання вікна .................................................................. 487 20.4. Меню ............................................................................................. 491 20.5. Управління кольором .................................................................. 495

ДОДАТКИ .............................................................................................. 497 Додаток 1. Система базових команд МП платформи х86 ................... 497 Додаток 2. API-функції, які часто використовуються ......................... 507 ЛІТЕРАТУРА ........................................................................................ 510

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 9: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

8

ВСТУП

Цей навчальний посібник призначений, в основному, для початку-ючих фахівців, які вирішили залучитися до програмування на мові асе-мблеру. При написанні цього навчального посібника ураховувалося те, що питаннями системного програмування в НТУ “ХПІ” студенти зай-маються за такими навчальними дисциплінами: “Системне програму-вання”, “Системне програмне забезпечення” та “Операційні системи”. Тому знання, які студенти отримують з дисципліни “Системне програ-мування”, є базовими для наступних дисциплін з системного програму-вання. Прочитавши цей посібник і обов’язково перепробувавши наведе-ні в ньому програми на комп’ютері, ви неодмінно навчитеся програму-вати на дивовижній мові асемблеру.

Ця мова програмування з’явилася однією з перших. Але скільки би мов високого рівня не виникло після неї та скільки ще не з’явилося в майбутньому, їх доля вирішена наперед, ще до їх появи. Всі вони ко-лись зникнуть. Але тільки не мова асемблеру. Через своє призначення вона не зникне доти, поки існуватимуть комп’ютери. Найголовнішим аргументом переконання в цьому є те, що будь-яка програма, яка напи-сана на мові високого рівня, має виконуваний файл. Проте всі виконува-ні файли для свого вирішення були отримані шляхом перетворення ко-манд мови високого рівня в машинні команди (коди), які у свою чергу і є командами мови асемблеру. І тому якщо в якійсь мові високого рівня з’являються нові можливості щодо обробки чисел, то засоби для такої можливості вже повинні бути раніше закладені в асемблері. І поки такі можливості не будуть закладені в асемблері, то і не удосконалювати-муться інші мови. Тому мова асемблеру постійно удосконалюється. А якщо фахівець вивчав мову асемблеру 7 – 10 років т ому, т о мож на ст вердж уват и, що т акий програміст вж е не знає її, т ому що за цей час з’явилося т ак багат о нових наборів команд, що вони майж е пов-ніст ю змінили знання про асемблер.

Екскурс в історію

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

Потім були реалізовані система команд SIMD і технологія Intel® MMX™. Система команд SIMD використовувалася корпорацією Intel для збільшення рівня паралелізму при обробці цілочисельних даних в

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 10: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

9

мікроархітектурі P5 (січень 1997 р.) за допомогою застосування спеціа-льних команд (57 команд на першому етапі). Використовуючи набір ко-манд технології Intel MMX, програмісти могли виконувати команди для декількох елементів даних, завантажених в регістри MMX (виконаних на основі стека співпроцесора), що забезпечувало підвищення продук-тивності мультимедійних застосувань, зокрема додатків для роботи з графікою, ігор, потокового відео і так далі.

У мікроархітектурі P6 корпорація Intel ввела набір команд Streaming SIMD Extensions (SSE) на основі нових регістрів XMM0-XMM7. Набір команд SSE, розроблений для процесора Intel® Pentium® III (початок 1999 р.), розширював можливості технології Intel MMX і дозволяв одночасно виконувати обчислення SIMD з чотирма елементами даних з плаваючою комою з одинарною точністю, викорис-товуючи 128-розрядні регістри (назва XMM0-XMM7).

З мікроархітектурою Intel Netburst® (процесор Intel® Pentium® 4) корпорація Intel ввела набір команд SSE2 (червень 2000 р.) для розши-рення набору команд SSE (і технології Intel MMX). Набір команд SSE2 забезпечив можливість паралельно виконувати більше обчислень, роз-ширюючи команди, введені в технології Intel MMX і набір команд SSE, та забезпечуючи підтримку 128-розрядних типів даних цілих чисел і упакованих чисел з плаваючою комою з подвійною точністю. У набір команд SSE2 були додані 144 нові команди, що забезпечило підвищення продуктивності різноманітних застосувань. Вважаємо за необхідне нага-дати, що перший набір так званих базових команд теж містив всього лише 144 команди.

Після випуску процесора Intel® Pentium® 4 на базі 90-нанометрової виробничої технології був розроблений набір команд SSE3. У початковий набір команд SSE3 (І. 2004 р.) входило 13 додаткових команд SIMD. Ці команди перш за все направлені на поліпшення синхронізації потоків і розширення можливостей математичних операцій x87 і операцій з плава-ючою комою.

Наступний крок був зроблений із створенням додаткового набору команд SSE3, який реалізований сьогодні в мікроархітектурі Intel® Core™. Додатковий набір команд SSE3, використовуваний в процесорах Intel® Xeon® 5100 (для серверів і робочих станцій) і Intel® Core™2 Duo (для мобільних і настільних ПК), додає 32 нових коди операцій, вклю-чаючи операції приведення у відповідність, множення і складання, що забезпечує ще більшу продуктивність.

Корпорація Intel для архітектури Intel® 64 (ISA), починаючи з мік-

Page 11: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

10

ропроцесора Core 2 Duo E6700 та корпорація AMD для МП Phenom 9600+, впровадили новий набор команд SSE4 який включає компоненти, що дозволяють використовувати розширені функціональні можливості, підвищену продуктивність і покращувану енергоекономічність для бі-льшості додатків, а також технологію EM64T.

Не можна забувати і про те, що з постійним введенням нових ко-манд не затихають роботи, які спрямовані на удосконалення модульнос-ті асемблера. З’явилися АРI-функції та програмування під 32-розрядну операційну систему Windows. Тому програмування під 16-розрядні до-дат ки MS-DOS є не т ільки архаїчним правилом, але й правилом “по-ганого т ону”, яке, звичайно, мож на виправдовуват и, але т ільки ... ледарст вом розуму.

Природно що у мови асемблеру є й недоліки. Головним її недолі-ком є те, що програма, написана для одного типу комп’ютерів, не може бути перекомпільована і використана на інших типах комп’ютерів [22]. Для кожного сімейства процесорів використовується своя мова асембле-ру зі своїм синтаксисом. Це є наслідком того, що мова асемблеру дуже близька до машинних команд і до архітектури мікропроцесора. Тому, щоб глибше зрозуміти архітектуру мікропроцесора, без мови асемблеру не обійтися.

Крім того, ніхто вже не пише великі закінчені програми на “чисто-му” асемблері. Це – безумство. Хоча треба визнати, що це безумство від великого розуму. Перед програмістами, що створюють такі програми, треба схилятися, бо теоретично, ці програми повинні бути ідеальними: найменшими за об’ємом і найбільш швидкодіючими. На практиці ж, великі за об’ємом програми пишуться на мові високого рівня з асембле-рними вставками для критичних ділянок коду. Навіть коли програма середньої складності написана на мові високого рівня, то все одно, бі-льшість бібліотечних функцій, що входять в Visual C++ чи Delphi, які були підключені, написані на асемблері. А паралельні обчислення, які засновані на технології SIMD, написані тільки з використанням сучас-них асемблерних команд.

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

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

Page 12: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

11

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

Успішне застосування мови асемблеру неможливе без знання архі-тектури процесорів Intel.

Під архітектурою мікропроцесорних систем (МПС) мають на увазі функціональні можливості комплексу апаратних, програмних і мікропрограмних засобів, які використовуються для подання даних, ма-шинних операцій, описання алгоритмів та процесів обчислення.

Елементами архітектури є: типи оброблюваних даних та засоби їх подання; структури пам’яті та засоби їх адресації; структури та системи команд (мікрокоманд); структури мікропроцесорів (МП) та їх програмні моделі. 32-розрядні процесори можуть оперувати з 8-, 16- і 32-бітовими

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

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

1.1. Типи даних МП PENTIUM

32-розрядні процесори безпосередньо підтримують знакові і без-

знакові цілі числа, рядки байтів, цифр і символів, бітові рядки, вказівни-ки і числа з плаваючою точкою. У сімействі х86 слова прийнято запису-вати в двох суміжних байтах пам’яті, починаючи з молодшого [2, 11 – 14]. Адресою слова є адреса його молодшого байта. Подвійні слова записують в чотирьох суміжних байтах. Цей порядок називається Little-Endian Memory Format. В інших сімействах процесорів застосовують і зворотний порядок – Big-Endian Memory Format. Для взаємного перет-ворення форматів слова є інструкція XCHG, подвійного слова – BSWAP (486+).

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 13: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

12

Біт (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). Одиничне значення найстаршого біта (знак) є ознакою від’ємного числа, що зберігається в додатному коді.

Двійково-десяткові числа (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 (потокові інструкції).

Page 14: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

13

Дійсні числа у форматі з плаваючою точкою: одинарної точності (Single Precision), 32 біт – 23 біт мантиса,

8 біт порядок; подвійної точності (Double Precision), 64 біт – 52 біт манти-

са, 11 біт порядок; підвищеної точності (Extended Precision), 80 біт – 64 біт манти-

са, 15 біт порядок. Двійково-десяткові 80-бітові упаковані числа (18 десяткових ро-

зрядів і знак). Упаковані дійсні числа одинарної точності у форматі з плаваю-

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

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

ММХ: • упаковані байти (Packed byte) – вісім байтів; • упаковані слова (Packed word) – чотири слова; • упаковані подвійні слова (Packed doubleword) – два подвійних

слова; • збільшене у 4 рази слово (Quadword) – одне слово. 32-розрядні процесори платформи х86 мають регістри: • регістри загального призначення; • вказівник інструкцій; • регістр прапорців; • регістри сегментів; • системні адресні регістри; • керуючі регістри; • регістри налагодження; • регістри тестування; • модельно-специфічні (залежні від конкретної моделі процесора)

регістри. Типи даних, які обробляються блоками FPU/MMX та XMM, наведе-

но на рис. 1.1 [24 – 27].

Page 15: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

14

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

Основні регістри процесора архітектури IA-32, з якими працюють

прикладні програми, показано на рис. 1.2. Ці регістри відносяться до видимої для прикладних програм части-

ни архітектури х86 і являють собою розширення набору регістрів 16-розрядних процесорів 8086/8088 і 80286 [4].

У 32-розрядних процесорів регістри загального призначення ЕAX, ЕBX, ЕCX, ЕDX складаються з двох 16-бітових половинок, молодша з яких теж ділиться на дві половинки. До них можна незалежно звертати-

Рис. 1.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 Число 2 Число 3 63

Упаковані слова для ММХ

0

0

Число Збільшене у 4 рази слово для ММХ

63 0

Мантиса Порядок Мантиса Порядок Мантиса Порядок Мантиса Порядок

Упаковані числа одинарної точності для ХММ 22 31 127 0

Число 1

Page 16: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

15

ся за символічними іменами АН, ВН, СН, DH (старші байти – High) і AL, BL, CL, DL (молодші байти – Low).

Регістри- вказівники ESP (Stack Pointer – вказівник стека), EВР

(Base Pointer – базовий регістр або вказівник бази) та індексні регістри ESI (Source Index – індекс джерела), EDI (Destination Index – індекс при-значення) допускають 32-розрядне звертання.

Адреса поточної інструкції зберігається в 32-бітовому вказівнику команд ЕІP (Instruction Pointer).

Регістри в командах можуть адресуватись явно. У ряді команд іс-нує неявне використання регістрів:

ЕАХ – множення, ділення, введення і виведення двійного слова; АХ – множення, ділення, введення і виведення слова; AL – множення, ділення, введення і виведення байта; десяткова

арифметика, трансляція (XLAT); АН – множення і ділення байта; ЕBX – трансляція; ЕCX – лічильник циклів і вказівник довжини рядкових опера-

цій; CL – зміщення з указанням змінної; ЕDX – множення і ділення слова, введення і виведення з не-

прямою адресацією; SP – операції зі стеком; ЕSI, ЕDI – рядкові операції.

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

Рис. 1.2. Загальні Рг 32-розрядного МП

Page 17: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

16

У процесорах IA-32 всі ці регістри мають приставку Е (Extended – розширений). Відсутність приставки в імені означає посилання на моло-дші 16 біт розширених регістрів [18, 20 – 21].

У реальному режимі за замовчуванням розрядність адреси і да-них – 16 біт.

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

Вказівник інструкцій EIP містить зміщення наступної інструкції,

що виконується, щодо бази сегмента коду. При 16-бітовій адресації ви-користовуються тільки молодші 16 біт (IP).

Регістр прапорців EFLAGS є розширенням регістра FLAGS до 32 бітів (рис. 1.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

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

Рис. 1.3. Регістр прапорців EFLAGS (x – системний прапорець,

s – прапорець стану, с – керуючий прапорець) Біти 0 – 15, визначені для 8086 і 80286, мають колишнє призначен-

ня. Прапорці стану OF, SF, ZF, AF, PF і CF зберігають ознаки резуль-татів виконання арифметичних і логічних операцій над операндами, ро-зміщеними в регістрах загального призначення й у пам’яті. Операції пересилання даних на прапорці стану не впливають. Значення цих прапорців аналізується при виконанні умовних інструкцій. Крім прапо-рців стану в регістрі є керуючі та системні прапорці, що впливають на поведінку процесора, у тому числі на обробку маскованих апаратних переривань (IF) і на напрямок руху в рядкових операціях (DF). Прапорці стану можуть бути скопійовані в регістр АН і, навпаки, завантажені з нього. Крім того, прапорці стану можуть бути завантажені з блока FPU, і тоді результати виконання інструкцій у FPU можна використовувати в умовних інструкціях.

Призначення бітів регістра EFLAGS: • ID (Id Flag) – прапорець доступності команди ідентифікації

CPUID (P5+ і деякі 486).

Page 18: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

17

• 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. Біт VM може вста-новлюватися тільки в захищеному режимі (інструкцією IRET на нульо-вому рівні чи привілеїв переключенням задач на будь-якому рівні приві-леїв). На біт VM не діє інструкція POPF, а інструкція PUSHF у цей біт завжди заносить 0. Одиничне значення біту VM може зберегтися тільки в EFLAGS, яке встановлюється при перериванні, переключенні задач чи переході в режим SMM.

• RF (Resume Flag) – прапорець поновлення. Використовується ра-зом з регістрами точкою зупину.

• IOPL (Input/Output Privilege Level) – рівень привілеїв введення-виведення.

• NT (N sted Task Flag) – прапорець вкладеної задачі. • OF (Overflow Flag) – прапорець переповнення. Встановлюється,

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

• DF (Direction Flag) – прапорець керування напрямком у рядкових операціях. При одиничному значенні цього біту індексні регістри, що беруть участь у рядкових операціях, автоматично декрементуються на кількість байтів операнда, при нульовому – інкрементуються. Прапорець керування програмно змінюється інструкціями CLD і STD.

• IF (Interrupt-enable Flag) – прапорець керування перериваннями. При одиничному значенні біту IF дозволяється виконання маскованих апаратних переривань. На цей прапорець можна впливати програмно, явними інструкціями (CLI і STI) і неявними інструкціями відновлення регістра прапорців; процесор при обробці переривань маніпулює прапо-рцем автоматично. У захищеному режимі з’являються додаткові тонко-щі.

Page 19: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

18

• 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-розрядних процесорах не було. Вміст сегментних регістрів не може бути модифікованим (збі-льшеним чи зменшеним), вони допускають лише завантаження і збере-ження вмісту.

Використання сегментних регістрів визначається типом звертання до пам’яті. Для багатьох типів звертань можливе застосування альтерна-тивних сегментних регістрів, що вводяться префіксами команд CS:, SS:, DS:, ES: FS: чи GS:. З кожним із шести сегментних регістрів зв’язані програмно-недоступні сховані регістри дескрипторів (їх ще на-зивають Segment Descriptor Cache – кеш сегментних регістрів), які зава-нтажуються автоматично при завантаженні відповідних сегментних ре-гістрів.

У захищеному режимі в регістри дескрипторів з таблиці дескрип-торів завантажуються 32-бітова базова адреса, 32-бітовий ліміт (розмір сегмента) і атрибути сегментів. За вмістом цих схованих регістрів при кожному звертанні до пам’яті виконуються обчислення лінійної адреси і перевірка захисту; причому саме ці регістри задають властивості сегме-нтів як у захищеному, так і в реальному режимах. Образ цих 96-бітових регістрів доступний у режимах SMM і внутрішньосхемної емуляції

Page 20: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

19

(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. Скидання біта РЕ є части-ною досить довгої послідовності інструкцій, що підготовляють коректне переключення процесора в реальний режим.

• МР (Monitor Processor Extension) – моніторинг співпроцесора. Дозволяє викликати виключення #NM за кожною командою WAIT при TS = 1. При виконанні програм для процесорів 286 і вище біт МР пови-нен бути встановлений.

• ЕМ (Processor Extension Emulated) – емуляція співпроцесора. Встановлення цього прапорця викликає появу виключення #NM при ко-жній команді, що відноситься до співпроцесора, який дозволяє прозоро здійснювати його програмну емуляцію.

• TS (Task Switch) – переключення задач. При встановленні цього прапорця наступна команда, що відноситься до співпроцесора, викликає виключення #NM, яке дозволяє програмно визначити, чи відноситься контекст співпроцесора до поточної задачі. Біт скидається інструкцією CLTS.

Page 21: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

20

Поєднання МР = 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-бітову лінійну

адресу, за якою була отримана остання відмова сторінки пам’яті. Регістр CR3 (Page Directory Base Register) у старших 20 бітах збе-

рігає фізичну базову адресу таблиці каталогу сторінок. З молодших 12 бітів у процесорах 486+ використовуються такі:

• PCD (Page-Level Cache Disable) – заборона кешування сторінки (одне з джерел апаратного сигналу PCD для керуваня зовнішнім ке-шем).

• PWT (Page-Level Writes Trough) – кешування сторінки з на-скрізним записом (одне з джерел апаратного сигналу PWT для керу-вання зовнішнім кешем).

Регістр CR4 (є присутнім у процесорах Pentium і вище) містить

біти дозволу архітектурних розширень. Призначення бітів регістра CR4:

Page 22: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

21

• 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-бітовий ліміт глобальної таблиці дескрипторів і таблиці дескрипторів перери-вань. У регістр задачі TR (Task Register) і регістр селектора локальної таблиці дескрипторів LDTR (Local Descriptor Table Register) завантажу-ються 16-бітові селектори дескрипторів сегмента стану задачі TSS і ло-кальної таблиці дескрипторів LDT. Це завантаження викликає автомати-чне завантаження самих дескрипторів, що містять 32-бітові поля ліній-ної базової адреси і ліміту, а також полів атрибутів у зв’язані з ними не-видимі регістри дескрипторів.

Page 23: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

22

Регістри налагодження (Debug Register) призначені для задання і керування точками зупину.

Регістри 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) – регістр даних для тесту кешу-вання сторінок.

У процесорах Pentium і вище тестові регістри входять до групи мо-дельно-специфічних регістрів MSR. Для цих процесорів звертання до регістрів TRx викликає виключення #UD неприпустимого коду операції.

Модельно-специфічні регістри MSR (Model-Specific Registers)

призначені для керування розширеннями налагодження, моніторингом продуктивності, машинним контролем, кешуванням областей фізичної пам’яті й інших функцій. Їх призначення прив’язується до мікроархітек-тури конкретного процесора, склад змінюється від моделі до моделі, доступ привілейований у регістрі ЕСХ, що дозволяє необмежено (до 4 млрд) збільшувати число цих регістрів. У табл. 1.1 наведено призначен-ня регістрів 32-розрядних процесорів.

Page 24: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

23

Таблиця 1.1 Режим Реальний Захищений Віртуального 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 чуттєві до рівнів привілеїв

Значення регістрів та їх позначення зведені в табл. 1.2.

Таблиця 1.2

Тип Біти Регістри General 8

16 32

al cl dl bl ah ch dh bh ax cx dx bx sp bp si di eax ecx edx ebx esp ebp esi edi

Segment 16 es cs ss ds fs gs Control 32 cr0 cr2 cr3 cr4 Debug 32 dr0 dr1 dr2 dr3 dr6 dr7 FPU 80 st0 st1 st2 st3 st4 st5 st6 st7 MMX 64 mm0 mm1 mm2 mm3 mm4 mm5 mm6 mm7 SSE 128 хmm0 хmm1 хmm2 хmm3 хmm4 хmm5 хmm6 хmm7 Команди FPU – це команди співпроцесора для обробки даних роз-

міром у 80 розрядів (бітів). Команди ММХ – це команди паралельної обробки цілочисельних

даних розміром у 64 біта. SSE-команди – це команди паралельної обробки даних у форматі з

плаваючою крапкою розміром у 128 бітів.

Page 25: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

24

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

Пам’ять для 32-розрядних процесорів 80x86 підрозділяється на байти (8 бітів), слова (16 бітів), подвійні слова (32 біти). Слова запису-ються в двох суміжних байтах, починаючи з молодшого. Адресою слова є адреса його молодшого байта. Подвійні слова записуються в чотирьох суміжних байтах, знов-таки починаючи з молодшого байта, адреса якого і є адресою подвійного слова [3 – 4].

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

сегментів змінної довжини (у реальному режимі – фіксованої). Сегменти можуть вивантажуватись на диск і в міру необхідності з нього підкачу-ватись у фізичну пам’ять. Крім сегментації, у захищеному режимі мож-ливе розбиття (Paging) логічної пам’яті на сторінки розміром 4 кбайт, кожна з яких може відображатись на будь-яку область фізичної пам’яті.

Починаючи з 5-го покоління, з’явилася можливість збільшення ро-зміру сторінки до 4 Мбайт. Сегментація і розбивка на сторінки можуть застосовуватись в будь-яких поєднаннях. Сегментація є засобом орга-нізації логічної пам’яті, використовуваним на прикладному рівні.

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

Стосовно пам’яті розрізняють три адресних простори: логічний, лінійний і фізичний.

Основним режимом роботи 32-розрядних процесорів вважається захищений режим, у якому працюють всі механізми перетворення адре-сних просторів (рис. 1.4).

Логічна адреса, також названа віртуальною, складається з селекто-ра сегмента (у реальному режимі – просто адреси сегмента) і ефективної адреси, названої також зміщенням.

Ефективна адреса формується підсумовуванням компонентів BASE, INDEX, DISPLACEMENT із врахуванням масштабу SALE. Оскі-льки кожна задача може мати до 16 К селекторів, зміщення, обмежене розміром сегмента, може досягати 4 Гбайт. Увесь логічний адресний простір для кожної задачі може досягати 64 Тбайт.

Блок сегментації транслює логічний адресний простір у 32-бітовий простір лінійних адрес.

Лінійна адреса утворюється додаванням базової адреси сегмента до ефективної адреси [4, 20. – 21]

Page 26: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

25

Базова адреса сегмента в реальному режимі утворюється множен-

ням вмісту використовуваного сегментного регістра на 16 (як і в 8086). У захищеному режимі базова адреса завантажується з дескриптора, що зберігається в таблиці, по селектору, завантаженому у використовува-ний сегментний регістр.

32-бітова фізична адреса пам’яті утворюється після перетворення лінійної адреси блоком сторінкової переадресації. Вона виводиться на зовнішню шину адреси процесора. В найпростішому випадку (при відк-люченому блоці сторінкової переадресації) фізична адреса збігається з лінійною.

Включений блок сторінкової переадресації здійснює трансляцію лінійної адреси на фізичну сторінками розміром 4 кбайт (для старших поколінь процесорів також можливі сторінки розміром 2 чи 4 Мбайт). Блок забезпечує розширення розрядності фізичної адреси процесорів шостого покоління до 36 біт. Блок переадресації може включатися тіль-ки в захищеному режимі.

Для звертання до пам’яті процесор (разом із зовнішньою схемою) формує шинні сигнали MEMWR# (Memory Write) і MEMRD# (Memory Read) для операцій запису і читання відповідно. Шина адреси розрядніс-

14 Індекс дескриптора лог. або віртуальної адреси

32 Лінійна адреса

Фізична пам’ять

Блок сторінкової переадресації

(необов’язковий)

Блок сегментації

INDEX

BASE DISPLACEMENT ×

SCALE 1, 2, 4, 8

Обчислення ефективної адреси

+ 32 Ефективна адреса

32 Фізична адреса

Селектор (Сегментний Рг)

Рис. 1.4. Формування адреси пам’яті 32-розрядних процесорів

Page 27: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

26

тю 32 біт дозволяє адресувати 4 Гбайт фізичної пам’яті, але в реальному режимі доступний тільки 1 Мбайт, що починається з молодших адрес.

У реальному режимі адресації пам’яті забезпечується сумісність із процесором 8086, що своєю 16-розрядною адресною шиною охоплює простір фізичної пам’яті в 1 Мбайт. Для сумісності з 80286 32-розрядні процесори повторюють його помилку, пов’язану з переносом, що вини-кає при додаванні адреси сегмента з ефективною адресою. При обчис-ленні фізичної адреси можливе виникнення переносу, що викликає поя-ву одиниці на лінії А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).

Схема розподілу першого мегабайта пам’яті комп’ютера наведена в табл. 1.3.

Найнижчі елементи пам’яті (адреси від 00000 до 003FF) включають таблицю векторів переривань, що складається з 32-розрядних адрес. Ці адреси, що називають векторами переривань, використовуються проце-сором, коли виникають програмні або апаратні переривання. Вище над таблицею векторів переривань знаходиться програмне забезпечення BIOS, в яке включені підпрограми керування клавіатурою, консоллю, принтером і календарем [19].

Page 28: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

27

Таблиця 1.3 00000 Таблиця векторів переривання

640 кбайт

00400 Область параметрів DOS

Ядро DOS, драйвера приладів і т. д. Програмне забезпечення BIOS Ядро DOS, драйвера пристроїв і т. д. Резидентна частина COMMAND.COM

(Доступна пам’ять для транзитних програм) 9FFFF Транзитна частина COMMAND.COM A0000 Буфер для графічних зображень B0000 Буфер для текстових даних MDA B8000 Буфер для текстових даних з кольором C0000 Зарезервовано F0000 FFFFF ROM BIOS

Підпрограми BIOS завантажуються з прихованого системного фай-

ла io.sys на завантажувальному диску MS-DOS. Ядром MS-DOS є підп-рограми (сервісні), які завантажуються з системного файла msdos.sys.

Опис даних, які використовуються BIOS, наведено в табл. 1.4. Вище над ядром MS-DOS розташовуються буфери файлів і заван-

тажувані драйвери (з файла config.sys). Резидентна частина командного процесора MS-DOS завантажується з файла, званого command.com. Ко-мандний процесор інтерпретує команди, що вводяться для MS-DOS, і завантажує виконувані програми, розташовані на диску.

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

ве завантаження (booted), відбувається таке: процесор робить перехід на програму ініціалізації в ROM BIOS.

Програма переписує програми із завантажувального сектора диска, який вважається стартовим. Завантажувальний сектор містить програми, що починають виконуватися відразу ж після того, як вводяться в пам’ять. Ці програми послідовно прочитують io.sys і msdos.sys. Останньою програ-мою, що переписується в пам’ять з диска, буде командний процесор з файла command.com.

резидентна частина командного процесора залишається в пам’яті протягом усього часу, поки працює комп’ютер. Вона видає пові-домлення про критичні помилки і викликає підпрограми обробки натиснення клавіш <Ctrl+Break>. Програма ініціалізації прочитує файл

Page 29: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

28

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

Таблиця 1.4

Зміщення (се-гмент 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 Остання лінія курсора 0061 Початкова лінія курсора 0062 Поточний номер відеосторінки 0063 – 0064 Базова адреса активного дисплея 0065 Режим CRT (MDA, CGA) 0066 Регістри для CGA 0067 – 006B Дані про касету 006C – 0070 Простір даних таймера

Далі 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

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

Page 30: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

29

ділянки пам’яті, щоб звільнити якомога більше основної пам’яті; у рядку 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 або mem.exe у поточному каталозі (С:\). Якщо програма не буде знайдена, то операційна система продовжить пошук в каталозі С:\WINDOWS. Якщо і

Page 31: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

30

там не буде виявлений відповідний файл, то наступним каталогом для пошуку буде С: \WINDOWS\COMMAND. Після знаходження необхід-ного файла mem.exe він буде виконаний;

у рядку 6 проводиться завантаження програми mscdex.exe для роботи з дисководом CD-ROM з командного рядка.

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

плея, вона викликає підпрограму з ROM BIOS, яка заносить символ в певне місце у відеопам’яті. У кольоровому текстовому режимі початок відеопам’яті знаходиться за адресою 8000. У режимі кольорової графіки карта пам’яті починатиметься з адреси А0000. Розробники додатка для DOS прагнуть безпосередньо записувати текст і графіку у відеопам’ять і не використовувати вбудовані підпрограми DOS, тому що такий спосіб підвищує швидкість роботи програм. У додатках для Windows такий спосіб мало підходить через конфлікти з системою, яка самостійно зай-мається переписанням екрана.

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

зв’язку із зовнішніми пристроями. Для них в пам’яті BIOS виділено про-стір від 0040:0000 до 0040:0007, що включає список адрес активних пор-тів. Звичайно система має два послідовні порти, тому адреси будуть встановлені. Якщо досліджувати системні установки, можна побачити, що в Windows порт СОМ1 дійсно використовує адреси 03F8 – 03FF, а порт COM2 – адреси 02F8 – 02FF.

Моделі пам’яті

Модель пам’яті визначає спосіб організації програм і даних в

пам’яті комп’ютера. У 32-розрядній архітектурі процесора Intel Pentium використовуються три моделі пам’яті:

плоска, або лінійна, (flat memory model), яка є безперервним простором адрес, що називається лінійним. У ньому розташовуються програмний код, дані, а також область стека. Адресний простір в це моделі адресується побайтно, а діапазон адрес дорівнює 232.

сегментована (segmented memory model), яка складається з трьох окремих просторів адрес, що називаються сегментами. При цьому програмний код, дані і стек розміщуються в окремих сегментах пам’яті. Для того, щоб звернутися до байта в пам’яті, програма формує логічну адресу, що складається з адреси сегмента (селектори сегмента) і зсуву.

Page 32: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

31

Програми, що виконуються в 32-розрядному режимі, можуть викорис-товувати до 16 383 сегментів різного розміру, кожний з яких може мати розмір 232 байт.

Механізм перетворення адрес при використанні сегментованої мо-делі такий: спочатку всі адреси сегментів, визначених в програмі, відо-бражаються на загальний лінійний простір адрес, доступний процесору. Потім логічна адреса операнда в пам’яті перетворюється на лінійну ад-ресу з простору адрес. Всі ці перетворення прозорі для працюючої про-грами. Подібна модель дозволяє підвищити надійність роботи програм. Наприклад, якщо розмістити програмний код і область стека в різних сегментах, то у разі різкого збільшення розміру стека не відбудеться перекриття програмного коду даними із стека;

модель реального режиму адресації (real-address mode memory model), яка використовується в процесорах 8086. Дана модель пам’яті підтримується для того, щоб забезпечити сумісність з раніше розробленими 16-розрядними додатками. У цій моделі застосовується механізм сегментації, причому максимальний розмір сегмента не пере-вищує 64 Кбайт. Максимальний розмір лінійного адресного простору, доступного в цьому режимі, становить 220 байт.

При розробці 32-розрядних програм на мові асемблеру звичайно використовується лінійна, або плоска, модель пам’яті [5 – 7]. При 32-розрядній адресації операндів логічна адреса складається з 16-розрядного селектора сегмента і 32-розрядного зсуву. При 16-розрядній адресації логічна адреса складається з 16-розрядного селектора сегмента і 16-розрядного зсуву.

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

Адреса операнда формується за схемою сегмент: зсув. Залежно від використовуваної моделі пам’яті адреса змінної в пам’яті може форму-ватися як 16:16 або 16:32. Зсув операнда називається його ефективною або виконавською адресою (Effective Address, EA).

Селектор сегмента можна вказати явним або неявним чином. Селе-ктор сегмента завантажується в сегментний регістр, а сам регістр виби-рається залежно від типу виконуваної операції (табл. 1.5).

Page 33: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

32

Таблиця 1.5

Тип операції Регістр Опис Команди

процесора CS – програмний

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

команд процесора Звернення

до стека SS –сегмент стека Використовується при операціях

зі стеком, а також в операціях з пам’яттю, в яких базовими є регі-стри ESP та EBP

Дані DS – сегмент да-них

Використовується в операціях з даними

Рядки-приймачі

ЕS – сегмент да-них, який адресу-ється регістром ЕS

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

Процесор автоматично вибирає сегмент відповідно до умов, описа-

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

Наприклад, потрібно зберегти вміст регістра ЕАХ в пам’яті, що ад-ресується сегментним регістром ES і зсувом, який знаходиться в регіст-рі ЕВХ. В цьому випадку можна використовувати команду

mov ES:[EBX], EAX Після імені сегмента указується символ двокрапки. На рівні процесора заміна сегмента задається спеціальним префік-

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

для сегмента програмного коду – всі команди використову-ють виключно сегментний регістр CS;

при виконанні рядкових операцій рядок-приймач адресується тільки регістром ES;

операції приміщення в стек і витягання із стека завжди вико-ристовують регістр SS.

Деякі інструкції процесора вимагають явної ініціалізації сегмент-

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

Page 34: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

33

команді: mov DS, BX ; переслати вміст регістра ВХ в регістр DS.

В цій команді селектор сегмента, що знаходиться в регістрі ВХ, поміщається в сегментний регістр DS.

В деяких випадках селектор сегмента може визначатися через 48-розрядний вказівник, що знаходиться в пам’яті. При цьому молодше подвійне слово містить 32-розрядний зсув, а старше слово – 16-розрядний селектор сегмента.

В більшості випадків програмісти мають справу з ефективною ад-ресою операнда, тобто з тією частиною повної адреси операнда, яка ви-значає зсув операнда у вказаному сегменті. Дуже часто терміни “ефек-тивна адреса” і “зсув” сприймаються як синоніми при аналізі способів адресації операндів, хоча це не зовсім так.

Ефективна адреса операнда, що знаходиться в пам’яті, може бути задана декількома способами. У загальному випадку можливо визначити ефективну адресу операнда якщо вона складається з декількох частин:

– зсуву, що має 8-, 16- і 32-розрядне значення; – бази, що є вмістом одного з регістрів загального призначення; – індексу, що є вмістом одного з регістрів загального призначення; – масштабного множника, що дорівнює 2, 4 або 8. Існують певні обмеження відносно застосування регістрів загаль-

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

– регістр ESP не можна використовувати як індексний регістр: – якщо за базовий використовується регістр ESP або ЕВР, то сег-

ментним регістром буде SS. У решті випадків сегментним регістром за умовчанням є DS.

1.4. Способи адресації МП Intel

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

пам’яті, у якій зберігаються команди і дані. Спосіб або метод визна-чення в команді адреси операнда або адреси переходу називається режимом адресації або просто адресацією [12 – 14].

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

Page 35: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

34

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

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

обчислення адреси щодо поточної команди (так звана відносна адресація), що забезпечує навантаження програм без модифікацій у будь-яку область пам’яті;

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

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

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

Система команд 32-розрядних процесорів передбачає 11 режимів

адресації. При цьому тільки в двох випадках операнди не зв’язані з пам’яттю. Це операнд, що береться з кожного 8-, 16- чи 32-бітового ре-гістра процесора, і безпосередній операнд (8, 16 чи 32 біт), що міститься в самій команді.

1. Безпосередня адресація. Регістр сегмента не використовується. Наприклад,

MOV EAX, 12345678 ; завантаження в ЕАХ const = 1234567816. 2. Регістрова адресація. Наприклад, MOV EAX, ECX. Інші дев’ять режимів так чи інакше звертаються до пам’яті. При звертанні до пам’яті ефективна адреса обчислюється з викори-

станням таких компонентів: • зміщення (Displacement чи Disp) – 8-, 16- чи 32-бітового числа,

включеного в команду; • бази (Base) – вмісту базового регістра. Звичайно використовуєть-

ся для вказання на початок деякого масиву; • індексу (Index) – вмісту індексного регістра. Звичайно викорис-

товується для вибору елемента масиву; • масштабу (Scale) – множника (1, 2, 4 чи 8), зазначеного у коді

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

Ефективна адреса обчислюється за формулою

Page 36: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

35

ЕА = Base + Index × Scale + Disp. Окремі складові в цій формулі можуть бути відсутніми. Процесор може працювати з 32-бітовою або 16-бітовою адресаці-

єю. 16-бітова адресація функціонує так само, як і в процесорах 8086 і 80286, при цьому як компоненти адреси використовуються молодші 16 біт відповідних регістрів. При 32-бітовій адресації застосовуються роз-ширені 32-розрядні регістри і додаткові режими з масштабуванням інде-ксу. Відмінності 16- і 32-бітових режимів адресації наведено у табл. 1.6.

Таблиця 1.6

Компонент 16-бітна адресація 32-бітна адресація Базовий регістр ВХ або ВР 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 біта. Префікс розрядності адреси перемикає розряд-ність для поточної інструкції на протилежну.

Для більшості типів звернення на час виконання поточної інструк-

ції можливе при указанні альтернативного сегментного регістра, що за-безпечує префікс заміни сегмента (CS:, DS:, ES:, SS:, FS: або GS:) перед кодом інструкції. Проте самі інструкції завжди вибираються тіль-ки з кодового сегмента.

3. Пряма адресація (Direct Mode). Адреса EA = Disp. Наприклад,

MOV EAX, mem1 ; завантаження в ЕAX змінної з іменем mem1.

Page 37: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

36

У реальних програмах для завдання статичних змінних звичайно використовують директиви визначення даних, які дозволяють посилати-ся на статичні змінні не за адресою, а за іменем. Тоді, якщо в сегменті, вказаному в ES, була описана змінна word_var розміром в слово, можна записати ту ж команду як

mov ах, es:word_var У такому разі асемблер сам замінить слово word_var на відповідну

адресу. Якщо селектор сегмента даних знаходиться в DS, то ім’я сегме-нтного регістра при прямій адресації можна не указувати (DS викорис-товується за умовчанням).

Якщо, наприклад, операнд в пам’яті є подвійним словом, то в ко-манді потрібно явним чином вказати старшу або молодшу частину за допомогою оператора PTR: mov AX, word ptr meml ; завантажити в АХ змінну з пам’яті з ім’ям

; meml розміром у слово. Якщо потрібно зберегти в регістрі АХ значення старшого слова

змінної meml, то слід застосувати команду mov AX, word ptr meml+2

У цьому випадку в регістр АХ поміщаються старші два байти змін-ної meml.

У загальному випадку оператор PTR можна зобразити у вигляді тип PTR вираз

За допомогою оператора PTR змінна або мітка, що задається вира-зом, може трактуватися як змінна або мітка вказаного типу. Тип задаєть-ся одним з імен або значень (табл. 1.7).

Таблиця 1.7

Тип Розмірність DB (BYTE) 1 байт – 8 розрядів DW (WORD) 2 байти – 16 розрядів DD (DWORD) 4 байти – 32 розрядів DF (FWORD) 6 байтів – 48 розрядів DP 6 байтів – далекий вказівник DQ (QWORD) 8 байтів – 64 розрядів DT (TBYTE) 10 байтів – 80 розрядів DQWORD 16 байтів – 128 розрядів

Вираз включає будь-які операнди. Типи BYTE, WORD, DWORD,

Page 38: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

37

FWORD, QWORD, TWORD та DQWORD використовуються тільки з операндами [1, 15 – 17].

Оператор PTR служить для організації доступу до об’єкта, який при іншому способі привів би до помилки компіляції (наприклад, для доступу до старшого байта змінної розміру WORD). Якщо PTR не ви-користовується, то асемблер має на увазі замовчуваний тип посилання.

Приклад використання деяких директив визначення даних з табл. 1.7 наведено в програмі з листингу 1.1.

Листинг 1.1. Приклад використання деяких директив визначення

даних: title l1 – використання директив

; masm32 ; компiляцiя – ml /c /coff 1_7L.asm ; компонування – link /SUBSYSTEM:CONSOLE 1_7L.obj

.386 ; директива визначення типу мікропроцесора

.model flat ; завдання лінійної моделі пам’яті

.data ; директива визначення даних a1B byte 11h ; запис у 8-розрядну комірку пам’яті

; з ім’ям a1B числа 11h = 8A1 a2B db 22h ; запис у 8-розрядну комірку пам’яті

; з ім’ям a2B числа 22h b1W word 3A3Bh ; запис у 16-розрядну комірку пам’яті числа 3A3Bh b2W dw 4A4Bh ; запис у 16-розрядну комірку пам’яті числа 4A4Bh c1D dword 5A5B5C5Dh ; запис у 32-розрядну комірку пам’яті

c2D dd 6A6B6C6Dh ; запис у 32-розрядну комірку пам’яті d1Q dq 7A7B7C7D7E7F7A7Bh ; 8 байтів d2Q qword 8A8B8C8D8E8F8A8Bh ; 8 байтів e1t tbyte 9A9B9C9D9E9F9A9B9C9Dh ; 10 байтів

.code ; директива початку коду програми _start: ; мітка початку програми з ім’ям start

ret ; повернення керування ОС end _start ; закінчення програми з ім’ям _start Вікно налагодження програми з листинга 1.1 програмою OllyDbg

наведено на рис. 1.5. З області розташування даних видно, що дані роз-ташовуються в пам’яті, починаючі з молодших адрес.

Page 39: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

38

Адресація відрізняється для реального і захищеного режимів. У ре-

альному режимі (так само як і в режимі V86) зсув завжди 16-бітовий. Це значить, що ні безпосередньо вказаний зсув, ні результат складання вмі-сту різних регістрів в складніших методах адресації не можуть переви-щувати границь слова. При роботі в Windows DOS4G, PMODE і в інших ситуаціях, коли програма запускається в захищеному режимі, зсув не повинен перевищувати границь подвійного слова.

4. Непряма регістрова адресація (Register Indirect Mode). Адреса

EA = Base. Наприклад, MOV EAX, [EBX] ; завантаження в ЕАХ змінної з пам’яті,

; адреса якої знаходиться в регістрі ЕВХ До процесора 80386 для непрямої адресації можна було використо-

вувати тільки ВХ, SI, DI і BР, але потім обмеження були зняті і адресу операнда дозволили прочитувати також з ЕАХ, ЕВХ, ЕСХ, EDX, ESI, EDI, ЕВР і ESP Наприклад, наступна команда розміщує у регістр EАХ слово з елемента пам’яті, селектор сегмента якої знаходиться в DS, а зсув – у EВХ:

mov eах, [ebx] ; eax := ds:[ebx] – завантаження в ЕАХ ; змінної з пам’яті, адреса якої знаходиться в регістрі ЕВХ.

Як і у випадку з прямою адресацією, DS використовується за умов-

чанням, але не завжди: якщо зсув беруть з регістрів ESP, EBP або ВР,

Рис. 1.5. Вікно налагодження програми з листинга 1.1

Page 40: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

39

то як сегментний регістр застосовується SS. У реальному режимі можна вільно працювати зі всіма 32-бітовими регістрами, треба тільки стежити, щоб їх вміст не перевищував границь 16-бітового слова.

5. Базова адресація (Baset Mode). Для формування ефективної ад-

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

Розглянемо приклад програмного коду lea EBX, meml ; завантаження в ЕВХ адреси пам’яті,

; де знаходиться змінна meml mov EАХ [EВХ] ; завантаження в ЕАХ змінної з пам’яті,

; адреса якої знаходиться в регістрі ЕВХ У даному прикладі meml – змінна в пам’яті розміром у подвійне

слово. Перша команда завантажує адресу змінної в регістр EВХ, а друга поміщає в регістр EАХ значення, що міститься за адресою, яка знахо-диться у EВХ.

В загальному випадку адреса EA = Base + Disp. Наприклад, MOV EAX, [4 + ЕBX] ; завантаження в ЕАХ змінної з пам’яті,

; адреса якої знаходиться в регістрі ЕВХ зі зміщенням ; на чотири байти

Така форма адресації використовується в тих випадках, коли в ре-

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

Ще один варіант застосування базової адресації із зсувом – доступ з підпрограми до параметрів, переданих до стека з використанням регіс-тра ВР (ЕВР) як бази і номера параметра як зсуву. Інші допустимі фор-ми запису цього способу адресації такі:

mov eах, [ebp] + 2 mov eах, 2[ebp]

До появи процесора 80386 як базовий регістр дозволялося викорис-товувати тільки ВХ, ВР, SI або DI і зсув міг бути тільки байтом або сло-вом (із знаком). Починаючи з моделі 80386 і вище, процесори Intel дозволяють додатково використовувати ЕАХ, ЕВХ, ЕСХ, EDX, EBP, ESP, ESI і EDI, так само, як і для звичайної непрямої адреса-ції. За допомогою цього методу дозволяється організовувати доступ до одновимірних масивів байтів: зсув відповідає адресі початку масиву, а

Page 41: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

40

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

6. Індексна адресація (Index Mode). Адреса EA = Index + Disp.

Наприклад, MOV ЕDX, [ЕDI] ; завантаження в ЕDX змінної з пам’яті,

; адреса якої знаходиться в регістрі ЕDI 7. Масштабована індексна адресація (Scaled Index Mode). Адреса

EA = Scale × Index + Disp. Наприклад, MOV ECX, [EDI*4 + EAX] ; завантаження в ЕCX змінної

; з пам’яті, адреса якої знаходиться як додаток значень ; регістра ЕАХ та перемноження значення регістра EDI на чотири

MOV EАХ, [ESI*2] + 2 ; завантаження в ЕAX змінної з пам’яті, ; адреса якої знаходиться як додаток двійки та перемноження ; значення регістра ESI на два

Множник, який дорівнює 1, 2, 4 або 8, відповідає розміру елемента масиву – байту, слову, подвійному або збільшеному учетверо слову. З регістрів в цьому варіанті адресації з масштабуванням можна викорис-товувати тільки ЕАХ, ЕВХ, ЕСХ, EDX, ESI, EDI, EBP, ESP, але не SI, DI, ВР або SP.

8. Базово-індексна адресація (Based Index Mode). Адреса EA =

Base + Index. Наприклад, MOV EAX, [ЕBX]ALPHA[ЕSI] ; завантаження в ЕAX змінної ; з пам’яті з ім’ям ALPHA, адреса якої знаходиться як додаток

; значень двох регістрів ЕBX та ESI У цьому методі адресації зсув операнда в пам’яті обчислюється як

сума чисел, що містяться в двох регістрах, і зсуву, якщо він вказаний. Всі перераховані нижче команди є різними формами запису тієї самої дії:

MOV EАХ, [EBX + ESI + 2] MOV EАХ, [EBX][ESI] + 2 MOV EАХ, [EBX + 2][ESI] MOV EАХ, [EBX][ESI + 2] MOV EАХ, 2[EBX][ESI] У регістр EАХ поміщається слово з елемента пам’яті із зсувом, що

Page 42: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

41

дорівнює сумі чисел, що містяться у EВХ, ESI, і числа 2. З 16-бітових регістрів так можна складати тільки ВХ + SI, ВХ + DI, ВР + SI і ВР + DI, а з 32-бітових – всі регістри загального призначення. Як і для прямої адресації, замість безпосередньої вказівки числа дозволено використо-вувати ім’я змінної, заданої одній з директив визначення даних. Таким чином можна розрахувати, наприклад, число з двовимірного масиву: якщо задана таблиця 10 × 10 байт, 2 – зсув її початку від початку сегме-нта даних (на практиці використовується ім’я цієї таблиці), ВХ = 20, а SI = 7, наведені команди прочитають слово, яке складається з сьомого і восьмого байтів третього рядка. Якщо таблиця складається не з одиноч-них байтів, а із слів або подвійних слів, зручніше використовувати як-найповнішу форму – базову адресацію з індексуванням і масштабуван-ням.

9. Масштабована базово-індексна адресація (Based Scaled Index

Mode). Адреса EA = Base + Scale × Index. Наприклад, MOV ECX, [EBX + 4*ESI] ; завантаження в ЕСХ змінної

; з пам’яті, адреса якої знаходиться як додаток значень ; регістра ЕВХ та перемноження значення регістра ESI на чотири

10. Базово-індексна адресація зі зміщенням (Based Index Mode

with Displacement). Адреса EA = Base + Index + Disp. Наприклад, MOV EAX, [EBX + ESI + 00ABCDF] ; завантаження в ЕAХ

; змінної з пам’яті, адреса якої знаходиться як додаток ; значень регістрів ЕBX, ESI та константи ABCDF

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

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

s1 DB "ABCD EFGH IJKLM" s2 DB "abed efgh ijklm" s3 DB "0123 4567 89" sarray label dword DD s1 DD s2 DD s3 … mov EBX, sarray+4

Page 43: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

42

mov ESI, 10 mov AL, byte ptr [EBX][ESI][2] Тут в сегменті даних визначено масив рядків sarray, що містить

адреси рядків s1 – s3. У кожному рядку визначено групи елементів, розділені символом пропуску. Припустимо, потрібно дістати доступ до символу k, що знаходиться в рядку s2. Використаємо регістр ЕВХ як базовий, а регістр ESI як індексний. Помістимо на ЕВХ адресу рядка s2, де знаходиться шуканий елемент (команда mov ЕВХ. sarray+4), а в ре-гістр ESI – зсув групи елементів, в якій знаходиться символ k (величина зсуву в даному випадку дорівнює 10). Для цього виконаємо команду

mov ESI, 10 ; завантаження в ESI константи 10 Символ k знаходиться за зсувом 2 щодо групи елементів ijklm, тому

остання команда поміщає символ в регістр AL: mov AL, byte ptr [EBX][ESI][2]

11. Масштабована базово-індексна адресація зі зміщенням

(Based Scaled Index Mode with Displacement). Адреса EA = Base + Scale × Index + Disp. Наприклад, MOV ECX, [EBX + 36] + [8*ESI] ; завантаження в ЕСХ змінної

; з пам’яті, адреса якої знаходиться як додаток значення ; регістра ЕВХ, збільшеного на 36 та значення регістра ESI, ; збільшеного в вісім разів

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

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

… S1 DB "0123456789ABCDEF" ; резервування у пам’яті комірок ; розміром у байт для збереження кожного числа змінної S1

mov EBX, 7 ; занесення в ЕВХ константи 7 mov AL, byte ptr S1[EBX*2] ; занесення в AL числа ; з пам’яті з масиву S1, адреса якого знаходиться в EBX*2 При вказаному значенні регістра ЕВХ в регістр AL буде поміщений

символ Е, оскільки він знаходиться за зсувом 14 (7 × 2) в масиві S1. Це найповніша схема адресації, в яку входять всі випадки, розгля-

Page 44: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

43

нуті раніше як приватні. Повну адресу операнда можна записати як вираз, наведений на

рис. 1.6.

Зсув може бути байтом або подвійним словом. Якщо ESP або ЕВР

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

Масштабування індексу можливе тільки при 32-розрядній адреса-ції.

Процесор може працювати з 32- чи 16-бітовою адресацією. 16-бітова адресація працює так само, як і в процесорах 8086 і 80286, при цьому як компоненти адреси використовуються молодші 16 бітів відпо-відних регістрів. При 32-бітовій адресації використовуються розширені 32-розрядні регістри і застосовуються додаткові режими з масштабуван-ням індексу.

Приклад використання безпосередньої адресації наведено у листин-гу 1.2.

Листинг 1.2. Програма з використанням безпосередньої адресації: title l2 (Засоби адресацiї_1)

; masm32 ; компiляцiя – ml /c /coff А1.asm ; компонування – link /SUBSYSTEM:CONSOLE А1.obj

.386 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

.data ; директива визначення даних data_8 db -3 ; число -3 в пам’яті має ім’я data_8 та розмір 8 біт

EAX EBX ECX EDX EBP ESP EDI ESI

EAX EBX ECX EDX EBP ESP EDI

+ *

1 2 4 8

+ зсув

CS: SS: DS: ES: FS: GS

: Рис. 1.6. Повна схема адресації

Page 45: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

44

data_16 dw ? ; не визначене число (?) в пам’яті має ім’я data_16 ; та розмір 16 біт

.code ; директива початку коду програми start: ; мітка початку програми з ім’ям start mov eax,0f f f f f f f fh ; занесення до Рг eax операнда f f f f f f f fh mov al, data_8 ; занесення до Рг al операнда -3 mov data_16, ax ; збереження в комірці пам’яті Рг ах ret ; повернення керування ОС end start ; закінчення програми з ім’ям start

Ця програма с початку заносить до ЕАХ 32-розрядну константу

f f f f f f f fh . Потім до AL заноситься статична константа з іменем data_8, яка в десятковій системі числення дорівнює –3, а у шістнадцятковій FD.

Команда mov data_16, ax заносить до комірки пам’яті DS:[402001] як молодшу частину з AL, так і старшу з AH. Таким чином, до пам’яті буде занесено слово FF FD.

Для того, щоб налагодити програму необхідно виконати такі дії (див. розділ 2):

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

masm32v9_0\bin\ім’я_програми.asm; – виконати компіляцію програми:

ml /c /coff ім’я_програми.asm; – виконати компонування програми:

link /SUBSYSTEM:CONSOLE ім’я_програми.obj. Після таких дій створюється файл з розширенням .ехе, який можна

для налагодження завантажити до налагоджувача, наприклад, OllyDbg. Для цього необхідно виконати команди Файл/Открыть та вказати дире-кторію, де знаходиться необхідний файл з розширенням .ехе. Якщо ви-конані попередні дії, які рекомендувалися, то такий файл повинен зна-ходитися за шляхом:

masm32v9_0\bin\ім’я_програми.ехе. Вікно налагодження програми з листингу 1.2 програмою OllyDbg

(http://cracklab.ru/_dl/new/ollydbg110xp.rar або www.ollydbg.de/ odbg200a. zip) наведено на рис. 1.7.

Page 46: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

45

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

ші F7. Приклад використання непрямої адресації наведено у листингу 1.3. У програмі листингу 1.3 як регістр непрямої адресації використову-

ється регістр ESP. Ця програма виконує занесення до EAX шістнадцят-кового числа 11223344h та перезапис його до стека за адресою, яка роз-міщена в регістрі ESP. Вікно налагодження програми з листингу 1.3 програмою OllyDbg наведено на рис. 1.8.

Листинг 1.3. Програма з використанням непрямої адресації: title l3 (Засоби адресацiї_1) ; masm32

; компiляцiя – ml /c /coff a2.asm ; компонування – link /SUBSYSTEM:CONSOLE a2.obj

.386 ; директива визначення типу мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті

; та угоди ОС Windows .code ; директива початку коду програми

start: ; мітка початку програми з ім’ям start mov eax,11223344h ; завантаження в ЕАХ числа 11223344h

Рис. 1.7. Вікно налагодження програми з листингу 1.2

Page 47: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

46

mov [esp],eax ; занесення з ЕАХ в пам’ять (стек) числа, ; адреса якого находиться в ESP

ret ; повернення керування ОС end start ; закінчення програми з ім’ям start У правому нижньому кутку наведено вершину стека з адресою

0012FFC4 та результатом 11223344.

Рис. 1.8. Вікно налагодження програми з листинга 1.3

Page 48: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

47

2. ЕТАПИ СТВОРЕННЯ ПРОГРАМИ НА МОВІ АСЕМБЛЕРУ

При вивченні мови асемблеру та розробці реальних програм на цій мові під операційну систему (ОС) Windows процес розподілення комі-рок пам’яті для збереження кодів команд та чисел виконується автома-тизовано.

Етапи створення програми на мові асемблеру такі: підготовка (або внесення змін) вихідного тексту програми; асемблювання програми (отримання об’єктного коду); компонування програми (отримання виконавчого файла про-

грами); налагодження програми (виправлення помилок). Звичайно ці етапи циклічно повторюються, оскільки при виявленні

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

2.1. Підготовка тексту програми

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

текстових файлів. Імена файлів і їх розширення можуть бути будь-які, але прийнято використовувати розширення *.asm. Ці файли є текстови-ми, їх можна підготовити за допомогою будь-якого текстового редакто-ра і зберігати у вигляді звичайних файлів у форматі ASCII.

Структура програми під Win32 може бути такою: TITLE <ім’я програми .386 ; директива визначення типу мікропроцесора .model flat ; завдання лінійної моделі пам’яті .data ; директива визначення даних ; дані, які визначені .data? ; неініціалізовані дані ; .code ; директива початку коду програми <label>: ; мітка початку програми

Page 49: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

48

;<code> end <label> ; закінчення програми

2.2. Асемблювання програми

Підготовлені тексти програми з розширення *.asm є вхідними да-ними для програм, які називаються асемблерами (наприклад, програми: Masm, Tasm, Wasm). Завдання програми асемблеру – перетворити текст програми у форму двійкових команд, які може виконати МП. Піс-ля асемблювання отримують файли об’єктних модулів, що мають роз-ширення *.obj. Процес асемблювання частіше називають трансляцією.

Для правильної робота асемблеру Masm32 (www.masm32.com) його необхідно інсталювати тільки на системний диск с:/, який повинен бути отформатований у розмітці FAT32. Якщо поставити асемблер Masm32 не на системний диск, а на інший логічний диск з розміткою FAT32, то в такому випадку необхідно конкретно вказувати шляхи підк-лючення бібліотек розташування АРІ-функцій.

Програма ml.exe з Masm32 виконує дві послідовні дії при ство-ренні виконуваного файла програми. По-перше, вона забезпечує транс-ляцію початкового тексту програми в проміжний об’єктний файл. По-друге, ml.exe викликає програму link.exe, яка компонує об’єктні файли і бібліотеки в єдину виконувану програму.

В асемблері masm32 трансляцію файлів з розширенням asm мож-на виконати з командного рядка:

ml /с /coff ім’я_файла.asm Створений за допомогою цієї команди об’єктний файл має формат

COFF. Якщо параметр /coff не заданий, то форматом створеного об’єктного файла буде OMF.

Компонувальник link.exe оперує з OBJ-файлами як у форматі COFF, так і у форматі OMF, при цьому виконується автоматичне перет-ворення формату файла з OMF в COFF. Звичайно при генерації викону-ваних файлів використовується формат COFF. Якщо файл об’єктного модуля повинен застосовуватися в додатку, написаному на Visual C++ .NET, то формат його обов’язково повинен бути COFF. У той же час при застосуванні об’єктного файла в додатку, розробленому в Borland Delphi 2005, єдиним сприйманим форматом є OMF.

У процесі трансляції початкового тексту програми виконуються та-кі дії:

Page 50: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

49

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

2. Розгортаються макроси. 3. Обчислюються константні вирази, при цьому вони заміщаються

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

Наприклад, команда mov ЕAX, 2008, оскільки вона не має операндів, розташованих в пам’яті.

5. Зберігаються зсуви змінних в пам’яті відносно зміщення у сег-ментах, в яких ці змінні розташовані.

6. Сегменти і їх атрибути розміщуються в об’єктному файлі. 7. У об’єктному файлі зберігаються переміщувані адреси

(relocatable addresses). 8. При необхідності створюється файл листингу. 9. Безпосередньо програмі link.exe передаються деякі директиви

(наприклад, INCLUDELIB і DOSSEG). Основні опції компіляції наведено у табл. 2.1.

Таблиця 2.1 /c Асемблювати без лінковки (використання зовнішнього

лінкера (наприклад link.exe) для компонування файлів) /coff Генерувати об’єктний файл в COFF-форматі (для компо-

нувальника microsoft) /Fo<file> Змінити ім’я об’єктного файла (якщо припускається змі-

на імені) /G<c|d|z> Використати виклики Pascal, C, або Stdcall (тип викликів

для процедур) /Zi Додати символьну налагоджувальну інформацію (для

налагоджувача) /I<name> Встановити include шлях

2.3. Компонування програми

Після успішної трансляції початкового тексту асемблерної програ-

ми результат у вигляді об’єктного файла передається компонувальнику link.exe. Він виконує об’єднання об’єктних модулів в один файл. Сег-менти, визначені в програмі, групуються відповідно до інструкцій, що містяться в об’єктному файлі. Вся інформація про розміщення сегментів записується в заголовок виконуваного файла.

Page 51: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

50

Результатом компонування є виконавчі файли, що мають розши-рення *.exe.

В асемблері masm32 для генерування 32-розрядних ЕХЕ-файлів може бути використаний один із командних рядків: link /SUBSYSTEM:WINDOWS /OPT:NOREF ім’я_файла.obj

або link /SUBSYSTEM:CONSOLE ім’я_файла.obj

Схему асемблювання, компонування і виконання програми наведе-

но на рис. 2.1.

Рис. 2.1. Схема асемблювання, компонування і виконання програми

Page 52: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

51

Структура програми (не тільки на асемблері) визначається декіль-кома чинниками:

– архітектурою процесора; – особливостями тієї операційної системи, під керуванням якої ця

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

ставлять різні вимоги до початкового тексту програми. MASM і TASM підтримують спрощену сегментацію. Суть такої

сегментації в тому, що директиви .CODE і .DATA можуть з’являтися в тексті програми кілька разів. Транслятор потім збирає код і дані разом. Основною метою такого підходу є можливість наблизити в тексті про-грами дані до тих рядків, де вони використовуються.

Основні опції компоновки наведені в табл. 2.2.

Таблиця 2.2

/DEBUG Налагодження (при використанні налагоджу-вача)

/DEBUGTYPE:CV|COFF

Тип налагодження: codeview / coff (вибирає вихідний формат налагоджувальної інформації. Налагоджувачі SoftІce і Visual С++ можуть обробляти CV (codeview))

/DEF:ім’я_файла DEF файл (вказує файл визначення (.def). Ви-

користовується з dll для функцій, що експорту-ються)

/DLL DLL (вихідний файл з розширенням .DLL)

/LIBPATH:path Шлях до бібліотек (вказує шлях до файлів біб-ліотек (*.lib).

/I< ім’я > Встановлює шлях для inc-файлів

/OUT: ім’я_файла Out:імя_файла (для зміни імені вихідного фай-ла)

/SUBSYSTEM:{...} Підсистема (вибір ОС:

NATIVE|WINDOWS|CONSOLE|WINDOWSCE|POSIX)

Page 53: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

52

2.4. Налагодження програми

Будь-яка програма потребує налагодження (виправлення помилок). Сучасні налагоджувальні програми для асемблеру платформи х86, на-приклад програми Dbg_x86 (http://msdl.microsoft.com/download/symbols/ debuggers/dbg_x86_6.7.05.1.exe), SoftICE, Emu8086 v.4.04, OllyDbg 1.10 (http://cracklab.ru/ download.php?action=get&n=MzYw), OllyDbg 2 (http:// www.ollydbg.de/ odbg v2.00c.zip), Syser (www.syser.com) дозволяють у процесі виконання програми контролювати значення регістрів загально-го призначення чи змінних і змінювати їх. Сучасні налагоджувачі, які підтримуються фірмами-виробниками та використовуються, можна та-кож знайти за адресою

http://www.team-x.ru/guru-exe/. За допомогою налагоджувачів можна переглядати вміст різних ді-

лянок пам’яті, а також виконувати програму крок з кроком.

Page 54: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

53

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

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

Директиви призначені для керування процесом асемблювання і фо-рмування листингу. Вони діють тільки в процесі асемблювання про-грами і не переводяться в машинні коди. Мова асемблеру містить такі основні директиви:

керування моделями пам’яті MODEL та сегментами DATA, CONST, STACK, CODE;

початку і кінця сегмента SEGMENT та ENDS; початку і кінця процедури PROC та ENDP; визначення пам’яті та призначення сегментів ASSUME; початку ORG; визначення даних DB, DW, DD, DF, DP, DQ, DT; символьних констант: = , EQU, TEXTEQU; завершення програми END; відзначення LABEL.

3.1.1. Директиви MODEL, DATA, CONST, STACK, CODE

Директива .MODEL модель_пам’ят і [,угода_про_виклики]

[,т ип_ОС] [,парамет р_ст ека] визначає модель пам’яті, використовува-ну програмою. Ця директива повинна знаходитися перед будь-якою з директив оголошення сегментів. Вона зв’язує певним чином різні сег-менти програми, визначувані її параметрами tiny, small, compact, medium, large, huge або flat. Параметр модель_пам’ят і є обов’язковим.

Для включення в програму процедури, написаної на мові високого рівня, необхідно вказати модель пам’яті, яка використовується компіля-тором мови високого рівня. Крім того, модель пам’яті повинна відпові-дати режиму роботи (типу) процесора. Це має значення для плоскої мо-делі пам’яті, яку можна застосовувати тільки в режимах . 386, .486, .586, .686. Модель пам’яті визначає, який тип адресації даних і команд підт-

Page 55: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

54

римує програма (near або far). Це має сенс для команд переходу, викли-ків і повернення з процедур. У табл. 3.1 демонструються ці особливості.

Таблиця 3.1 Параметри моделей пам’яті

Модель пам’яті

Адресація коду

Адресація даних

Операційна система

Tіny Near Near MS-DOS Small Near Near MS-DOS, Windows Medium Far Near MS-DOS, Windows Compact Near Far MS-DOS, Windows Large Far Far MS-DOS, Windows Huge Far Far MS-DOS, Windows Flat Near Near Windows NT/2000/XP/2003

Модель tiny – коди і дані разом повинні займати не більше 64

Кбайт, працює тільки в 16-розрядних додатках MS-DOS. У цій моделі всі дані і код розташовуються в одному фізичному сегменті. Розмір про-грамного файла в цьому випадку не перевищує 64 Кбайт. З іншого боку, модель flat припускає несегментовану конфігурацію програми і викори-стовується тільки в 32-розрядних операційних системах. Ця модель по-дібна до моделі tiny в тому сенсі, що дані і код розміщені в одному сег-менті, тільки 32-розрядному.

Модель small – code ≤ 64 Кбайт, data ≤ 64 Кбайт. Один сегмент ко-ду, один сегмент даних Дані і код при використанні цієї моделі адресу-ються як near (ближні).

Модель large – code > 64 Кбайт, data > 64 Кбайт – підтримує декі-лька сегментів кодів і декілька сегментів даних. За умовчанням всі по-силання на код і дані вважаються дальніми (far).

Модель medium – data ≤ 64 Кбайт, код будь-якого розміру. Багато сегментів коду, один сегмент даних, при цьому всі посилання в сегмен-тах програмного коду за умовчанням вважаються дальніми (far), а поси-лання в сегменті даних – ближніми (near).

Модель compact – code ≤ 64 Кбайт, дані будь-якого розміру. Один сегмент коду, багато сегментів даних, в яких використовується дальня адресація даних (far), і один сегмент коду з ближньою адресацією (near).

Модель huge – code > 64 Кбайт, data > 64 Кбайт. Ця модель прак-тично еквівалентна моделі пам’яті large.

Page 56: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

55

Для розробки програми для моделі flat перед директивою .model flat слід розмістити одну з таких директив: .386, .486, .586 або .686. При цьому адресація даних є ближньою (near), а всі адреси і вказівники є 32-розрядними. Сегменти відсутні. 32-розрядна адресація використовується як для коду, так і для даних.

При використанні всіх моделей пам’яті, окрім tiny, створюються виконувані програми типу .ехе, а при використанні моделі пам’яті tiny – програми .com. Всі моделі, виключаючи flat, розраховані на викорис-тання в реальному режимі процесора. Модель flat може використовува-тися тільки для роботи в захищеному режимі для створення консольних додатків Windows.

Параметр угода_про_виклики використовується для визначення способу передачі параметрів при виклику процедури з інших мов, у то-му числі і мов високого рівня (C++, Pascal). Параметр може набувати таких значень: С++, BASIC, FORTRAN, PASCAL, SYSCALL, STDCALL.

Параметр т ип_ОС дорівнює ОS DОS, і на даний момент це єдине підтримуване значення цього параметра.

У прикладі .model flat, С

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

У прикладі .model flat, stdcall

параметр stdcall указує, що застосовується спосіб передачі параметрів при використанні процедур справа наліво.

Після того, як модель пам’яті встановлена, набувають чинності спрощені директиви визначення сегментів, що об’єднують дії дирек-тив SEGMENT і ASSUME. Крім того, сегменти, оголошені спрощеними директивами, не потрібно закривати директивою ENDS – вони закрива-ються автоматично, як тільки асемблер виявляє нову директиву визна-чення сегмента або кінець програми.

Директива .DATA визначає початок сегмента ініційованих даних з

ім’ям DATA і за наявності попереднього сегмента завершує його: DATA segment word public ‘DATA’

Цій директиві повинна передувати директива .MODEL, яка вказує модель пам’яті, використовувану програмою.

Page 57: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

56

Директива .DATA? визначає сегмент даних, в якому розташову-ються неініційовані дані. За наявності попереднього сегмента новий сегмент завершує його. Неініційовані дані можуть оголошуватися в сег-менті .DATA? за допомогою знака оператора “?” Цей сегмент звичайно не включається в програму, а розташовується за кінцем пам’яті, тому всі описані в ньому змінні на момент завантаження програми мають неви-значені значення. Перевагою директиви .DATA? є те, що при її викорис-танні зменшується розмір виконуваного файла і забезпечується краща сумісність з іншими мовами. Цій директиві повинна передувати дирек-тива .MODEL.

Директива .CONST – визначає початок сегмента незмінних даних:

CONST segment word public ‘CONST’ За наявності попереднього сегмента новий сегмент завершує його.

Для забезпечення сумісності з іншими мовами дані повинні бути у фор-маті, сумісному з прийнятими в мовах високого рівня угодами. Сегмент, визначений директивою .CONST, має атрибут «тільки для читання». Цій директиві повинна передувати директива .MODEL.

Директива .STACK [розмір] визначає початок сегмента стека з

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

STACK segment para public ‘stack’ Якщо параметр не вказаний, розмір стека передбачається таким,

що дорівнює 1 Кбайт. За наявності попереднього сегмента новий сег-мент завершує його. Цій директиві повинна передувати директива .MODEL.

Директива .CODE [ім’я] визначає сегмент програмного коду і за-

кінчує попередній сегмент. Цій директиві повинна передувати директи-ва .MODEL, яка вказує модель пам’яті, використовувану програмою.

3.1.2. Директиви SEGMENT та ENDS Директиви початку SEGMENT і кінця ENDS сегмента призна-

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

Назва Мнемокод Операнд DATASG SEGMENT {<параметри>}

Page 58: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

57

. . . ; Інші команди або директиви сегмента DATASG ENDS

Обидві директиви SEGMENT і ENDS повинні мати однакові назви.

Директива SEGMENT може містити три типи параметрів: вирівнювання; об’єднання; класу. Параметр вирівнювання визначає початкову адресу або межу сегмен-

та, наприклад: BYTE – з різної адреси – байт, WORD – з парної адреси – слово, DWORD – з адреси, кратної 4 – подвійне слово, QWORD – слово, збільшене у чотири рази (64 розряди = 8 байтів), TWORD – слово розміром 80 розрядів, PARA – межа за замовчуванням – з адреси, кратної 16, PAGE – з адреси, кратної 256.

Якщо немає параметра вирівнювання за замовчуванням, береться па-раметр PARA, який вказує на те, що сегмент розташовується на початку параграфа, а початкова адреса сегмента є кратною 16. Параграфом нази-вається область пам’яті розміром 16 байт, початкова адреса якої кратна 16, тобто має праворуч чотири нульових розряди.

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

NONE: значення за замовчуванням. Сегмент має бути логічно відокремленим від інших сегментів, хоча фізично він може розташову-ватися поряд. Передбачається, що сегмент має власну базову адресу;

PUBLIC: усі PUBLIC – сегменти з однаковими назвою та кла-сом завантажуються у суміжні області і мають одну базову адресу;

STACK: призначення аналогічне параметру PUBLIC. У будь-якій програмі має бути визначений принаймні один сегмент STACK. Якщо визначено більше одного стека, то вказівник стека SP (Stack Pointer) встановлюється на початок першого стека;

COMMON: для сегментів COMMON з однаковими назвами та класами встановлюється одна спільна базова адреса. Під час виконання програми здійснюється накладання другого сегмента на перший. Розмір загальної області визначається найдовшим сегментом;

Page 59: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

58

АТ – параграф, який слід визначати заздалегідь. Цей параметр за-безпечує визначення міток та змінних за фіксованими адресами у фіксо-ваних областях пам’яті;

‘Клас’: цей параметр може мати будь-яку правильну назву, яка розміщується в одинарних лапках. Параметр використовується для обро-бки сегментів, які мають однакові назви та класи. Типовими є класи ‘STACK’ та ‘CODE’, наприклад:

Назва Мнемокод Операнд STACKSG SEGMENT PARA STACK ‘STACK’

У випадку, якщо програма не повинна об’єднуватися з іншими про-грамами, параметр об’єднання не вказується.

3.1.3. Директиви PROC та ENDP

Директиви початку і кінця процедури PROC та ENDP викорис-

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

<Назва> PROC {<тип процедури>}. Можливі два типи процедур: NEAR – процедура знаходиться в тому самому сегменті, що і

команди, які її викликають; FAR – процедура знаходиться за межами сегмента. За замовчуванням береться тип процедури NEAR. Сегмент кодів може містити декілька процедур. Описання сегмента

кодів, що містить тільки одну процедуру, має такий вигляд: Назва Мнемокод Операнд Ім’я сегмента SEGMENT PARA Ім’я_процедури PROC FAR

RET Ім’я_процедури ENDP Ім’я сегмента ENDS

Ім’я процедури має бути визначене обов’язково і збігатися з іменем у директиві ENDP, яка визначає кінець процедури.

3.1.4. Директива ASSUME

Директива призначення сегментів ASSUME використовується

для встановлення відповідності між сегментами та сегментними регіст-рами і має такий формат:

Page 60: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

59

ASSUME <сегментний регістр>:<ім’я>{,}{...}. Наприклад, запис SS:ім_стек вказує, що ім’я стека визначається вмі-

стом регістра SS. Одна директива ASSUME може призначати до чоти-рьох сегментних регістрів у будь-якій послідовності, наприклад:

Мнемокод Операнд(и) ASSUME SS-ім_стек, DS-ім_дані, СS: ім_код, ES:ім._додаткові дані

Для скасування будь-якого призначеного раніше в директиві ASSUME сегментного регістра треба використовувати слово NOTHING:

Мнемокод Операнд(и) ASSUME ES: NOTHING. Якщо програма не використовує якийсь сегмент, то відповідний

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

3.1.5. Директива ORG Директива ORG використовується для зміни вмісту програмного

лічильника без команд умовного чи безумовного переходу. Найчастіше цю директиву використовують для встановлення початкової адреси про-грами. Наприклад, директива ORG 100H встановлює програмний лічи-льник на зміщення 100Н відносно початку сегмента кодів. Операнд зі знаком долара "$" має поточне значення програмного лічильника. На-приклад, директива

ORG $ + 10h збільшує адресу, завантажену в програмний лічильник, на 10h.

3.1.6. Директиви визначення даних DB, DW, DD, DF, DP, DQ, DT

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

вмісту та резервування комірок пам’яті. Директива має формат

[ <ім’я> ] Dn [кількість повторень ] <вираз>, де мнемокод Dn = DB, DW, DD, DF, DP, DQ, DT вказує на довжину даних: DB – байт; DW – слово (два байти); DD – по-двійне слово; DF, DP – шість байтів, DQ – чотири слова; DT – десять байтів. Якщо у форматі наявне ім’я, то далі в програмі воно може вико-ристовуватися для позначення комірки пам’яті.

<Вираз> у форматі директиви містить одну або кілька констант для задання початкових значень вмісту комірок пам’яті або знак “?” – для невизначеного значення вмісту. Наприклад, директива

Page 61: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

60

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(21)

Приклади директив визначення даних можуть бути такими: db1 DB 5 ; запис у 8-розрядну комірку пам’яті з ім’ям db1 числа 5

db2 DB ‘ABCD’ ; запис у пам'ять з ім’ям db2 8-розрядних літер db3 DB ? ; резервування в пам’яті з ім’ям db3 даних, які не визначені dw1 DW 1234 ; запис у 16-розрядну комірку пам’яті з ім’ям dw1 числа 1234 dw2 DW 5*6 ; запис у 16-розрядну комірку пам’яті з ім’ям dw2 числа 30

dw3 DW 1. ‘ $’ dw4 DW array dd1 DD 2.7 ; число займає 4 байти в пам’яті dd2 DD ‘abcd’ dql DQ 123456789 ; число займає 8 байтів в пам’яті mixl DB 5 DUP(5 DUP(5 DUP(10))) dt1 DT 56789 ; запис у 80-розрядну комірку пам’яті з ім’ям ; dt1 числа 56789, число займає в пам’яті 10 байтів Директиви визначення даних можуть використовуватися як дирек-

тиви завдання типу. Базові типи, які можна використовувати для визна-чення даних наведені у табл. 3.2.

Page 62: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

61

Таблиця 3.2 Тип Значення

BYTE 8-розрядне ціле число без знаку SBYTE 8-розрядне ціле число зі знаком WORD 16-розрядне ціле число без знаку SWORD 16-розрядне ціле число зі знаком DWORD 32-розрядне ціле число без знаку SDWORD 32-розрядне ціле число зі знаком FWORD 48-розрядне ціле число (використовується як вказівник) QWORD 64-розрядне ціле число TBYTE 80-розрядне ціле число DQWORD 128 розрядне число REAL4 32-розрядне коротке дійсне число REAL8 64-розрядне дійсне число REAL10 80-розрядне розширене дійсне число

Приклади: 1. Записати в байт пам’яті десяткове число 23 і присвоїти цьому

байту ім’я а: а db 23. 2. Зарезервувати 1 байт пам’яті: db ? 3. Записати в слово пам’яті шістнадцяткове число 1234: dw 1234h. 3.1.7. Директиви символьних констант: = , EQU, TEXTEQU Директива знака рівності створює константу, присвоюючи імені

числове значення ім’я = вираз

На відміну від директив DB і DW, директива знака рівності не роз-поділяє пам’ять. Під час трансляції програми всі відповідні імена будуть замінені виразами. В результаті обчислення виразу повинне вийти 32-розрядне число зі знаком або без нього (для процесорів 386 і вище), як показано в прикладі:

prod = 10 * 5 ; обчислення виразу maxlnt = 7FFFh ; макс. значення 16-розрядного числа зі знаком minlnt = 80000h ; мінім. значення 16-розрядного числа зі знаком

Page 63: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

62

maxUInt = 0FFFFh ; макс. значення 16-розряд. числа без знака.

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

Вирази, що включають цілочисельні значення, визначають цифрову константу, але вирази з дійсними числами інтерпретуються як рядок символів. Рядки символів можуть бути поміщені в кутові дужки (<...>) для підтвердження того, що це рядок символів. Це виключає неоднозна-чність при визначенні імен:

Приклад Тип значення maxint equ 32767 ; Цифровий maxuint equ 0FFFFh ; Цифровий coun equ 10 * 20 ; Цифровий floatl equ <2,345> ; Рядок символів len equ $-string1 Запис len equ $-string1 дозволяє обчислити кількість байтів, яку

займає у пам’яті змінна з ім’ям string1 та присвоєння цієї кількості змінній len.

За допомогою директиви TEXTEQU можна присвоїти рядку сим-

волів ім’я і потім використовувати рядок під цим ім’ям. Синтаксис при-своювання:

ім’я TEXTEQU <текст> ім’я TEXTEQU макровизначення тексту ім’я TEXTEQU % константний вираз У даному випадку текст (т екст ) представляє послідовність будь-

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

Символічне ім’я може бути присвоєне рядку символів, який надалі буде завжди замінюватися рядком символів. Наприклад, змінна promptl визначає макровизначення тексту continueMsg:

continueMsg text equ <"Do you wish to continue (Y/N)?">

Page 64: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

63

.data ; директива визначення даних promptl db continueMsg

3.1.8. Директива END Директива завершення програми END є останньою у програмі і

має такий формат: END {<стартова адреса>}.

Параметр директиви <стартова адреса> використовується лише при створенні EXE-файлів.

3.1.9. Директива LABEL

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

повідності між іменем і типом змінних та не займає у пам’яті ніяких ко-мірок пам’яті. Вона має такий формат:

<ім’я> LABEL {<тип>}. Як тип можна використовувати слова BYTE, WORD, DWORD, що

визначають довжину даних: байт, слово або подвійне слово. Дире-ктива LABEL перевизначає параметри процедур NEAR або FAR. На-приклад, директива

TOS LABEL WORD присвоює комірці пам’яті ім’я TOS і зазначає, що її вміст є словом та не займає у пам’яті ніяких комірок пам’яті.

3.2. Оператори мови асемблеру

OFFSET – оператор, який заносить (повертає) відстань змінної від початку сегмента в приймач або, іншими словами, передає адресу змінної в приймач інформації. Оператор OFFSET функціонує аналогічно команді lea.

MOV ЕBX,OFFSET count ; у ЕВХ заноситься адреса зміною count

; EBX := [count] У наступному прикладі зсув адреси кожного елемента масиву пере-

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

Page 65: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

64

.data ; директива визначення даних bmas db 10h,20h,30h,40h ; масив чисел розміром у байт кожен wmas dw 1000h,2000h,3000h ; масив чисел розміром у слово кожен

.code ; директива початку сегмента команд mov еdi,offset bMas ; ЕDI = [bMas] mov еbx,offset bMas+1 ; ЕBX = ]bMas+1] mov еsi,offset wMas+2 ; ЕSI = [wMas+2]

PTR – оператор, який примусово встановлює розмір операнда. PTR може використовуватися у поєднанні із стандартними типами да-

них: BYTE, WORD, DWORD, QWORD та TBYTE. Оператор PTR також корисний, коли необхідно змінити розміри

операнда, встановлені за умовчанням. SEG – оператор передає (повертає) сегментну частину сегмен-

тного регістра в приймач інформації. Оператор SEG застосовується, ко-ли змінна знаходиться в сегменті, відмінному від того, на який указує ре-гістр DS. mov ebx,seg ds ; поточне значення сегменту DS поміщається в ebx

TYPE – оператор, який записує (повертає) у приймач інформа-

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

Листинг 3.1. Використання оператора TYPE: ; masm 32: компіляція– ml /c /coff 1_1L.asm ; компоновка – link /SUBSYSTEM:CONSOLE 1_1L.obj

.386 ; директива визначення типу мікропроцесора .model flat ; завдання лінійної моделі пам’яті option casemap:none ; відмінність малих та великих літер

.data ; директива визначення даних var1 DB 2 ; var1 := 02 розміром у байт var2 DW 1000h ; var2 := 1000h розміром у слово (2 байти) var3 DD ? ; var3 := невизначені дані розміром у 4 байти var4 DQ ? ; var4 := невизначені дані розміром у 8 байти var5 DT ? ; var5 := невизначені дані розміром у 10 байтів var6 DB 6,7,8,9,10 ; кожне число розміщується у байті msg DB ‘hello’, 0 ;

Page 66: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

65

.code ; директива початку сегмента команд _start: ; мітка початку програми з ім’ям _start

MOV AL,TYPE var1 ; AL = 01 MOV AL,TYPE var2 ; AL = 02 MOV AL,TYPE var3 ; AL = 04 MOV AL,TYPE var4 ; AL = 08 MOV AX,TYPE var5 ; AX = 000A MOV AX,TYPE var6 ; AX = 0001 MOV AX,TYPE msg ; AX = 0001 MOV AX,TYPE _start ; AX = FF04h

ret ; повернення керування ОС end _start ; закінчення програми з ім’ям _start Вікна налагоджувача OllyDbg для досліджування оператора TYPE

наведено на рис. 3.1. LENGTH – оператор, який повертає число байтів, слів, подвій-

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

Листинг 3.2. Використання оператора LENGTH: ; masm 32: компіляція – ml /c /coff 1_5L.asm

Рис. 3.1. Вікна налагоджувача OllyDbg для досліджування оператора TYPE

Page 67: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

66

; компонування – link /SUBSYSTEM:CONSOLE 1_5L.obj .386 ; директива визначення типу мікропроцесора .model flat ; завдання лінійної моделі пам’яті option casemap:none ; відмінність малих та великих літер

.data ; директива визначення даних var1 DB 2 ; змінна var1 := 2 займає в пам’яті один байт var2 DB 3 DUP(5) ; три числа зі значенням 5 кожен var3 DD 4 DUP(0) ; чотири нульових чисел, кожен розміром 32 біта var4 DQ 5 DUP(2 DUP(2)) var5 DT ? var6 DB 6,7,8,9,10 msg DB ‘hello’, 0

.code ; директива початку сегмента команд _start: ; мітка початку програми з ім’ям _start

MOV AL,LENGTH var1 ; AL = 01 MOV AL,LENGTH var2 ; AL = 03 MOV AL,LENGTH var3 ; AL = 04 MOV AL,LENGTH var4 ; AL = 05 MOV AX,LENGTH var5 ; AX = 0001 MOV AX,LENGTH var6 ; AX = 0001 MOV AX,LENGTH msg ; AX = 0001 MOV AX,LENGTH _start ; AX = 0001 ret ; повернення керування ОС end _start ; закінчення програми з ім’ям _start Вікна налагоджувача OllyDbg для досліджування оператора

LENGTH наведено на рис. 3.2. AND, OR, NOT – порозрядні оператори для цілих констант. +, -, *, / – оператори складання, віднімання, множення і ділення

цілих чисел. EQ, NE, LT, LE, GT, GE – оператори відношення: =, ≠, <, ≤, >,

≥. Асемблер повертає значення 0ffffh, коли результатом відношення є правда, і 0 – коли брехня.

HIGH – оператор, який повертає старші 8 бітів константного виразу.

HIGHWORD – оператор, який повертає старші 16 бітів в 32-розрядному операнді.

Page 68: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

67

LOW – оператор, який повертає молодші 8 бітів константного виразу.

LOWWORD – оператор, який повертає молодші 16 біт 32-

розрядного операнда. MASK – оператор, який повертає бітову маску змінної. Бітова

маска зберігає тільки важливі біти, скидаючи всі останні в нуль. Змінна повинна бути визначена директивою RECORD.

MOD – оператор модуля: повертає цілий залишок операції ді-лення.

SHORT – оператор, який повертає атрибут мітки в SHORT. Часто використовується в командах JMP, наприклад, JMP SHORT Label.

Рис. 3.2. Вікна налагоджувача OllyDbg для досліджування оператора LENGTH

Page 69: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

68

SIZE – оператор, який повертає загальне число байтів, виділе-них для змінної. Розраховується як довжина (LENGTH), помножена на тип (TYPE).

FIELD (.) – ім’я з подальшою крапкою (.), яке визначає поле із зумовленою структурою, додаючи зсув поля до зсуву змінної. Формат: variable.field.

THIS – оператор, який створює операнд певного типу в про-грамі. Тип може визначатися оператором PTR або директивою LABEL.

TYPE – оператор повертає число, що визначає розмір або тип змінної. Наприклад, оператор TYPE для змінної типу слово повертає значення 2.

WIDTH – оператор повертає кількість бітів, займаних змінною, яка була оголошена за допомогою директиви RECORD. & – підставляє фактичне значення параметра макрокоманди. – інтерпретує текст як літерал, незалежно від спеціальних сим-

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

значення, яке він може мати. % – інтерпретує текст як вираз, обчислює його значення і замі-

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

;; – пригнічує виділення пам’яті для коментарю в макровизна-ченні.

3.3. Лабораторна робота “Подання даних”

Навчальні та виховні цілі: 1. Виконати дослідження переводу чисел з десяткової в двійкову

систему числення. Дати їх внутрішнє (машинне) подання відповідно до діапазону в знакових і беззнакових форматах типів Shortlnt (signed char), Byte (unsigned char), Integer (int), Word (unsigned int). Машинне подання даних повинне бути наведено в двійковій і шістнадцятковій системах числення.

2. Виконати дослідження переводу чисел з десяткової в двійкову систему числення. Дати їх внутрішнє (машинне) подання у форматах типів Single (float), Double (double), Extended (long double). Машинне подання даних повинне бути надане в двійковій і шістнадцятковій сис-темах числення.

Page 70: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

69

Завдання № 1 “Внутрішнє подання цілочисельних даних у IBM

PC”: – вибрати для свого варіанта цілі числа; – перевести їх з десяткової у двійкову (або шістнадцяткову) систе-

му числення; – одержати їх внутрішнє подання; – написати програму опису цих чисел мовою асемблеру й одержати

листинг програми; – перевірити правильність своїх викладень. Завдання №2 “Внутрішнє подання дійсних даних у IBM PC”: – обчислити для свого варіанта дійсні числа; – перевести їх з десяткової у двійкову систему числення і зробити

нормалізацію чисел; – одержати їх внутрішнє подання (числа вказує викладач); – написати програму опису цих чисел мовою асемблеру й одержати

листинг програми; – перевірити правильність своїх викладень.

Зміст звіту 1. Постановка задачі для конкретного варіанта. 2. Протокол перевод всіх заданих чисел з десяткової у двійкову і

шістнадцяткову системи числення. 3. Листинг програм. 4. Висновки за результатами роботи.

Порядок виконання роботи Для виконання завдання №1 необхідно вибрати свій варіант із

табл. 3.3 та записати чотири числа зі знаками. Наприклад, для 20-го варіанта цілі числа будуть такі:

+ 3200 + 115 – 3200 – 115

Написати програму з використанням всіх директив визначення да-них. Правильність одержаних результатів необхідно проконтролювати. Як приклад, напишемо програму з ім’ям Lab1.asm (листинг 3.3).

Page 71: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

70

Таблиця 3.3 Варіанти завдань

Листинг 3.3. Програма подання цілих чисел: .386 ; директива визначення типу мікропроцесора .model flat ; завдання лінійної моделі пам’яті .data ; директива визначення даних

; цілі числа в пам’яті розміром у байт (8 розрядів) db 115 db -115

; цілі числа в пам’яті розміром у слово (16 розрядів) dw 115 dw -115 dw 3200 dw -3200

; цілі числа в пам’яті розміром у подвійне слово (32 розряди) dd 115 dd -115 dd 3200 dd -3200

.code ; директива початку коду програми start: ; мітка початку програми з ім’ям start

ret ; повернення керування ОС end start ; закінчення програми з ім’ям start

№ варіанта Завдання № варіанта Завдання ±X ±Y ±X ±Y

1 1300 20 11 2300 70 2 1400 25 12 2400 75 3 1500 30 13 2500 80 4 1600 35 14 2600 85 5 1700 40 15 2700 90 6 1800 45 16 2800 95 7 1900 50 17 2900 100 8 2000 55 18 3000 105 9 2100 60 19 3100 110

10 2200 65 20 3200 115

Page 72: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

71

Для одержання листингу програми в асемблері MASM32 (опція Fl) необхідно викликати файловий менеджер FAR та вже з нього відкомпі-лювати програму за допомогою компілятора:

Ml /c /coff /Fl Lab1.asm <Enter> Листинг програми Lab1.asm буде мати такий вигляд:

Microsoft (R) Macro Assembler Version 6.14.8444 10/25/07 07:41:23 Lab1.asm Page 1 - 1 .386 .model flat,stdcall 00000000 .data ; цілі числа 00000000 73 db 115 00000001 8D db -115 00000002 0073 dw 115 00000004 FF8D dw -115 00000006 0C80 dw 3200 00000008 F380 dw -3200 0000000A 00000073 dd 115 0000000E FFFFFF8D dd -115 00000012 00000C80 dd 3200 00000016 FFFFF380 dd -3200 00000000 .code 00000000 start: 00000000 C3 ret end start

Microsoft (R) Macro Assembler Version 6.14.8444 10/25/07 07:41:23 Lab1.asm Symbols 2 - 1 Segments and Groups: N a m e Size Length Align Combine Class FLAT . . . . . . . . . . . . GROUP _DATA . . . . . . . . ..32 Bit 0000001A DWord Public ‘DATA’ _TEXT . . . . . . . .. . .32 Bit 00000001 DWord Public ‘CODE’ Symbols: N a m e Type Value Attr @CodeSize . . . . . . . . . . .Number 00000000h @DataSize . . . . . . . . . . . Number 00000000h @Interface . . . . . . . . . . . Number 00000003h @Model . . . . . . . . . . . . Number 00000007h

Page 73: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

72

@code . . . . . . . . . . . . . Text _TEXT @data . . . . . . . . . . . . . Text FLAT @fardata? . . . . . . . . . . . Text FLAT @fardata . . . . . . . . . . . . Text FLAT @stack . . . . . . . . . . . . . Text FLAT start . . . . . . . . . . . . . L Near 00000000 _TEXT Public STDCALL 0 Warnings 0 Errors

Порядок розміщення цілих чисел у пам’яті необхідно також проко-

нтролювати за допомогою налагоджувача OllyDbg. Для цього спочатку слід одержати .exe-файл за допомогою команди

link /subsystem:console Lab1.obj. Потім треба викликати налагоджувач OllyDbg

(http://cracklab.ru/_dl/new/ollydbg110xp.rar або www.ollydbg.de/ odbg200a.zip) та загрузити одержаний файл Lab1.exe (рис. 3.3).

Проаналізувати порядок розміщення даних у пам’яті комп’ютера

та їх відповідність адресам. Для виконання завдання №2 необхідно згідно з варіантом із табл. 1

вибрати числа: 115. 3200. 115.3200 -115.-3200. -115.3200

Рис. 3.3. Розміщення цілих чисел у налагоджувачі OllyDbg

Page 74: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

73

0.115 0.32 -0.115 -0.32

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

Дійсні числа при своєму запису повинні мати точку у форматі числа. Для цього напишемо програму з ім’ям, наприклад Lab1_2.asm (лис-тинг 3.4).

Листинг 3.4. Програма подання дійсних чисел: .386 ; директива визначення типу мікропроцесора .model flat ; завдання лінійної моделі пам’яті

.data ; директива визначення даних ; дійсні числа в пам’яті розміром у 32 розряди

dd 115. dd -115. dd 0.115 dd -0.115 dd 3200. dd -3200. dd 0.32 dd -0.32 dd 115.3200 dd -115.3200

; дійсні числа в пам’яті розміром у 64 розряди dq 115. dq -115. dq 0.115 dq -0.115 dq 3200. dq -3200. dq 0.32 dq -0.32 dq 115.3200 dq -115.3200

; дійсні числа в пам’яті розміром у 80 розрядів dT 115. dT -115. dT 0.115 dT -0.115

Page 75: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

74

dT 3200. dT -3200. dT 0.32 dT -0.32 dT 115.3200 dT -115.3200

.code ; директива початку коду програми start: ; мітка початку програми з ім’ям start

ret ; повернення керування ОС end start ; закінчення програми з ім’ям start

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

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

Ml /c /coff /Fl Lab1_2.asm <Enter> Сторінка1 листингу програми Lab1_2.asm буде мати такий вигляд:

Microsoft (R) Macro Assembler Version 6.14.8444 10/25/07 08:05:00 Lab1_2.asm Page 1 - 1

.386 .model flat,stdcall 00000000 .data 00000000 42E60000 dd 115. 00000004 C2E60000 dd -115. 00000008 3DEB851F dd 0.115 0000000C BDEB851F dd -0.115 00000010 45480000 dd 3200. 00000014 C5480000 dd -3200. 00000018 3EA3D70A dd 0.32 0000001C BEA3D70A dd -0.32 00000020 42E6A3D7 dd 115.3200 00000024 C2E6A3D7 dd -115.3200 00000028 405CC00000000000 dq 115. 00000030 C05CC00000000000 dq -115. 00000038 3FBD70A3D70A3D71 dq 0.115 00000040 BFBD70A3D70A3D71 dq -0.115 00000048 40A9000000000000 dq 3200. 00000050 C0A9000000000000 dq -3200.

Page 76: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

75

00000058 3FD47AE147AE147B dq 0.32 00000060 BFD47AE147AE147B dq -0.32 00000068 405CD47AE147AE14 dq 115.3200 00000070 C05CD47AE147AE14 dq -115.3200 00000078 4005E600000000000000 dT 115. 00000082 C005E600000000000000 dT -115. 0000008C 3FFBEB851EB851EB851F dT 0.115 00000096 BFFBEB851EB851EB851F dT -0.115 000000A0 400AC800000000000000 dT 3200. 000000AA C00AC800000000000000 dT -3200. 000000B4 3FFDA3D70A3D70A3D70A dT 0.32 000000BE BFFDA3D70A3D70A3D70A dT -0.32 000000C8 4005E6A3D70A3D70A3D7 dT 115.3200 000000D2 C005E6A3D70A3D70A3D7 dT -115.3200 00000000 .code 00000000 start: 00000000 C3 ret end start Порядок розміщення дійсних чисел у пам’яті необхідно також про-

контролювати за допомогою налагоджувача OllyDbg. Для цього треба одержати .exe-файл за допомогою команди

link /subsystem:console Lab1_2.obj. Потім слід викликати налагоджувач OllyDbg та загрузити одержа-

ний файл Lab1_2.exe (рис. 3.4). Проаналізувати порядок розміщення даних у пам’яті комп’ютера

та їх відповідність адресам. Довідковий матеріал Формати даних для подання двійкових чисел. У форматі з фіксова-

ною комою числа представляються в додаткових кодах. Знак числа кодується в старшому біті (0 - “+”, 1 - “-”). Наприклад, для подання числа A = [-1990]10 скористаємося перево-

дом його в додатковий код і форматом для цілих чисел із знаком, при-чому доповнимо число А2 до п’ятнадцяти розрядів:

A = [-1990]10 = [-11111000110]2пк = [-000 0111 1100 0110]2пк = [1.111 1000 0011 1010]2дк.

Page 77: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

76

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

можуть бути типу float (32 розрядів), double (64 розряди) або long double (extended) (80 розрядів).

Внутрішнє (машинне) подання цих чисел достатньо складне:

S Характеристика Нормалізована мантиса

Біт S – знак числа. Характеристика = Зміщення ± Порядок. Зміщення – число, що дорівнює ПОЛОВИНІ максимально можли-

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

Рис. 3.4. Розміщення дійсних чисел у налагоджувачі OllyDbg

Page 78: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

77

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

Розмір простору, який ПК використовує для зберігання характерис-тики і мантиси, встановлений стандартом IEEE 724-1985 і підтримується всією сучасною комп’ютерною архітектурою.

Нормалізованим двійковим числом називається двійкове число, яке починається з одиниці і має такий вигляд:

X = ±1.m2 * 2p, де m2 – двійкова мантиса числа; р – порядок двійкового числа. Формат короткого (32-розрядного) дійсного числа:

1 – прихований розряд v

S Характеристика – 8 розрядів Нормалізована мантиса – 23 розряди 31 30 . . . 23 22 21 . . . 1 0

Зміщення складає – 7F16 = 12710. Задача № 1. Нормалізувати число А = [±0.5]10 і подати його у фор-

маті слова з плаваючою комою. Рішення А = [0.5]10 = [0.1]2 = [1.0]2 * 2-1. Характеристика: 7F – 1 = 7E. У мантисі тільки один розряд, який невидимий для людини. Тому,

мантиса дорівнює нулю. Задача №2. Подати число А = 115.10 у форматі DD з плаваючою то-

чкою. Рішення Мантиса: А = 115.10 = [1110011]2 = [1.110011]2 * 26. Характеристика: 7F + 6 = 85h = 1000 0101. Число А = [115.]10 = 0 1000 0101 1100 1100000000000000000b =

42E6 0000h. Задача №3. Подати число А = 115.3210 в форматі DD з плаваючою

точкою. Рішення Мантиса: А = 115.3210 = [1.110011.01010001111010111]2 * 26. Характеристика: 7F + 6 = 85h = 1000 0101b.

Page 79: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

78

Число: А = [115.32]10 = 0 1000 0101 110 0110 1010 0011 1101 0111 = = 42E6 A3D7h.

Формат довгого (64-розрядного) дійсного числа:

1 – прихований розряд v

S Характеристика Нормалізована мантиса 63 62 . . . 52 51 50 . . . 1 0

Зміщення складає 3FF16 = 102310. Задача №4. Подати число А = -115.3210 у форматі DQ з плаваючою

точкою. Рішення Мантиса: А = -115.3210 = [1.1100 11.01 0100 0111 1010 1110 0001

0100 0111 1010 1110 0001 0100]2 * 26. Характеристика: 3FF + 6 = 405h = 100 0000 0101. Число: А = [115.32]10 =

= 1 100 0000 0101 110 0 110 1 0100 0111 1010 1110 0001 0100 0111 1010 1110 0001 0100 = C05C D47A E147 AE14h.

Формат розширеного (80-розрядного) дійсного числа:

S Характеристика Нормалізована мантиса 79 78 . . . 64 63 62 . . . 1 0

Особливість останнього формату полягає у тому, що мантиса НЕ

МАЄ прихованого розряду. Зміщення складає 3FFF16 = 1638310. Задача №5. Подати число А = -115.3210 у форматі DT з плаваючою

точкою. Рішення Мантиса: А = 115.3210 = [0.110011.01010001111010111]2 * 26. Характеристика: 3FFF + 6 = 4005h = 100 0000 0000 0101. Число: А = [115.32]10 =

= 0 100 0000 0000 0101 1110 0110 1010 0011 1101 0111 0000 1010 0011 1101 0111 0000 1010 0011 1101 0111 = 4005 E6A3 D70A 3D70 A3D7h.

Page 80: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

79

4. ОПЕРАЦІЇ ПЕРЕСИЛАННЯ ДАНИХ 4.1. Команди пересилання даних загального призначення Команди пересилання даних загального призначення можуть за-

стосовуватись з безліччю операндів, хоча й існують деякі винятки. Ко-манди пересилання даних загального призначення (крім команди XCHG) – єдині, що дозволяють як операнд використовувати регістр се-гмента (http://www.intel.com/techtrends/technologies/ hyperthreading.htm, документ 25366717.pdf).

MOV приймач, джерело Пересилання даних

Команда MOV виконує пересилання байта чи слова з джерела

(правий операнд) у приймач (лівий операнд). MOV mem/reg1, mem/reg2

MOV ЕDX, ЕCX ; Передати подвійне слово з Рг ЕCX у Рг EDX MOV ЕBХ, [ECX] ; Передати дані з пам’яті, початкова адреса якої ; знаходиться в регістрі ЕСХ до Рг ЕBХ MOV TEMP, BL ; Передати байт із Рг ВL у масив пам’яті ; з ім’ям TEMP MOV [EDІ], BX ; Передати слово з Рг ВХ у комірку пам’яті, ; адреса якої знаходиться в Рг EDІ MOV EDX,[EBP][ESІ] ; Передати в Рг EDX дані з пам’яті, ; адреса яких визначається як сума вмістів Рг EBP і Рг ESІ

MOV mem/reg, data

MOV [EDІ], 8400H ; Занесення операнда 8400h у комірку пам’яті, ; адреса якої знаходиться в Рг EDІ

MOV [ЕBP][ЕSІ], 2CH ; Передати число 2Сh у комірку пам’яті ; за адресою, яка визначається як сума ЕBP та ЕSI

MOV ЕСХ, 87654321Н ; Передати число 87654321Н в Рг EСХ MOV AC, mem

MOV ЕAX, TEMP ; Передати дані з пам’яті з ім’ям TEMP в Рг ЕАХ

Page 81: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

80

MOV mem, AC MOV BETA, ЕAX ; Передати зміст Рг ЕАХ у пам’ять з іменем BETA

MOV sreg, mem/reg

MOV SS, BP ; Передати слово з Рг ВР у сегментний Рг SS MOV ES, [DX] ; Передати число у сегментний Рг ES з комірки ; пам’яті, адреса якої знаходиться в Рг DX

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-

Page 82: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

81

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

MOVSX приймач, джерело Пересилання з розширенням знаку Команда MOVSX копіює вміст джерела (регістр або змінна розмі-

ром у байт або слово) в приймач (16- або 32- бітовий регістр) і розши-рює знак аналогічно командам CBW/CWDE.

MOVZX приймач, джерело Пересилання з розширенням нулями

Команда MOVZX копіює вміст джерела (регістр або змінна) в

приймач (16- або 32- бітовий регістр) і виконує розширення формату приймача нулями, тобто команда

movzx ах, bl еквівалентна парі команд

mov al, bl mov ah,0

CMOVcc прм, прд Умовне пересилання даних Команди CMOVcc копіюють вміст джерела в приймач, якщо задо-

вольняється та або інша умова (табл. 4.1). Джерелом може бути регістр загального призначення або змінна, а приймачем – тільки регістр. Вимо-га, яка повинна виконуватися, – просто прирівнення до нуля або до оди-ниці тих або інших прапорців із регістра EFLAGS. Якщо використову-вати команди CMOVcc відразу після СМР (порівняння) з тими ж опера-ндами, умови набувають особливого сенсу, наприклад:

cmp ах,bх ; Порівняти ах і bx cmov ах,bх ; якщо ах < bх, то скопіювати bх в ах

Слова “вище” і “нижче” в табл. 4.1 відносяться до порівняння чисел без знака, слова “більше” і “менше” враховують знак.

Таблиця 4.1 Різновиди команди CMOVcc

Код команди Реальна умова Умова для СМР CMOVA CMOVNBE CF = 0 та ZF = 0 Якщо вище

Якщо не нижче і не дорівнює

Page 83: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

82

Закінчення табл. 4.1 CMOVAE CMOVNB CMOVNC

CF = 0 Якщо вище або дорівнює Якщо не нижче Якщо немає перенесення

CMOVB CMOVNAE CMOVC

CF = 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 Обмін операндів між собою Команда XCHG змінює байт чи слово, які адресуються операнда-

ми. Регістри сегментів не можуть бути операндами команди XCHG. XCHG reg, mem/reg XCHG AL, SEMA ; Обмін байтами між Рг AL та змінною,

; яка знаходиться в пам’яті та має ім’я SEMA

Page 84: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

83

XCHG AL, ВL ; Обмін байтами між регістрами XCHG EАХ, EСХ ; Обмін словами між регістрами

BSWAP регістр32 Обмін байтів в регістрі Команда BSWAP виконує обертання порядку байтів у 32-бітовому

регістрі. Біти 0 – 7 (молодший байт молодшого слова) міняються місця-ми з бітами 24 – 31 (старший байт старшого слова), а біти 8 – 15 (стар-ший байт молодшого слова) – з бітами 16 – 23 (молодший байт старшого слова).

mov eax,12345678h bswap eax ; в еах знаходиться 78563412h.

Щоб виконати обертання порядку байтів у 16-бітовому регістрі, слід використовувати команду XCHG:

xchg al, ah ; Обертання порядку байтів АХ. У процесорах Intel команду BSWАP можна використовувати і для

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

4.2. Організація роботи зі стеком

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

одному з принципів: останнє значення, поміщене в стек, витягується першим або останнє значення, поміщене в стек, витягується останнім. Для адресації стека використовуються регістри SS:ESP (32-розрядні програми). Регістр SP (ESP) називається вказівником стека і містить 16- або 32-розрядну адресу останнього елемента, поміщеного в стек. Якщо останнє значення, поміщене в стек, витягується першим, то подіб-на структура називається LIFO (Last In, First Out – прибув останнім, об-служений першим). Стек росте до менших адрес, тобто останнє значен-ня, що надійшло в стек, зберігається за найменшою адресою.

Мінімальний розмір операнда, яким оперують команди стекових операцій, дорівнює слову (2 байти). З цієї причини дані в стеку відстоять один від одного на величину, кратну двом. Наприклад, при розміщенні в стеку слова значення вказівника стека SP (ESP) зменшується на 2, при розміщенні подвійного слова – на 4 і т.д. При цьому молодші байти опе-рандів поміщаються в стек за молодшими адресами, а старші байти – за старшими адресами.

Page 85: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

84

Для того, щоб помістити яке-небудь значення в стек, потрібно ви-користовувати команду push. Ця команда як параметр може приймати будь-який регістр або елемент пам’яті. При цьому вміст вказівника стека SP (ESP) зменшується на 2 (для слова) або на 4 (для подвійного слова). Команда допускає один з форматів:

push reg16/reg32 ; запис в стек значення регістра push mem16/mem32 ; запис в стек змінної з пам’яті push sreg ; запис в стек із сегментного регістра (CS, DS, ES) push immed ; запис в стек безпосереднього операнда Команда PUSH (помістити) декрементує вказівник стека (регістр

ESP), потім копіює операнд-джерело у вершину стека. Команда PUSH часто використовується для розміщення в стеку параметрів перед ви-кликом процедури. Усередині процедури вона може бути використана для резервування простору в стеку під тимчасові змінні. Команда PUSH працює з операндами, розміщеними в пам’яті, з безпосередніми операн-дами і з регістровими операндами (включаючи регістри сегмента). Ко-манда PUSH зменшує ESP на розмір джерела у байтах (2 або 4) та збе-рігає зміст джерела у памяті за адресою SS:[ESP].

PUSH джерело Переслати дані у стек Команда PUSH зменшує вказівник стека на 2, якщо атрибут розмі-

ру операнда команди дорівнює 16 чи 8 бітам; у протилежному випадку вона зменшує вказівник стека на 4. Потім команда PUSH поміщає опе-ранд у нову вершину стека, на яку вказує вказівник стека.

Якщо регістр SP або ESP дорівнює 1, процесор переходить у ре-жим закриття через недостатній розмір пам’яті стека.

PUSH mem/(s)reg

PUSH ЕCX ; Завантажити в стек слово з Рг ЕСХ PUSH [ЕBX] ; Завантажити в стек дані, адреса яких знаходиться

; в Рг ЕВХ PUSH SІ ; Включення в стек регістра SІ PUSH ES ; Включення в стек сегментного регістра ES PUSH [ЕDІ] ; Включення в стек подвійного слова з пам’яті

POP джерело Зчитати дані зі стека

Page 86: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

85

Команда POP (відновити (дані) зі стека) передає слово або подвій-не слово з вершини стека (на яку вказує регістр ESP) операнда призна-чення і потім збільшує значення регістра ESP, щоб той указував на нову вершину стека. POP переміщає інформацію зі стека в регістр загального призначення, в регістр сегмента або в пам’ять. Для передачі подвійного слова зі стека в регістр загального призначення використовується спеці-альна форма команди POP.

Команда POP заміняє вміст операнда пам’яті, регістра або сегмен-тного регістра словом, знятим з вершини стека, який адресується за до-помогою 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 ; Витяг зі стека в область пам’яті,

; яка має ім’я ALPHA POP DS ; Витяг зі стека в сегментний регістр POP ЕDX ; Витяг зі стека в регістр ЕDX PUSHA

PUSHAD Переслати дані у стек усі регістри загального призначення

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,

Page 87: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

86

EDI. Існують спеціальні модифікації команди push: pushf – збереження 16-розрядного регістра прапорців процесо-

ра в стеку; pushfd – збереження 32-розрядного регістра прапорців проце-

сора в стеку. POPA

POPAD Зчитати дані зі стека усі регістри загального призначення

POPA/POPAD – витяг зі стека всіх регістрів загального призна-

чення у такому порядку: DI, SI, BP, BX, DX, CX і AX. Команди POPA/POPAD виконують дії, які зворотні діям PUSHA/PUSHAD.

Команда POPA витягає зі стека вісім 16-бітових регістрів загально-го призначення. Однак значення SP замість завантаження регістра SP знищується. Команда POPA реверсує дію команди PUSHA, відновлю-ючи значення регістрів загального призначення, які вони мали перед виконанням команди PUSHA.

Команда pop використовує ті ж типи операндів, що і команда

push. Наприклад, в програмі на листингу 41 регістр міняються вмістом. Листинг 4.1. Програма, в якій регістри міняються вмістом:

; masm32: компiляцiя – ml /c /coff А1.asm ; компонування – link /SUBSYSTEM:CONSOLE А1.obj

.386 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

.code ; директива початку коду програми start: ; мітка початку програми з ім’ям start mov eax, 2 ; eax = 2 mov ecx, 3 ; ecx = 3 push eax ; запам’ятання у стеку значення регістра eax push ecx ; запам’ятання у стеку значення регістра ecx pop eax ; зчитати дані із вершини стека в еах (eax = 3) pop ecx ; зчитати дані із вершини стека в ecx (есх = 2) ret ; повернення керування ОС end start ; закінчення програми з ім’ям start

Page 88: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

87

У зв’язку з тим, що розмірність регістрів в попередньому прикладі однакова, то передача значень пройшла успішно. Розглянемо приклад на листингу 4.2, в якому розмірність регістрів вибрана не однаковою.

Листинг 4.2. Програма, в якій розмірність регістрів вибрана не од-

наковою: ; masm32: компiляцiя – ml /c /coff 1L.asm

; компонування – link /SUBSYSTEM:CONSOLE 1L.obj .386 ; директива визначення типу мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті

; та угоди ОС Windows .code ; директива початку коду програми

start: ; мітка початку програми з ім’ям start mov ax, 3210h mov ecx, 0BA987654h push ax ; esp = esp – 2 push ecx ; esp = esp – 4 pop ax ; esp = esp + 2, ax = 7654h pop ecx ; esp = esp + 4, ecx = 3210BA98h ret ; повернення керування ОС

end start ; закінчення програми з ім’ям start Стан стека при виконанні команд push і рор має такий вигляд: Адреса стека вміст 0012FFC4 77E7EB69 початкове значення стека 0012FFC2 EB693210 після виконання push ах 0012FFBE BA987654 після виконання push ecx 0012FFC0 3210BA98 після виконання pop ах 0012FFC4 77E7EB69 після виконання pop ecx Стек росте убік зменшення адрес. Наприклад, після команди push

ах в стек додається два байти, а адреса вершини зменшується на два. Команда push ecx 4-байтова, тому вершина стека зменшується на 4.

Команда рор збільшує адресу вершини стека, але не стирає самі числа.

Стан програми з листингу 4.2 після виконання команди push ecx наведено на рис. 4.1.

Програма з листингу 4.3 підбирає залишені в стеку числа.

Page 89: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

88

Листинг 4.3. Програма, яка підбирає залишені в стеку числа:

; masm32: компiляцiя – ml /c /coff 1_1L.asm ; компонування – link /SUBSYSTEM:CONSOLE 1_1L.obj

.386 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

.code ; директива початку програми start: ; мітка початку програми з ім’ям start

mov ax, 3210h ; занесення до ах 16-кової константи mov ecx, 0BA987654h ; занесення до есх 16-кової константи push ax ; esp = esp – 2 push ecx ; esp = esp – 4 pop ax ; esp = esp + 2, ax = 7654h pop ecx ; esp = esp + 4, ecx = 3210BA98h mov ecx,[esp-6] ; ecx = BA987654h mov ax, [esp-2] ; ax = 3210h ret ; повернення керування ОС end start ; закінчення програми з ім’ям start

4.3. Команди пересилання, що працюють з акумулятором Команда ІN пересилає байт (слово, або подвійне слово) зі вступно-

го порту в регістр AL (АХ або ЕАХ). Порт вказується або байтом даних

Рис. 4.1. Програма після виконання команди push ecx

Page 90: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

89

(доступ до портів від нуля до двохсот п’ятидесяти п’яти), або номером порту в регістрі DX, що допускає звертання до 210 портів вводу.

IN приймач, джерело Зчитати дані з порту

ІN ac, port ІN ac, DX

ІN AX, 40H ; Введення слова з 40-го порту ІN AL, DX ; Введення байта з порту, адреса якого знаходиться в Рг DX

OUT приймач, джерело Записати дані в порт

Команда OUT працює подібно ІN, але передача інформації здійс-

нюється з акумулятора в порт виведення. OUT port, ac OUT DX, ac OUT 80H, AL ; Виведення байта з Рг AL через порт 80H OUT DX, AX ; Виведення слова з Рг АХ через порт,

; адреса якого зазначена у Рг DX

CWD Конвертація слова в подвійне слово CDQ Конвертація подвійного слова в слово, збільшене учетверо

Команда CWD перетворює слово в АХ в подвійне слово, молодша

половина якого (біти 0 – 15) залишається в АХ, а старша (біти 16 – 31) розташовується в DX.

Команда CDQ виконує аналогічну дію по відношенню до подвій-ного слова в ЕАХ, розширюючи його до збільшеного учетверо слова в EDX:EAX.

Ці команди лише встановлюють всі біти регістра DX або EDX в значення, що дорівнює величині старшого біта регістра АХ або ЕАХ, зберігаючи таким чином його знак.

CBW

CWDE Конвертація байта в слово Конвертація слова в подвійне слово

Команда CBW розширює байт, що знаходиться в регістрі AL, до

слова в АХ. Команда CWDE розширює слово в АХ до подвійного слова в ЕАХ. Команди CWDE і CWD відрізняються тим, що CWDE розміщує

Page 91: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

90

свій результат в ЕАХ, тоді як CWD, що виконує таку саму дію, розташо-вує результат в парі регістрів DX:AX. Так само, як і в командах CWD/CDQ, розширення виконується шляхом установлення кожного біта старшої половини результату, що дорівнює старшому біту початко-вого байта або слова, тобто

mov al,0F5h ; AL = 0F5h = 245 = –11. cbw ; Тепер АХ = 0FFF5h = 65 525 = – 11.

XLAT адреса XLATВ

Трансляція відповідності до таблиці

Команда XLAT здійснює пошук у таблиці і заміну операнда на від-

повідний байт із таблиці. Вміст регістра AL заміняється вмістом комірки пам’яті ES:BX (ES:EBX), адреса якої визначається як зміщення, що зберігалося в Рг AL відносно Рг ВХ (EBX). Обраний таким способом однобайтовий операнд пересилається в регістр AL.

За аргумент для XLAT можна вказати ім’я таблиці, але ця інформа-ція процесором не використовується. Якщо ж вона не потрібна, то мож-на використати форму XLATВ (листинг 4.4).

Листинг 4.4. Програма дослідження команди xlatb: ; masm32: компiляцiя – ml /c /coff 1L.asm

; компонування – link /SUBSYSTEM:CONSOLE 1L.obj .386 ; директива визначення типу мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті

; та угоди ОС Windows .code ; директива початку коду програми

start: ; мітка початку програми з ім’ям start mov al, 0Ch ; занесення до al числа 0Ch mov еbx, offset table ; занесення до bx адреси

; розташування у пам’яті змінної з ім’ям table хlatb ; пошук у таблиці і заміна операнда

ret ; повернення керування ОС end start ; закінчення програми з ім’ям start

Стан налагоджувача до моменту виконання програми з листин-

гу 4.4 наведено на рис. 4.2.

Page 92: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

91

З рис. 4.3 видно, що в результаті виконання програми до регістру ЕАХ занесене число, яке розташовувалося в 6-й комірці пам’яті.

А якщо у сегменті даних, на який вказує ES, було tabl db “0123456789ABCDEF”

то в AL розміщується не число ОСh, а ASCII– код літери С.

4.4. Команди пересилання типу адреса – об’єкт Розглянуті команди відрізняються від інших команд передачі тим,

що при їх виконанні в адресований регістр передаються не дані, а адре-си. Основне застосування команд – це ініціалізація регістрів перед вико-нанням ланцюгових команд.

Стан налагоджувача після виконання програми з листингу 4.4 на-

ведено на рис. 4.3.

Рис. 4.2. Стан налагоджувача до моменту виконання програми з листингу 4.4

Рис. 4.3. Стан налагоджувача після виконання програми з листингу 4.4

Page 93: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

92

LEA приймач, джерело Обчислення ефективної адреси

LEA (LDS) ( LES) reg, mem Команда LEA (завантаження виконавчої адреси) передає зміщення,

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

lea bx, [bx] [sі] lea esi,mas1 ; занесення адреси початку елементів масиву mas1

Команду LEA часто використовують для виконання арифметичних обчислень, наприклад множення

lea bx,[ebx + ebx*4] ; BX = EBX × 5 або додавання

lea ebx,[eax + 12] ; EBX = EAX + 12 Ці команди не змінюють прапорці.

LDS прм, джерело Завантажити адресу, використовуючи DS LES прм, джерело Завантажити адресу, використовуючи ES LFS прм, джерело Завантажити адресу, використовуючи FS LGS прм, джерело Завантажити адресу, використовуючи GS LSS прм, джерело Завантажити адресу, використовуючи SS

LDS SІ, [DІ] LES BP, ALPHA Другий операнд (джерело) для всіх цих команд – змінна в пам’яті

розміром в 32 або 48 біт (залежно від розрядності операндів). Перші 16 або 32 біти з цієї змінної завантажуються в регістр загального призна-чення, вказаний як перший операнд, а наступні 16 бітів – у відповідний сегментний регістр (DS для LDS, ES для LES і т. д.). У захищеному режимі значення, що завантажується в сегментний регістр, завжди по-винне бути правильним селектором сегмента (у реальному режимі будь-яке число може використовуватися як селектор).

4.4. Команди пересилання бітів умов Існує чотири команди пересилання бітів умов.

Page 94: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

93

LAHF Завантажити регістр АН значеннями бітів умов Команда LAHF (завантажити регістр АН значеннями бітів умов)

передає біти умов SF, ZF, AF, PF і CF у регістр АН.

SAHF Завантажити біти умов з регістра АН Команда SAHF (завантажити біти умов з регістра АН) передає біти

умов з регістра АН в однорозрядні регістри SF, ZF, AF, PF і SF.

PUSHF PUSHFD

Завантажити регістр FLACS у стек Завантажити регістр ЕFLACS у стек

Команда PUSHF (засилання бітів умов у стек) зменшує вказівник

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

PUSHF ; Включення в стек прапорців

POPF POPFD

Завантажити регістр FLACS зі стека Завантажити регістр ЕFLACS зі стека

Команда POPF (витягання бітів умов ІP стека) пересилає біти

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

POPF ; Витягання зі стека в регістр прапорців

STC Встановити прапорець переносу CF CLC Зкинути прапорець переносу CF CMC Інвертувати прапорець переносу CF STD Встановити прапорець напряму DF CLD Зкинути прапорець напряму DF CLI Заборона переривання

Команда CLI скидає прапорець IF в 0. Після виконання цієї коман-

ди процесор ігнорує всі переривання від зовнішніх пристроїв (окрім NMI). У захищеному режимі ця команда, так само як і всі інші команди,

Page 95: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

94

що модифікують прапорець IF (POPF або IRET), виконується, тільки якщо програмі дані відповідні привілеї (CPL ≤ IOPL).

STI Дозволити переривання Команда STI встановлює прапорець IF в 1, відміняючи тим самим

дію команди CLI.

SALC Встановити AL відповідно до CF Команда SALC встановлює AL в 0FFh, якщо прапорець CF = 1, і

скидає в 00h, якщо CF = 0. Це недокументована команда з кодом 0D6h.

Page 96: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

95

5. АРИФМЕТИЧНІ ТА ЛОГІЧНІ ОПЕРАЦІЇ

5.1. Арифметичні операції

МП виконує основні математичні дії (з різноманітними модифіка-ціями) з урахуванням знака і без нього. Для чисел зі знаком прийняте стандартне подання в додатковому коді. При виконанні арифметичних дій встановлюються чи скидаються шість бітів умов: CF, AF, ZF, SF, PF, OF.

Команди додавання

ADD приймач, джерело Додавання ADС приймач, джерело Додавання з урахуванням перенесення

Команда ADD здійснює додавання операндів і запам’ятовує ре-

зультат за адресою, що задається першим операндом. ADD mem/reg1, mem/reg2 ADD [EBX], ECX ; додати ECX до комірки пам’яті,

; адреса якої находиться у Рг EBX ADD ECX, EDX ; ECX := ECX + EDX ADD EDІ, ALPHA ; EDI := EDI + ALPHA – додати змінну

; з пам’яті з ім’ям ALPHA до Рг EDІ ADD mem/reg, data ADD AL, 02H ; AL := AL + 0216 ADD BETA, 0FFH ; додати константу FFH до змінної у пам’яті

; з ім’ям BETA Команда ADC здійснює додавання операндів і вмісту біта CF, ре-

зультат запам’ятовується за адресою першого операнда. ADC mem/reg1, mem/reg2 ADС ECX, EDX ; EСX := ECX + EDX + C, регістр – регістр ADС EDІ, ALPHA ; EDІ = EDІ + ALPHA + CF – додати змінну ; з пам’яті з ім’ям ALPHA до Рг EDІ та вміст біта CF

Page 97: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

96

ADC mem/reg, data ADC ЕAX, 7777H ; ЕAX = ЕAX + 00007777H + CF (прапорець CF)

Листинг 5.1. Програма додавання двох чисел розміром у слово: ; masm 32: ml /c /coff 1_1L.asm ; link /SUBSYSTEM:CONSOLE 1_1L.obj

.386 ; директива визначення типу мікропроцесора

.MODEL flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows DATA segment ; початок сегмента даних X DW 5 ; резервування в пам’яті 2-х байтів для змінної Х Y DW 3 ; резервування в пам’яті 2-х байтів для змінної Y Z DW ? ; резервування в пам’яті 2-х байтів для змінної Z .CODE ; директива початку сегмента команд

begin: ; мітка початку основного тіла програми MOV AX,X ; завантаження операнда Х ADD AX,Y ; додавання операндів Х та Y MOV Z,AX ; збереження результату у пам’яті у комірці з ім’ям Z RET ; вихід із ОС Windows END begin ; закінчення програми з іменем begin Вікна налагоджувача OllyDbg з програмою з ім’ям 1_1L.exe наве-

дено на рис. 5.1. Рис. 5.1. Вікна налагоджувача OllyDbg з програмою з листингу 5.1

Page 98: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

97

Листинг 5.2. Програма додавання з 8- та 16-ковими регістрами:

; masm32: ml /c /coff 2.asm ; link /SUBSYSTEM:CONSOLE 2.obj .386 ; директива визначення типу мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

.code ; директива початку сегмента команд start: ; мітка початку програми з ім’ям start

mov al, -120 ; al = 88h – пересилання до al mov bl, -127 ; bl = 81h – пересилання до bl add al, bl ; додавання – al = 09h, O = 1, С = 1, S = 0 mov ах, -120 ; al = f f88h, mov bx, -127 ; bx = f f81h = -127 add ax, bx ; ax = f f09h = -247, O = 0, S = 1 ret ; повернення керування ОС

end start ; закінчення програми з ім’ям start Вікна налагоджувача OllyDbg з програмою листингу 5.2 наведено

на рис. 5.2.

Рис. 5.2. Вікна налагоджувача OllyDbg з програмою з листингу 5.2

Page 99: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

98

Програма з листингу 5.2 починається із спроби скласти два числа -120 та -127, що зберігаються в байтах AL і BL. 8-розрядні регістри здат-ні мати 28 = 256 різних станів. Тому, результат виконання команди

add al, bl ; al = 09h буде невірний. Щоб отримати правильний результат, в програмі здійс-нено розширення регістрів до розміру в слово. В такому випадку резуль-тат додавання двох чисел розміром у слово, який буде збережено в ре-гістрі ЕAX та дорівнюватиме 0FF09h.

Листинг 5.3. Програма додавання двох чисел розміром в байт. Ре-

зультат операції зберігається у пам’яті: .386 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

.data ; директива визначення даних op1b db -30 ; визначення у пам’яті операнда розміром у байт op2b db -12 ; визначення у пам’яті операнда розміром у байт sumb db (0) ; визначення у пам’яті результату розміром у байт

.code ; директива початку сегмента команд start: ; мітка початку програми з ім’ям start

mov cl, op1b ; сl = E2h – завантаження до cl mov al, op2b ; bl = F4h – завантаження до al add al, cl ; al = D6h – додавання двох операндів mov sumb,al ; збереження результату у пам’яті ret ; повернення керування ОС end start ; закінчення програми з ім’ям start Результатом виконання програми буде число D6h (рис. 5.3). У пам’яті дані будуть розміщуватися в такій послідовності:

E2, F4, D6. Результатом додавання перших двох чисел розміром у байт буде

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

У пам’яті дані будуть розміщуватися в такій послідовності:

F0, F9, E9, F0, FF F9 FF, E9, FF

op1b op2b sumb op1w op2w sumw

Page 100: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

99

Вікна відладчика OllyDbg з програмою з листингу 5.3 наведені на

рис. 5.3.

Листинг 5.4. Програма додавання двох чисел розміром в байт та слово. Результат операції зберігається у пам’яті:

.386 ; директива визначення типу мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows .data ; директива визначення даних

op1b db -16 ; визначення у пам’яті операнда розміром у байт op2b db -7 ; визначення у пам’яті операнда розміром у байт sumb db (?) ; визначення у пам’яті результату розміром у байт

op1w dw -16 ; визначення у пам’яті операнда розміром у слово op2w dw -7 ; визначення у пам’яті операнда розміром у слово sumw dw (0) ; визначення у пам’яті результату розміром у слово

.code ; директива початку сегмента команд start: ; мітка початку програми з ім’ям start

mov cl, op1b ; al = F0h mov al, op2b ; bl = F9h

Рис. 5.3. Вікна налагоджувача OllyDbg з програмою з листингу 5.3

Page 101: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

100

add al, cl ; al = E9h – додавання двох операндів mov sumb,al ; sumb := E9h – збереження результату 1 mov cx, op1w ; завантаження операнда розміром у слово add cx, op2w ; додавання двох операндів розміром у слово mov sumw, cx ; збереження результату 2

ret ; повернення керування ОС end start ; закінчення програми з ім’ям start Вікна налагоджувача OllyDbg з програмою з листингу 5.4 наведено

на рис. 5.4. За результатом виконання команди add ax, bx у регістрі ЕАХ буде

число 0000 FF09.

ІNС приймач Додавання одиниці (інкремент) Команда ІNC збільшує на "1" вміст адресного елемента і розміщає

результат за тією ж адресою.

Рис. 5.4. Вікна налагоджувача OllyDbg з програмою з листингу 5.4

Page 102: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

101

ІNC mem/reg ІNC BL ; bl := bl + 1 (8-розрядний регістр) ІNC ECX ; ecx := ecx + 1 (32-розрядний регістр) ІNC GAMMA[ЕDІ] ; збільшити на 1 адресу комірки пам’яті

; з іменем GAMMA, адреса якої находиться в Рг EDІ

XADD приймач, джерело Обміняти між собою та додати 80486 При виконанні команди XADD джерелом є завжди регістр, а прий-

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

ААА ACSII– корекція після додавання Команда ААА корегує суму двох неупакованих двійково-

десяткових чисел в AL. Якщо корекція приводить до десяткового пере-несення, АН збільшується на 1. Цю команду краще використовувати відразу після команди складання двох таких чисел. Наприклад, якщо при складанні 05 і 06 в АХ опиниться число 000Bh, то команда ААА скорегує його в 0l0lh (неупаковане десяткове 11). Прапорці CF і OF встановлюються в 1, якщо відбулося перенесення з AL в АН, інакше вони дорівнюють нулю. Значення прапорців OF, SF ZF і PF не визначе-ні.

DAA BCDI– корекція після додавання Команда DAA здійснює корекцію числа в регістрі AL, отриманого

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

Якщо ця команда виконується відразу після ADD (ADC, INC або XADD) і в регістрі AL знаходиться сума двох упакованих двійково-десяткових чисел, то в AL записується упаковане двійково-десяткове число, яке повинне було стати результатом складання. Наприклад, якщо AL містить число 19h, послідовність команд

inc al daa

призведе до того, що в AL опиниться 20h (а не 1Ah, як було б після ко-манди INC).

Команда DAA виконує такі дії: 1. Якщо молодші чотири біти AL більше 9 або прапорець AF = 1, то

Page 103: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

102

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 приймач, джерело Віднімання Команда SUB (http://www.intel.com/techtrends/technologies/

hyperthreading.htm, документ 25366717.pdf) здійснює віднімання другого операнда із першого. Результат записується за адресою першого операн-да

SUB mem/reg1, mem/reg2 SUB ECX, EBX ; ECX := ECX – EBX SUB EDX, ALEX[ESІ] ; Відняти з Рг EDX зміст комірки пам’яті

; з іменем ALEX, адреса якої находиться у Рг ESІ SUB [EBP+2], ECX ; [EBP + 2] := [EBP+2] – ECX SUB mem/reg, data SUB AL, 10Н ; AL := AL – 10h SUB [SІ], 0F000H ; [SІ] := [SІ] – F000h

Команда SBB здійснює віднімання із вмісту, що адресується дру-

гому операнду вмісту, що адресується першим операндом із врахуван-ням вмісту регістра CF.

SВB mem/reg1, mem/reg2 SBB EAX, EBP ; EAX := EAX – EBP – CF SBB {EBP + 40H], EBX ; [EBP + 40H] := [EBP + 40H] – EBX – CF

SВB mem/reg, data SBB [EDІ], 30Н ; [EDІ] := [EDІ] – 30h –CF

SВB приймач, джерело Віднімання з позиченням

Page 104: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

103

Листинг 5.5. Віднімання багатобайтових чисел різного розміру: .686 ; директива визначення типу мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows .data ; директива визначення даних op1 dq 1311768467463790320 ; 123 4567 89ABC DEF0h len equ $-op1 ; обчислення кількості байтів змінної ор1 op2d dd 180080352 ; 0ABB CEE0h op2 dq 0 ; rez dq 0 ; резервування комірок пам’яті для змінної rez

.code ; директива початку сегмента команд start: ; мітка початку програми з ім’ям start

mov ecx, len ; занесення у регістр-лічильник кількості байтів ор1 mov eax,op2d ; занесення ор2 (32 розряда) до Рг ЕАХ cdq ; перетворення подвійного слова в 64 розряди – EDX:EAX

mov dword ptr op2,eax ; збереження молодших розрядів в масиві op2 mov dword ptr op2+4,edx ; збереження старш. розрядів в масиві op2 xor eax,eax ; заповнювання нулями ЕАХ (додавання “виключне АБО”)

clc ; скидання прапорця CF lea esi,byte ptr op1 ; занесення адреси ор1 до Рг ESI lea edi,byte ptr op2 ; занесення адреси ор2 до Рг EBX lea ebx,byte ptr rez ; занесення адреси результату rez до Рг EBX

m1: mov al,[esi] ; занесення байта з числа ор1

sbb al,[edi] ; віднімання з урахуванням ознаки CF mov byte ptr [ebx],al ; занесення до rez через [EBX] байта резул.

inc esi ; збільшення адреси ор1 inc edi ; збільшення адреси ор2 inc ebx ; збільшення адреси rez dec ecx ; ECX := ECX – 1 jnz m1 ; перейти до m1, якщо z ≠ 0 lea eax,rez ; занесення адреси масиву rez

ret ; повернення керування ОС end start ; закінчення програми з ім’ям start Початковий вигляд вмісту комірок пам’яті в масиві даних наведено

на рис. 5.5. Стан виконання програми з листингу 5.5 наведено на рис. 5.6.

Page 105: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

104

Рис. 5.5. Початковий вигляд вмісту комірок пам’яті в масиві даних про-грами з листингу 5.5

Рис. 5.6. Стан виконання програми з листингу 5.6

Page 106: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

105

DEC Декремент Команда DEC віднімає одиницю з вмісту адресованого елемента і

запам’ятовує результат за тією ж адресою. DEC [EBP] ; зменшити на 1 вміст комірки пам’яті (стека),

; адреса якої находиться в Рг EBP DEC AL ; зменшити на 1 вміст Рг AL розміром 8 бітів DEC EBX ; EBX := EBX – 1 NEG приймач Зміна знака

Команда NEG здійснює віднімання вмісту адресованого елемента з

нуля і розміщує результат на тому ж місці (зміни знака для утворення додаткового коду).

NEG reg

CMP приймач, джерело Порівняння Команда СМР (порівняння) здійснює віднімання подібно команді

SUB, установлює біти умов, але не здійснює запам’ятовування резуль-тату.

CMP mem/reg1, mem/reg2 CMP mem/reg, data

CMPXCHG приймач, джерело Порівняти і обміняти між собою 80486

Команда CMPXCHG порівнює значення, що містяться в AL, АХ,

ЕАХ (залежно від розміру операндів), з приймачем (регістром). Якщо вони рівні, інформація з джерела копіюється в приймач і прапорець ZF встановлюється в 1, інакше вміст приймача копіюється в AL, АХ, ЕАХ і прапорець ZF встановлюється в 0. Решта прапорців визначається за ре-зультатом операції порівняння, як після СМР. Джерело – завжди ре-гістр, приймач може бути регістром і змінною.

CMPXCHG8B приймач Порівняти і обміняти 8 байт Р5 Команда CMPXCHG8B виконує порівняння вмісту регістрів

EDX:EAX як 64-бітового числа (молодше подвійне слово – в ЕАХ, ста-рше – в EDX) з приймачем (8-байтова змінна в пам’яті). Якщо вони рів-

Page 107: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

106

ні, вміст регістрів ЕСХ:ЕВХ як 64-бітове число (молодше подвійне сло-во в ЕВХ, старше – в ЕСХ) поміщається в приймач. Інакше вміст прий-мача копіюється в EDX:EAX.

AAS ACSII– корекція після віднімання

Команда AAS здійснює корекцію числа в регістрі AL, отриманого

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

DAS BCD–корекція після віднімання

Команда DAS здійснює корекцію результату віднімання двох упа-

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

Якщо ця команда виконується відразу після SUB (SBB або DEC) і в регістрі AL знаходиться різниця двох упакованих двійково-десяткових чисел, то в AL записується упаковане двійково–десяткове число, яке повинне було бути результатом віднімання. Наприклад, якщо AL містить число 20h, послідовність команд

dec al das

призведе до того, що в регістрі опиниться 19h (а не 1Fh, як було б після DEC).

DAS виконує такі дії: 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

Page 108: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

107

Після 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.

Множене Множник Результат

AL оператор_8 AX AX оператор_16 DX:AX EAX оператор_32 EDX:EAX

MUL reg

MUL ECX ; EDX, EAX ← ECX × EAX MUL BL ; Перемножити вміст регістрів AL і BL без знаків

; із запам’ятовуванням результату в Рг AH та AL MUL mem

MUL [EDІ – 40H] ; Перемножити вміст Рг EAX і операнда ; з пам’яті, адреса якого знаходиться в Рг EDІ з урахуванням ; зміщення – 40Н (без знака). ; Результат запам’ятовується в Рг EDX і EAX MUL [0040] ; DX, AX ← [0040] × AX, DH = 00

Як приклад розглянемо виконання операції множення. На першому

етапі виконується множення двох операндів op1_w і op2_w, що мають

MUL джерело Множення чисел без знаків

Page 109: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

108

розмірність слова, а результат поміщається в змінну res1_w розмірніс-тю в подвійне слово.

На другому етапі виконується множення операнда op_b розмірніс-тю в 1 байт на op_w, що має розмірність слова, і результат поміщається в двословну змінну res2_w (листинг 5.6). Для розширення розмірності операнда op_byte використовується команда movzx (Move with Zero-Extend – копіювання з розширенням нуля).

Листинг 5.6. Перемноження чисел різної розмірності:

.686 ; директива визначення типу мікропроцесора

.model flat ; завдання лінійної моделі пам’яті option casemap: none ; відмінність малих та великих літер

.data ; директива визначення даних op1_w DW 46 ; перший операнд розміром у слово op2_w DW 65535 ; другий операнд розміром у слово res1_w DW 2 dup(0) ; комірка розміром у 2 слова для res1_w

op_b DB 25 ; запис в пам'ять з ім’ям op_b 8-розрядного числа 25 op_w DW 65244 ; запис в 16-розрядну комірку пам’яті числа 65244

res2_w DD 0 ; комірка розміром у 2 слова для res2_w .code ; директива початку сегмента команд

_start: ; мітка початку програми з ім’ям _start ; перемноження op1_w на op2_w

mov AX,op1_w mov BX, op2_w mul BX ; DX,AX := AX × BX mov word ptr res1_w, AX mov word ptr res1_w+2, DX

; перемноження op_b на op_w movzx AX, op_b ; беззнакове розширення операнда op_b mov BX, op_w mul BX ; DX,AX := AX × BX mov word ptr res2_w, AX mov word ptr res2_w+2, DX ret ; повернення керування ОС end _start ; закінчення програми з ім’ям _start Стан програми перемноження чисел різної розмірності після її ви-

конання наведено на рис. 5.7.

Page 110: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

109

IMUL джерело IMUL приймач, джерело

Множення чисел без знаків

8086 80386

Команда ІMUL подібна команді MUL, але за нею виконується мно-

ження з урахуванням знака. Біти умов CF і OF установлюються, якщо старша половина результату не є розширенням для формування знака молодшої половини.

ІMUL reg ІMUL EСХ ; EDX, EАХ = EAХ × EСХ зі знаками

ІMUL mem ІMUL ALPHA ; EDX, EАХ = EАХ × [ALPHA] з урахуванням знаків

Команда ІMUL має дві форми, що розрізняються числом операндів:

Рис. 5.7. Стан програми перемноження чисел різної розмірності після її виконання

Page 111: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

110

1. IMUL джерело – джерело (регістр або змінна) помножується на AL/АХ/ЕАХ (залежно від розміру операнда), і результат розташовується в АХ DX:AX або EDX:EAX відповідно.

2. IMUL приймач, джерело – джерело (число, регістр або змінна) помножується на приймач (регістр), і результат заноситься в приймач.

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

більше місця, ніж розмір джерела. У першому випадку приймач автома-тично виявляється дуже великим, але в другому і третьому випадках існує вірогідність переповнювання і втрати старших бітів результату. Прапорці OF і CF будуть дорівнювати одиниці, якщо це відбулося, і нулю, якщо результат множення помістився цілком в приймачі (у дру-гому і третьому випадках) або в молодшій половині приймача (у пер-шому випадку).

Значення прапорців SF, ZF, AF і PF після команди IMUL не визна-чені.

Розглянемо приклад множення однобайтового негативного операн-

да на подвійне слово (листинг 5.7). Листинг 5.7. Множення однобайтового негативного операнда на

подвійне слово: .686 ; директива визначення типу мікропроцесора .model flat ; завдання лінійної моделі пам’яті option casemap: none ; відмінність малих та великих літер .data ; директива визначення даних

op_b DB -46 ; -46 = D2h – один байт op_dword DD 678 ; 678 = 2A6h – чотири байта op_rez DQ 0 ; десять байтів з нульовим вмістом

.code ; директива початку сегмента команд start: ; мітка початку програми з ім’ям _start

movsx AX,op_b ; AX := FFD2 – знакове розширення movsx EAX,AX ; EAX := FFFF FFD2 – знакове розширення mov EBX,op_dword ; EBX := 0000 02A6 imul EBX ; ЕDX,ЕAX := ЕAX × ЕBX mov dword ptr op_rez,EAX mov dword ptr op_rez+4,EDX lea EAX,op_rez ; збереження адреси результату ret ; повернення керування ОС

Page 112: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

111

end start ; закінчення програми з ім’ям _start Стан комірок пам’яті до початку виконання програми наведено на

рис. 5.8. Стан програми перемноження знакових чисел різної розмірності пі-

сля її виконання наведено на рис. 5.9. У даному прикладі задіяні два операнди: op_b розміром в 1 байт і

двословна змінна op_dword. Результат операції поміщається в 8-бітову змінну op_rez. Перед виконанням множення необхідно розширити роз-мірність операнда op_b до подвійного слова. Для цього використову-

Рис. 5.8. Стан комірок пам’яті до початку виконання програми

Рис. 5.9. Стан програми перемноження знакових чисел різної розмірності після її виконання

Page 113: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

112

ються дві команди movsx (Move with Sign Extend – копіювання з розши-ренням знака).

Перша команда movsx поміщає 8-бітовий операнд в 16-розрядний регістр АХ, розширюючи знак на старшу половину АХ (регістр АН). Друга команда movsx перетворює 16-розрядне значення в 32-розрядне і поміщає його в регістр ЕАХ. Можна виконати й одну команду

movsx ЕAX,op_b Якщо множене і множник мають однаковий знаковий біт, то ко-

манди mul і imul генерують однаковий результат. Але якщо співмнож-ники мають різні знакові біти, то результатом виконання команди mul буде позитивне число, тоді як команда imul дасть негативне значення.

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

ААМ ACSII– корекція після множення

Команда ААМ корегує результат множення неупакованих двійко-

во-десяткових чисел, який знаходиться в АХ після виконання команди MUL, перетворюючи одержане в пару неупакованих двійково-десяткових чисел (у АН і AL). Наприклад:

mov al,5 mov bl,5 ; bl ← 5 mul bl ; AH,AL ← al × bl aam ; АХ містить 0205h. Команда ААМ встановлює прапорці SF, ZF і PF відповідно до ре-

зультату і залишає OF, AF і CF невизначеними. Код команди ААМ – D4h 0Ah, де 0Ah – основа системи числення,

по відношенню до якої виконується корекція. Цей байт можна замінити на будь-яке інше число (окрім нуля), і ААМ перетворить АХ на дві неу-паковані цифри будь-якої системи числення. Така узагальнена форма ААМ працює на всіх процесорах (починаючи з 8086), але з’являється в документації Intel тільки з процесорів Pentium. Фактично дія, яку вико-нує ААМ, – цілочисельне ділення AL на 0Ah (або будь-яке інше число в загальному випадку), частка поміщається в АН і залишок – в AL, тому

Page 114: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

113

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

Команди ділення

DІV джерело Цілочисельне ділення чисел без знаків Команда DІV здійснює ділення без знака вмісту акумулятора і його

розширення (AL і АН для 8-розрядної операції, АХ і DX – для 16-розрядної, ЕАХ і ЕDX – для 32-розрядної) на вміст, що адресується операндом, і розміщує частку в акумуляторі (AL/АХ/EAX) та залишок одинарної довжини в розширенні акумулятора (АН/DX/EDX). Біти умов не змінюються. Ділення на нуль дає переривання за вектором 0.

DІV reg/mem/data

Ділене Дільник Частка Залишок AX оператор_8 AL AH

DX:AX оператор_16 AX DX EDX:EAX оператор_32 EAX EDX

DІV 8H ; Поділити вміст Рг АХ на 8Н без врахування знака. ; Результат формується у Рг AL, а залишок – у Рг AH. DІV [BP + 20H] ; Поділити вміст регістрів DX і AX на число,

; адреса якого знаходиться в Рг BP з урахуванням зміщення + 20Н. IDІV джерело Цілочисельне ділення чисел зі знаком

Команда ІDIV працює подібно команді DІV, за винятком того, що

вона здійснює ділення з урахуванням знака. ІDІV reg/mem AAD ACSII– корекція перед діленням

Команда AAD здійснює корекцію діленого в регістрі перед ділен-

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

Команда AAD виконує корекцію неупакованого двійково-десяткового числа, що знаходиться в регістрі АХ, тому подальше ділен-

Page 115: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

114

ня привело до десяткового результату. Наприклад, розділимо десяткове 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 можна використовувати для швидкого множення на будь-яке число.

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

Для ділення беззнакових даних використовується команда div, а для знакових – idiv. Залежно від розмірності операндів існують такі формати операції ділення:

– Ділення слова на байт. Ділене знаходиться в регістрі АХ, а діль-ник – в байті пам’яті або в однобайтовому регістрі. Після ділення зали-шок поміщається в регістр АН, а частка – в AL. Операція з даними типа-ми операндів має обмежене застосування через невеликий діапазон до-пустимих значень (однобайтова частка не перевищує +255 для беззнако-вого ділення і +127 – для знакового).

– Ділення подвійного слова на слово. Ділене знаходиться в регіст-ровій парі DX:АХ, а дільник – в слові пам’яті або в регістрі. Після ділен-ня залишок поміщається в регістр DX, а частка – в регістр АХ. Частка в одному слові допускає максимальне значення +32 767 для беззнакового ділення і +16 383 – для знакового.

– Ділення збільшеного учетверо слова на подвійне слово. Ділене знаходиться в регістровій парі EDX:ЕАХ, а дільник – в подвійному слові пам’яті або в регістрі. Після ділення залишок поміщається в регістр EDX, а частка – в регістр ЕАХ.

Команди div і idiv мають єдиний операнд, що є дільником.

Page 116: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

115

Як приклад розглянемо ділення 64-розрядного беззнакового числа на однобайтове ціле. Програму ділення беззнакового числа на байт на-ведено в листингу 5.8.

Листинг 5.8. Ділення беззнакового числа на байт: .686 ; директива визначення типу мікропроцесора .model flat ; завдання лінійної моделі пам’яті

option casemap: none ; відмінність малих та великих літер .data ; директива визначення даних

div1 DQ 1234 ; 1234 = 4D2h div2 DB 74 ; запис у 8-розр. комірку пам’яті з ім’ям div2 числа 74 = 4Ah

res1 DD 0 ; резервування комірки для збереження цілої частини res2 DD 0 ; резервування комірки для збереження залишку

.code ; директива початку сегмента команд start: ; мітка початку програми з ім’ям _start

movzx BX, div2 ; BX = 004Ah movzx EBX, BX ; EBX = 0000 004Ah mov EAX, dword ptr div1 ; EAX = 0000 04D2h mov EDX, dword ptr div1+4 ; EDX = 0000 0000h div EBX ; EDX,EAX = EAX/EBX mov res1, EAX ; збереження цілої частини результату mov res2, EDX ; збереження залишку результату ret ; повернення керування ОС end start ; закінчення програми з ім’ям _start

Стан комірок пам’яті до початку виконання програми з листин-

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

її виконання показано на рис. 5.11. У програмі з листингу 5.8 ділене знаходиться в змінній div1, а діль-

ник – в змінній div2.

Рис. 5.10. Стан комірок пам’яті до початку виконання програми

Page 117: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

116

Готуємо операцію ділення. Для цього поміщаємо молодше подвій-

не слово діленого в регістр ЕАХ, а старше подвійне слово змінної – в регістр EDX. Нарешті, після виконання операції ділення зберігаємо час-тку в змінній res1, яка дорівнює 10h, а залишок – в змінній res2.

Ділення знакових чисел виконується за допомогою команди idiv

Модифікуємо попередній приклад. Для цього потрібно замінити коман-ду div на idiv і використовувати замість команд movzx команди movsx. Текст програми показано в листингу 5.9.

Листинг 5.9. Ділення 64-розрядного знакового числа на байт : .686 ; директива визначення типу мікропроцесора .model flat ; завдання лінійної моделі пам’яті

option casemap: none ; відмінність малих та великих літер .data ; директива визначення даних

div1 DQ -1234 ; -1234 = FFFF FFFFF FFFF B2Eh

Рис. 5.11. Стан програми ділення беззнакових чисел різної розмірності з листингу 5.8 після її виконання

Page 118: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

117

div2 DB 74 ; 74 = 4Ah – один байт res1 DD 0 ; резервування комірки для збереження цілої частини res2 DD 0 ; резервування комірки для збереження залишку .code ; директива початку сегмента команд

_start: ; мітка початку програми з ім’ям _start movsx BX, div2 ; BX = 004Ah movsx EBX, BX ; EBX = 0000 004Ah mov EAX, dword ptr div1 ; EAX = FFFF FB2Eh mov EDX, dword ptr div1+4 ; EDX = FFFF FFFFh idiv EBX ; EDX=FFFFFFCEh, EAX=FFFF FFF0h mov res1, EAX ; збереження цілої частини результату mov res2, EDX ; збереження залишку результату

ret ; повернення керування ОС end _start ; закінчення програми з ім’ям _start Стан комірок пам’яті до початку виконання програми з листин-

гу 5.9 наведено на рис. 5.12. Стан програми ділення знакових чисел різної розмірності після її

виконання показано на рис. 5.13. Якщо ділене і дільник мають однаковий знаковий біт. то команди

div і idiv генерують однаковий результат. Але якщо ділене і дільник ма-ють різні знакові біти, то команда div генерує позитивну частку, а ко-манда idiv – негативну частку.

У деяких випадках можна добитися підвищення продуктивності при виконанні операцій ділення на ступінь числа 2 (2, 4, і т. д.). В цьому випадку ефективнішим є зрушення управо на необхідне число бітів.

Припускаємо, що ділене знаходиться в регістрі АХ) ділення. Ділення на 2: shr AX,1 Ділення на 8: mov CL,3

shr AX,CL

Рис. 5.12. Стан комірок пам’яті до початку виконання програми

Page 119: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

118

При використанні команд div і idiv може виникнути переповнюван-

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

5.2. Логічні операції

NOT приймач Інверсія Команда NOT здійснює операцію інвертування вмісту, що адресу-

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

NOT reg/mem Чотири команди зсуву виконуються над вмістом пам’яті чи регіс-

трів SAL, SAR, SHL, SHR (рис. 5.14).

Рис. 5.13. Стан програми ділення знакових чисел різної розмірності після її виконання

Page 120: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

119

Ці чотири команди виконують двійкове зрушення приймача (ре-

гістр або змінна) праворуч (убік молодшого біта) або ліворуч (убік ста-ршого біта) на значення лічильника (число або регістр CL, з якого вра-ховуються тільки молодші 5 біт, що набувають значення від 0 до 31). Операція зрушення на 1 еквівалентна множенню (зрушення ліворуч) або діленню (зрушення праворуч) на 2. Так, число – 10b = 210 після зрушен-ня на 1 ліворуч перетворюється в 0100b = 410.

Команди SAL і SHL виконують ту саму операцію (насправді це та сама команда) – на кожен крок зрушення старший біт заноситься в CF, всі біти зрушуються вліво на одну позицію, і молодший біт заповнюєть-ся нулями.

Команда SHR здійснює протилежну операцію: молодший біт зано-ситься в CF, всі біти зрушуються на 1 праворуч, старший біт заповню-ється нулями. Ця команда еквівалентна беззнаковому цілочисельному

SAL приймач, лічильник Арифметичний зсув ліворуч SAR приймач, лічильник Арифметичний зсув праворуч SHL приймач, лічильник .Логічний (беззнаковий) зсув ліворуч SHR приймач, лічильник Логічний (беззнаковий) зсув праворуч

SHLD приймач, лічильник .Логічний зсув подвійного слова ліворуч SHRD приймач, лічильник Логічний зсув подвійного слова праворуч

Рис. 5.14. Формати команд зсуву

CF ← RCL CF → RCR

CF → ROR

CF → SAR

SHR

CF ← ROL

CF ← SAL/ SHL

0

7, 15, 31

CF → 0

0

0 0

Page 121: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

120

діленню на 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 – в значення старшого біта початкового числа. Для зсувів на декілька бітів значення 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 приймач, лічильник Арифметичний (циклічний) зсув ліворуч ROR приймач, лічильник Арифметичний (циклічний) зсув праворуч RCL приймач, лічильник Логічний (циклічний) зсув ліворуч RCR приймач, лічильник Логічний (циклічний) зсув праворуч

Page 122: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

121

Циклічний зсув являє собою операцію зсуву, при якій біт, що висо-вується, займає місце, яке стало вільним. Чотири команди циклічного зсуву з використанням біта CF виконуються над вмістом пам’яті чи ре-гістрів: ROL, ROR, RCL, RCR. Можливі циклічні зсуви на один біт і змінне число бітів, зазначене в регістрі CL. Біт CF стає таким, що дорів-нює останньому біту, який зсувається; біт OF визначається тільки для зсувів на один розряд і встановлюється в тому випадку, якщо біт знака результату операції відрізняється від первісного значення біта знака.

Існують чотири логічні команди над двома операндами. При всіх цих операціях біти CF і OF скидаються, а біти SF, PF і ZF відбивають результат виконання операції.

ROL (ROR, RCL, RCR) mem/reg, count

Команда AND здійснює розрядами логічне множення операндів і

розміщує результат за адресою, що задається першим операндом. AND прм, прд ; прм := (прм) ∧ (прд)

and al,0000111b ; заповнення нулями старших чотирьох бітів в al

OR приймач, джерело Логічне АБО Команда OR виконує розрядами логічне додавання операндів і ро-

зміщує результат за першою адресою. OR прм, прд ; прм := (прм) ∨ (прд)

ХOR приймач, джерело Логічне виключне АБО Команда XOR виконує розрядами логічне додавання за модулем

два двох операндів і розміщує результат за першою адресою. XOR прм, прд ; прм := (прм) ⊕ (прд) хor ах, ах ; заповнення нулями ах

TEST приймач, джерело Логічне порівняння Команда TEST здійснює те ж, що і команда AND. Вона встанов-

лює біти умов, але не формує результат.

AND приймач, джерело Логічне І

Page 123: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

122

TEST прм, прд ; (прм) ∧ (прд) Команда обчислює результат дії побітового логічного І над прий-

мачем (регістр або змінна) і джерелом (число, регістр або змінна; джере-ло і приймач не можуть бути змінними одночасно) і встановлює прапо-рці SF, ZF і PF відповідно до одержаного показника, не зберігаючи ре-зультату (прапорці OF і CF заповнення нулями, значення AF не визна-чене). TEST, так само як і СМР, використовується в основному в поєд-нанні з командами умовного переходу (Jcc), умовного пересилання да-них (CMOVcc) і умовного установлення байтів (SETcc).

Розглянемо програму множення вмісту регістра ЕAX на 10 з вико-

ристанням команд зсуву, пересилання та складання (листинг 5.10). Листинг 5.10. Програма множення на 10 без використання коман-

ди множення: .686 ; директива визначення типу мікропроцесора

.model flat ; завдання лінійної моделі пам’яті option casemap: none ; відмінність малих та великих літер .data ; директива визначення даних

dOp1 DD 3 ; запис у 32-розрядну комірку пам’яті з ім’ям dOp1 числа res DD 0 ; резервування комірки пам’яті під збереження результату

.code ; директива початку сегмента команд _start: ; мітка початку програми з ім’ям _start

mov eax,dOp1 ; занесення числа dOp1 mov ebx, eax ; збереження у додатковому регістрі shl eax,3 ; зсув ліворуч на 3 розряди – множення на 8 shl ebx,1 ; зсув ліворуч на 1 розряд – множення на 2 add eax,ebx ; отримання результату mov res, eax ; збереження результату у пам’яті ret ; повернення керування ОС end _start ; закінчення програми з ім’ям _start Стан програми отримання результату з листингу 5.11 наведено на

рис. 5.15. Крім наведеного варіанта перемноження з використанням команд

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

Page 124: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

123

mov ebx, eax mov ebx,eax shl ebx, 2 shl eax,3 add ebx, eax mov cx,2 shl ebx,1 m1: add eax,edx mov res, ebx loop m1 mov res, eax Таким чином, виконання операцій множення та ділення на ступень

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

5.3. Лабораторна робота “Програмування арифметичних виразів”

Мета заняття: – поглибити і закріпити знання з архітектури МП платформи х86 і

навички його програмування;

Рис. 5.15. Стан програми отримання результату з листингу 5.10

Page 125: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

124

– придбати практичні навички складання, налагодження і виконан-ня програм, написаних мовою асемблеру для програмування арифмети-чних виразів для МП платформи х86.

Постановка задачі Згідно з останньою цифрою номера в групі вибрати варіант та на-

писати програму на асемблері обчислення одного з виразів: 1. a – e/c – ab; 2. (a – d)/b + d; 3. c – ad – e/b; 4. (a – e)b – d/b; 5. a – e/b – de; 6. (b – de)/a – с; 7. ae – d/c – b; 8. (ab – d)/b – d; 9. (de – e)/(c – a); 0. (a – e)b/(a + c),

де a – № в списку; b – № навчальної групи; c – рр – дві останні цифри року народження; е – рррр – чотири цифри року народження; d – ддмм:

дд – день народження; мм – місяць народження.

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

Зміст звіту 1. Постановка задачі для конкретного варіанта. 2. Листинг програми з детальним коментарем та описом роботи. 3. Рrint screen екрана 32-розрядного налагоджувача з виконаною

програмою. 4. Висновки за результатами роботи.

Приклад 5.1. Написати програму на асемблері обчислення виразу

(а + b)с – d/c, де a – № в списку;

b – № навчальної групи; c – рр – дві останні цифри року народження;

Page 126: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

125

е – рррр – чотири цифри року народження; d – ддмм:

дд – день народження; мм – місяць народження.

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

Приклад обчислення виразу (5 + 16)81 – 2209/81 наведено в листин-гу 5.11.

Листинг 5.11. Програма обчислення прикладу 5.1 з використанням

змінних розміром у байт: title CopyRight by Rysovaniy A. N. [email protected] .686 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows .data ; директива визначення даних

_a db 5 ; запис у 8-розрядну комірку пам’яті з ім’ям _а числа 5 _b db 16 ; _b = 10h _c db 81 ; _c = 51h _d dw 2209 ; запис у 16-розрядну комірку пам’яті числа _d = 8A1 rez1 dw 0 ; резервування пам’яті для збереження змінної rez1 rez2 dw 0 ; резервування пам’яті для збереження змінної rez2

.code ; директива початку сегмента команд start: ; мітка початку програми з ім’ям _start

mov al,_a ; al = 05h add al,_b ; al = 15h mul _c ; ax = 15h × 51h = 06A5h push ax ; стек = ХХХХ06A5 mov ax,_d ; ax = 08A1h div _c ; ah,al = ax/_c = 16 1Bh movzx bx,ah ; bx = 0016h – залишок xor cx,cx ; cx = 0 sub cx,bx ; cx = cx – bx = FFEAh – остаток mov rez1,cx pop cx ; cx = 06A5h movzx ax,al ; al = 001Bh sbb cx,ax ; cx = 06A5h – 001Bh = 0689h – ціла частина mov rez2,cx ret ; повернення курування ОС

Page 127: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

126

end start ; закінчення програми з ім’ям _start Результатом виконання програми буде число 0689.FFEA, де 689h –

ціла частина, а FFEAh – остаток результату. Порядок розміщення даних у пам’яті та стан налагоджувача

OllyDbg програми з листингу 5.11 наведено на рис. 5.16.

Збереження тимчасових результатів частини виразу (а + b)с вико-

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

Програму обчислення прикладу 5.1 з використанням даних розмі-ром у слово наведено у листингу 5.12.

Рис. 5.16. Cтан налагоджувача OllyDbg з програмою прикладу 5.1

Page 128: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

127

Листинг 5.12. Програма обчислення прикладу 5.1 з використанням змінних розміром у слово:

title CopyRight by Rysovaniy A. N. .686 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows .data ; директива визначення даних

_a dw 5 ; запис у 8-розрядну комірку пам’яті з ім’ям _а числа 5 _b dw 16 ; _b = 10h _c dw 81 ; _c = 51h

_d dw 2209 ; запис у 16-розрядну комірку пам’яті з ім’ям _ d числа 8A1 res dw 3 dup (0) ;

.code ; директива початку сегмента команд

start: ; мітка початку програми з ім’ям _start mov ax,_a ; ax = 0005h add ax,_b ; ax = 0015h mul _c ; dx = 0000h, ax = 06A5h push dx ; стек = xxxx0000h push ax ; стек = 0000 06A5h mov ax,_d ; ax = 08A1h div _c ; dx = 0016h, ax = 001Bh xor si,si ; si = 0 – заповнювання нулями регістра si sub si,dx ; 0000 – 0016h = FFEAh – дріб mov res,si ; запис дробової частини pop si ; si = 06A5h – старша частина результату (а-b)c sbb si,ax ; віднімання з урахуванням позики mov res+2,si ; запис молодшої цілої частини pop si sbb si,0 ; віднімання з урахуванням позики mov res+4,si ; запис цілої старшої частини ret ; повернення керування ОС

end start ; закінчення програми з ім’ям _start Порядок розміщення даних у пам’яті та стан налагоджувача

OllyDbg з програмою наведено на рис. 5.17.

Page 129: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

128

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

0000 0689,FFEAh. Приклад використання формату даних, збільшеного учетверо, на-

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

Листинг 5.13. Приклад використання формату даних, збільшеного

учетверо: title CopyRight by Rysovaniy A. N.

Рис. 5.17. Стан налагоджувача OllyDbg з програмою з листингу 5.12

Page 130: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

129

; (e + d – ed)/a .686 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

.data ; директива визначення даних a dd 6 ; a = 00000006h d dd 2112 ; d = 00000840h e dd 1989 ; e = 000007C5h

rez1 dd 0 ; rez1 = 00000000h rez2 dd 0 ; rez2 = 00000000h

.code ; (e + d – ed)/a – початок сегмента команд start: ; мітка початку програми з ім’ям _start

; e*d mov eax,d ; eax = 00000840h imul e ; edx = 00000000h, eax = 00401940h

; – e*d (перетворення у додатковий код) not eax ; інверсія eax = FFBFE6BFh not edx ; інверсія edx = FFFFFFFFh inc eax ; eax = FFBFE6C0h adc edx,0 ; edx = FFFFFFFFh (CF=0)

; + d – e*d add eax,d ; eax = FFBFEF00h adc edx,0 ; edx = FFFFFFFFh (CF=0)

;e + d – e*d add eax,e ; eax = FFBFF6C5h adc edx,0 ; edx = FFFFFFFFh (CF=0)

; (e+d-e*d)/a idiv a ; edx = FFFFFFFDh, eax = FFF553CCh ; mov rez1,eax ; rez1 = FFF553CCh – частка mov rez2,edx ; rez2 = FFFFFFFDh – залишок ret ; повернення керування ОС end start ; закінчення програми з ім’ям _start У зв’язку з тим, що значення (e+d-e*d) при таких початкових да-

них повністю розміщується у регістрі eax та не “переходить” у регістр edx, то в такому випадку програма стає достатньо простою. В протиле-жному випадку потрібно виконувати спочатку ділення регістра edx, по-

Page 131: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

130

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

Порядок розміщення даних у пам’яті та стан налагоджувача OllyDbg з програмою листингу 5.13 наведено на рис. 5.18.

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

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

ДОДАТКОВИЙ МАТЕРІАЛ ПРО НАЛАГОДЖУВАЧ OLLYDBG Для виправлення команд в ехе-файлі у налагоджувачі Ollydbg не-

обхідно виконати таке: – натиснути праву кнопку миші у вікні дизасемблеру і вибрати пункт

Copy to execution / Selection. В результаті весь дизасембльований мо-дуль разом з виправленими командами буде скопійований в нове вікно.

– клацнути правою кнопкою миші по новому вікну і вибрати пункт Save file. Указати ім’я нового ехе-файла.

Рис. 5.18. Порядок розміщення даних у пам’яті та стан налагоджувача OllyDbg з програмою з листингу 5.13

Page 132: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

131

КРАПКИ ЗУПИНКИ Звичайні крапки зупинки Для того щоб поставити звичайні крапки зупинки (ordinary

breakpoints), необхідно у вікні дизасемблеру використовувати клавішу <F2> або подвійне клацання миші в другій колонці вікна коду. В цьому випадку команда забарвлюється в червоний колір. Цей вид зупинки не-обхідний для того, щоб в точці зупинки можна було б перевірити стан регістрів, змінних, стека. Вторинне натиснення клавіші <F2> в точці зупинки або подвійне клацання миші видаляють точку зупинки.

Умовні крапки зупинки Умовні крапки зупинки (conditional breakpoints) необхідні для того,

щоб здійснити зупинку, якщо виконується необхідна умова. Умовні крапки зупинки встановлюються натисненням комбінації клавіш <Shift>+<F2>. При цьому з’являється вікно з комбінованим списком, куди можна занести крапку зупинки, наприклад, з такою умовою:

EAX == 5 – зупинка на відміченій команді (перед її виконан-ням) буде здійснена, якщо вміст регістра EAX дорівнюватиме 5;

EAX = 0 AND ECX > 6 — зупинка на відміченій команді буде здійснена, якщо вміст регістра EAX дорівнюватиме нулю та вміст регіс-тра ECX буде більше 6;

[403050] = 1234 – зупинка, якщо вміст елемента пам’яті дорів-нює 1234.

Умовні крапки зупинки із записом в журнал Умовні крапки зупинки із записом в журнал (conditional logging

breakpoint) є розширенням умовних точок зупинки, яке встановлюється натисненням комбінації клавіш <Shift>+<F4>. Для розглядання вмісту журналу необхідно скористатися комбінацією клавіш <Alt>+<L> або вибрати з меню View | Log.

Крапка зупинки на повідомлення Windows Для встановлення зупинки на повідомлення Windows необхідно на-

тиснути комбінацію клавіш <Ctrl>+<F8>. Щоб того, щоб вийти на фун-кцію вікна, треба викликати список створених додатком вікон за допо-могою пункту меню View | Windows. При роботі з віконними функція-ми слід ефективніше використовувати крапку зупинки на повідомлен-ня. Для цього, клацнемо по вікну, яке з’явилося при цьому і виберемо з

Page 133: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

132

контекстного меню пункт Message breakpoint on Classproc. У вікні, що з’явилося, можна встановити параметри крапки зупинки, а саме:

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

даного повідомлення; – визначити лічильник спрацьовувань крапки зупинки; – встановити, чи зупиняти виконання програми; – встановити, чи проводити запис в журнал. Крапка зупинки на функції імпорту Список імен, що імпортуються з налагоджуваним модулем, можна

отримати за допомогою натиснення комбінації клавіш <Ctrl>+<N>. Да-лі, клацнувши правою кнопкою миші по вікну, можна встановити:

– крапку зупинки на виклик функції, що імпортується (команда Toggle breakpoint on impor t);

– умовну крапку зупинки на виклик функції, що імпортується (ко-манда Conditional breakpoint on impor t);

– умовну крапку зупинки на імпорт із записом в журнал (команда Conditional log breakpoint on impor t);

– крапки зупинки на всі посилання на дане ім’я (команда Set breakpoint on every reference);

– крапки зупинки із записом в журнал на всі посилання на дане ім’я (команда Set log breakpoint on every reference) або видалити всі крапки зупинки (команда Remove all breakpoints).

Крапка зупинки на область пам’яті Налагоджувач Ollydbg дозволяє встановити одну крапку зупинки

на область пам’яті. Вибираємо вікно дизасемблера або вікно даних (dump). Далі використовуємо контекстне меню і вибираємо пункт Breakpoint | Memory on access (на доступ до пам’яті) або Breakpoint | Memory on wr ite (на запис в пам’ять). Після цього крапка зупинки го-това до використання. Видалити крапку зупинки на область пам’яті мо-жна з контекстного меню: Breakpoint | Remove memory breakpoint.

Крапка зупинки у вікні Memory Для цієї крапки зупинки використовується контекстне меню, що

з’являється за допомогою клацання правою кнопкою миші і вибору пу-нкту Set memory breakpoint on access (встановити крапку зупинки на доступ до пам’яті) або Set memory breakpoint on wr ite (встановити

Page 134: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

133

крапку зупинки на запис в пам’ять). Видалити крапку зупинки можна з того контекстного меню командою Remove memory br eakpoint.

Апаратні крапки зупинки Звичайні крапки зупинки використовують стандартний вектор пе-

реривання int3. У мікропроцесора Intel Pentium є чотири налагоджува-льні регістри: DR0 – DR3. Ці регістри можуть містити чотири контро-льні крапки. Як тільки адреса, яку використовує команда, дорівнює ад-ресі в одному з вказаних регістрів, то тоді генерується виключення, що перехоплюється налагоджувачем. Встановити апаратну крапку зупинки можна з вікна дизасемблеру за допомогою пункту Breakpoint | Hardware on execution контекстного меню або у вікні даних за допомо-гою пунктів Breakpoint | Hardware on access або Breakpoint | Hardware on access. Видалити апаратні крапки зупинки можна за допо-могою контекстного меню: Breakpoint | Remove hardware breakpoints.

Пошук інформації Налагоджувач Ollydbg дозволяє ефективно шукати різну інформа-

цію. За командою від натиснення комбінації клавіш <Ctrl>+<B> з’являється вікно пошуку, де можливо визначити рядок, який розшуку-ватиметься. Рядок для пошуку можна вводити у вигляді послідовності символів, байтів, символів в кодуванні Unicode.

Для пошуку команд використовуються комбінації клавіш <Ctrl>+<F> для одиночної команди і <Ctrl>+<S>: – для послідовності команд.

Натиснення комбінації клавіш <Ctrl>+<L> повторює останній зроблений пошук.

Page 135: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

134

6. ОРГАНІЗАЦІЯ РОЗГАЛУЖЕНЬ В ПРОГРАМАХ

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

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

BT база, зміщення Перевірка біта 80386

Команда ВТ прочитує в прапорець CF значення біта з бітового ря-

дка, визначеного першим операндом – бітовою базою (регістр або змін-на), зі зсувом, вказаним в другому операнді – бітовому зсуві (число або регістр). Коли перший операнд – регістр, то бітовою базою вважається біт 0 в названому регістрі і зсув не може перевищувати значення 15 або 31 (залежно від розміру регістра); якщо воно перевищує ці межі, то як зсув використовуватиметься залишок від ділення на 16 або 32 відповід-но. Якщо перший операнд – змінна, то як бітова база потрібен біт 0 вка-заного байта в пам’яті, а зсув може набувати значення від 0 до 31, якщо воно встановлене безпосередньо (старші біти процесором ігноруються), і від – 231 до 231 – 1, якщо воно вказане в регістрі.

Не зважаючи на, те що ця команда прочитує єдиний біт з пам’яті, а процесор – ціле подвійне слово за адресою База + (4 х (Зміщення/32)) або слово за адресою База + (2 х (Зміщення /16)), залежно від розрядно-сті адреси, все одно не слід користуватися ВТ поблизу від недоступних для читання областей пам’яті.

Після виконання команди ВТ прапорець CF дорівнює значенню ообчисленого біта, прапорці OF, SF, ZF, AF і PF не визначені.

BTS база, зміщення BTR база, зміщення BTC база, зміщення

Перевірка та встановлення біта Перевірка та скидання біта Перевірка та інвертування біта

80386 80386 80386

Page 136: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

135

Ці три команди відповідно встановлюють в 1 (BTS), скидають в 0 (ВТR) і інвертують (ВТС) значення біта, який знаходиться в бітовому рядку з початком, визначеним в базі (регістр або змінна), і зсувом, вка-заним в другому операнді (число від 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 не визначені.

SETcc приймач Установка байта за умовою 80386 Це набір команд, що встановлюють приймач (8-бітовий регістр або

змінна розміром в 1 байт) в 1 або 0, якщо задовольняється або не задо-вольняється певна умова. Фактично у кожному випадку перевіряється стан тих або інших прапорців, але, коли команда з набору SETcc вико-ристовується відразу після СМР, умови набувають формулювань, відпо-відних до відносин між операндами СМР (табл. 6.1).

Тобто, якщо операнди СМР були нерівні, то команда SETNE, що

виконана відразу після СМР, встановить значення свого операнда в 1. Слова “вище” і “нижче” в табл. 6.1 відносяться до порівняння чисел без знака, слова “більше” і “менше” враховують знак.

Page 137: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

136

Таблиця 6.1 Команди 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 Якщо не дорівнює

Якщо не нуль SETNO OF = 0 Якщо немає переповнювання SETO OF = 1 Якщо є переповнювання SETNP SETPO PF = 0 Якщо немає парності

Якщо непарне SETP SETPE PF = 1 Якщо є парність

Якщо парне SETNS SF = 0 Якщо немає знака SETS SF = 1 Якщо є знак

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

JMP операнд Безумовний перехід 8086

Page 138: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

137

Команда JMP передає керування в іншу точку програми, не збері-

гаючи інформацію для повернення. Операндом може бути безпосередня адреса для переходу (в програмах використовують ім’я мітки, встанов-леної перед командою, на яку виконується перехід), а також регістр або змінна, що містить адресу.

Залежно від типу переходу розрізняють: перехід типу short (короткий перехід) – якщо адреса переходу

знаходиться в межах – 128...+ 127 байт від команди JMP; перехід типу near (ближній перехід) – якщо адреса переходу

знаходиться в тому ж сегменті пам’яті, що і команда JMP; перехід типу far (дальній перехід) – якщо адреса переходу зна-

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

перехід з перемиканням завдання – передача керування іншому завданню в багатозадачному середовищі.

При виконанні переходів типу short та near команда JMP фактич-

но перетворює значення регістра EIP (або IP), змінюючи тим самим зсув наступної виконуваної команди щодо початку сегмента коду. Якщо опе-ранд – регістр або змінна в пам’яті, то його показник просто копіюється в EIP, неначебто це була команда MOV. Якщо операнд для JMP – без-посередньо вказане число, то його значення додається до вмісту EIP, приводячи до відносного переходу. У асемблерних програмах як опе-ранд звичайно указують імена міток, але на рівні виконуваного коду асемблер обчислює і записує саме відносні зсуви.

Виконуючи далекий перехід в реальному, віртуальному і захище-ному режимах (при переході в сегмент з тими ж привілеями), команда JMP завантажує нове значення в EIP і новий селектор сегмента коду в CS, використовуючи старші 16 біт операнда як нове значення для CS і молодші 16 або 32 біт як значення IP або EIP.

Команду jmp можна використовувати не тільки для безумовного

переходу в сегменті програмного коду, але і для організації галужень. Для цього можна застосувати один з її форматів, показаних далі:

jmp reg16 jmp reg32 jmp word ptr [reg16]

Page 139: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

138

jmp dword ptr [reg32] Формат (reg32) команди jmp характерний для 32-розрядних

Windows-додатків. Останні два формати команди jmp використовують механізм не-

прямої адресації, при цьому регістр містить адресу елемента пам’яті, в якій знаходиться адреса команди, яка одержує керування, наприклад:

lea EDI, L1 ; завантажити в EDI адресу змінної L1 jmp EDI ; безумовний перехід за вмістом EDI У даному прикладі в регістр EDI поміщається зсув мітки L1, після

чого за допомогою команди jmp EDI керування передається на цю міт-ку.

.data ; директива визначення даних

mas1 dd L1 ; резервування в пам’яті 4-х байтів ; для збереження змінної L1

.code ; директива початку сегмента команд

... lea esi, mas1 ; завантаження в esi адреси змінної mas1 jmp dword ptr [esi] ; перейти за адресою, яка знаходиться в esi У даному прикладі в регістр ESI поміщається адреса змінної mas1,

тоді як сама змінна mas1 містить адресу мітки L1. Команда jmp dword ptr [esi] в цьому випадку передає керування на

мітку L1.

Jcc мітка Умовний перехід 8086 Це набір команд, що виконують перехід (типу short або near), як-

що задовольняється відповідна умова, якою в кожному випадку реально є стан тих або інших прапорців. Але, коли команда з набору Jcc викори-стовується відразу після СМР, умови набувають формулювань, відпові-дних взаємодіям між операндами СМР (табл. 6.2).

Слова “вище” і “нижче” в табл. 6.2 належать до порівняння чисел

без знака; слова “більше” і “менше” враховують знак.

Page 140: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

139

Таблиця 6.2 Варіанти команди 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 Якщо немає переповнювання JO OF=1 Якщо є переповнювання JNP JPO PF = 0 Якщо немає парності

Якщо непарне JP JPE PF = 1 Якщо є парність

Якщо парне JNS SF = 0 Якщо немає знака JS SF =1 Якщо є знак

Команди Jcc не підтримують далеких переходів, тому, якщо потрі-

бно виконати умовний перехід на далеку мітку, необхідно використати команду з набору Jcc зі зворотною умовою і далекий JMP, як, напри-клад:

cmp ах,0

Page 141: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

140

jne lосаl_1 jmp far_label ; перехід, якщо АХ = 0.

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

розгалужень. Приклад 6.1. Написати програму аналізу двох чисел:

якщо А < В, то записати 1 в Рг СХ; якщо А = В, то записати 1 в Рг ВХ; якщо А > В, то записати 1 в Рг DХ.

Алгоритм виконання програми наведено на рис. 6.1. Листинг 6.1. Програма виконання прикладу 6.1:

; masm32 компiляцiя – ml /c /coff 1L.asm ; компонування – link /SUBSYSTEM:CONSOLE 1L.obj

.386 ; директива визначення типу мікропроцесора

.model flat ; завдання лінійної моделі пам’яті .data ; директива визначення даних

a dd 3 ; запис у 32-розрядну комірку пам’яті з ім’ям а числа 3 ; (перший операнд) b dd 5 ; другий операнд

.code ; директива початку сегмента команд _start: ; мітка початку програми з ім’ям _start

mov eax, a ; занесення першого числа sub eax, b ; порівняння двох чисел для встановлення ознак

AX ← A

AX ← AX – B

S = 1

EDX ← 1

Початок

Закінчення Рис. 6.1. Алгоритм виконання прикладу 6.1

Так Ні

Z = 1

ECX ← 1 EBX ← 1

Page 142: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

141

js minus ; перейти, якщо a < b jz ravno ; перейти, якщо a = b mov edx, 0001h jmp a1 ; безумовний перехід на а1

ravno: mov ebx, 0001h jmp a1 ; безумовний перехід на а1

minus: mov ecx, 0001h a1:

ret ; повернення керування ОС end _start ; директива закінчення програми з ім’ям _start В програмі не використовуються комірки пам’яті для запису ре-

зультату. Тому, комірки для збереження результату й не резервуються. Приклад 6.2. Задано масиви А та В по 4 елементи. Навести алго-

ритм та програму формування масиву С за правилом: якщо Аі < Bi, то Сі = Аі, інакше – Сі = Ві.

Блок-схему виконання прикладу наведено на рис. 6.2.

Ні

Рис. 6.2. Блок-схема виконання прикладу 6.2

Так S = 1

Закінчення

[EDI + EBX] ← AL

EBX ← 04

СL ← 4

EAX ← [ESI]

EDX ← [EDI]

AL – DL

[EDI] + EBX] ← DL

ESI := ESI + 1

EDI := EDI + 1

EBX := EBX + 1

СL := СL – 1

СL = 0 Так

5

6

7

8

9 Ні

10

11 12

13

14

15

16

17

Початок

0

Визнач. A1

Визнач. A2

1

2

EDI := адр А2 4

ESI := адр А1 3

Page 143: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

142

Листинг 6.2. Програма виконання прикладу 6.2: ; masm32: компiляцiя – ml /c /coff 6_2L.asm ; компонування – link /SUBSYSTEM:CONSOLE 6_2L.obj

title CopyRight by Rysovaniy A. N. .386 ; директива визначення типу мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

.data ; директива визначення даних a1 db 0,1,2,3 ; запис у масив пам’яті з ім’ям а1 8-розрядних чисел a2 db 1,2,1,4 ; запис у масив пам’яті з ім’ям а2 8-розрядних чисел

.code ; директива початку сегмента команд start: ; мітка початку програми з ім’ям start

lea esi,a1 ; занесення адреси першого масиву чисел mov edi,offset a2 ; занесення адреси другого масиву чисел mov ebx, 4 ; урахування зміщення адрес між масивами mov cl, 04 ; лічильник кількості пар чисел

m3: mov eax,[esi] ; занесення числа з масиву а1 mov edx,[edi] ; занесення числа з масиву а2 cmp al,dl ; порівняння чисел js m1 ; перейти на m1, якщо al < dl mov [edi+ebx],dl jmp m2 ; безумовний перехід на мітку m2

m1: mov [edi+ebx],al m2: add esi, 01 ; збільшення адреси масиву а1

add edi, 01 ; збільшення адреси масиву а2 add ebx, 01 ; dec cl ; cl := cl – 1 та формування ознак jnz m3 ; перехід на m3 якщо не нуль ret ; повернення керування ОС end start ; директива закінчення програми з ім’ям start У зв’язку з тим, що числа масивів в пам’яті розташовані послідовно

один за одним, то перше число масиву а2 відстає на 4 байти від адреси першого числа масиву а1, тому й необхідна команда mov ebx, 4.

Вікна налагоджувача OllyDbg з відповідною програмою наведено на рис. 6.3.

Результат формування чисел нового масиву після їх взаємного по-рівняння розташовано в дампі пам’яті, починаючи з адреси 00402000h.

Page 144: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

143

Приклад 6.3. Задано масив А з 5 елементів. Навести алгоритм та

програму визначення елементів масиву А, які задовольняють умові 6 ≤ Аі < 3А, та розмістити їх в новому масиві.

Блок-схему виконання прикладу наведено на рис. 6.4.

Рис. 6.3. Вікна налагоджувача OllyDbg з програмою з листингу 6.2

Page 145: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

144

Листинг 6.3. Програма виконання прикладу 6.3: title CopyRight by Rysovaniy A. N. .386 ; директива визначення типу мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

.data ; директива визначення даних mas1 db 0,4,6,3ah,3bh res db 5 dup(?)

.code ; директива початку сегмента команд start: ; мітка початку програми з ім’ям start mov ecx,5 lea esi,mas1 ; занесення адреси початку елементів масиву mas1

Занесення const2

Порівняння елемента з const2

Порівняння елемента з const1

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

Занесення в АХ елемента, адреса якого розміщена в РгSI

Ні

Рис. 6.4. Блок-схема виконання прикладу 6.3

Так ECX = 0

Початок

0

Закінчення

CX := 5

Визнач. A1

Визнач. A2

EAX ← [ESI]

ECX ← ECX – 1

AL – 3A

3

1

AL – BL

ESI := ESI + 1

Так

2

6

7

10

13

8

9

BL := 6

AL < 3A Так Ні

[EDI] ←AL 15

EDI := EDI + 1 16

0

11

12

14

Кількість елементів масиву Початкова адреса масиву А1 Початкова адреса масиву A2

AL – BL Ні

DI := адр А2 5

SI := адр А1 4

M1:

M3:

Page 146: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

145

lea edi,res ; занесення адреси масиву результату m4: mov eax, [esi]

dec ecx jz m1 ; перехід на мітку m1 якщо нуль inc esi ; esi := esi + 1 cmp al,3ah ; порівняння значень jl m3 jmp m4 ; безумовний перехід та мітку m4

m3: mov bl,06 cmp al,bl ; порівняння значень jnl m5 jmp m4 ; безумовний перехід та мітку m4

m5: mov [edi],al inc edi ; edi := edi + 1 (збільшення на одиницю edi) jmp m4 ; безумовний перехід та мітку m4

m1: ret ; повернення керування ОС end start ; директива закінчення програми з ім’ям start Вікна налагоджувача OllyDbg з програмою з листингу 6.3 наведено

на рис. 6.5. Рис. 6.5. Вікна налагоджувача OllyDbg з програмою з листингу 6.3

Page 147: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

146

Приклад 6.4. Задано масив А з N = 4 елементів. Навести алгоритм та програму визначення кількості елементів масиву А, у яких біти 0 ма-ють нулі.

Блок-схему алгоритму виконання програми наведено на рис. 6.6. Листинг 6.4. Програма виконання прикладу 6.4: title CopyRight by Rysovaniy A. N.

.386 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

.data ; директива визначення даних mas1 db 5,7,8,9 ; резервування в області пам’яті з іменем ; mas1 комірок розміром у байт для чисел цього масиву

.code ; директива початку сегмента команд start: ; мітка початку програми

mov ecx, 4 ; ecx := 4 mov edx, 0 ; edx := 0 lea esi, mas1 ; занесення адреси масиву mas1 в esi

m1: mov eax, [esi] inc esi ; esi := esi +1 dec ecx ; ecx := ecx – 1 jz m2 ; перейти на m2, якщо есх = 0 (z = 1) and eax, 01 ; логічне перемноження jnz m3 ; перейти на m3, якщо еах ≠ 0 (z = 1)

Рис. 6.6. Алгоритм виконання прикладу 6.4

Закінчення

Z = 1

EAX := [ESI]

ESI := ESI + 1

EAX := EAX ^ 01

Z = 0

EDX := EDX + 1

EDX ← 0

ECX ← 4 2

Початок

0

Визнач. A1 1

ESI := адр mas1

3

4

Лічильник кількості

елементів у масиві

Лічильник кількості

збігів еле-ментів

ECX := ECX – 1

Так

m3 Так

Page 148: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

147

jmp m1 ; безумовний перехід на мітку m1 m3: inc edx

jmp m1 ; безумовний перехід на мітку m1 m2: ret ; повернення керування ОС

end start ; директива закінчення програми з ім’ям start Вікна налагоджувача OllyDbg з відповідною програмою наведено

на рис. 6.7. Рис. 6.7. Вікна налагоджувача OllyDbg з програмою з листингу 6.4

Page 149: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

148

JCXZ мітка JECXZ мітка

Перехід, якщо СХ = 0 Перехід, якщо ЕСХ = 0

8086 80386

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

СХ або EСX (для JCXZ і JECXZ відповідно) дорівнює нулю. Так само як і команди із серії Jcc, JCXZ і JECXZ не можуть виконувати далеких переходів. Перевірка рівності СХ = 0, наприклад, може бути потрібна на початку циклу, організованого командою LOOPNE. Якщо в нього увій-ти з СХ = 0, то він буде виконаний 65 535 разів.

LOOP мітка Умовний перехід 8086

Команда LOOP зменшує регістр ЕСХ на 1 і виконує перехід типу

short на мітку, яка не може бути далі відстані – 128...+ 127 байт від ко-манди LOOP, якщо ЕСХ не дорівнює нулю. Ця команда використову-ється для організації циклів, в яких регістр ЕСХ (або СХ при 16-бітовій адресації) виконує роль лічильника. Так, в наступному фрагменті ко-манда ADD виконується 10 разів:

mov cx,0Ah loop_start:

add ах,cx loop loop_start Команда LOOP повністю еквівалентна парі команд: dec ecx jnz мітка Але команда LOOP коротша за ці дві команди на один байт і не

змінює значення прапорців. LOOPE мітка LOOPZ мітка LOOPNE мітка LOOPNZ мітка

Цикл, поки дорівнює Цикл, поки нуль Цикл, поки не дорівнює Цикл, поки не нуль

8086 8086 8086 8086

Всі перераховані команди зменшують регістр ЕСХ на один, після

чого виконують перехід типу short, якщо ЕСХ не дорівнює нулю і якщо виконується умова. Для команд LOOРЕ і LOOPZ умовою є рівність ZF = 0; для команд LOOPNE і LOOPNZ – рівність ZF = 0. Самі команди LOOPcc не змінюють значень прапорців, тому ZF повинен бути встано-

Page 150: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

149

влений (або скинутий) попередньою командою. Приклад 6.5. Навести програму пошуку максимального беззнаково-

го числа. У програмі, що наводиться нижче, максимальне беззнакове число в

масиві адресується регістром ЕSI. Регістр СХ містить число елементів в масиві mas1. Після закінчення програми в регістрі EDX знаходиться мак-симальне значення елемента масиву.

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

Блок-схему виконання прикладу наведено на рис. 6.8.

Листинг 6.6. Програма виконання прикладу 6.5: ; masm32: компiляцiя – ml /c /coff 2.asm ; компонування – link /SUBSYSTEM:CONSOLE 2.obj

title CopyRight by Rysovaniy A. N. .386 ; директива визначення типу мікропроцесора .model flat, stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

.data ; директива визначення даних mas1 db 1,9,1,2,8,10,3,4,6,5

.code ; директива початку сегмента команд start: ; мітка початку програми з ім’ям start

Ні

Рис. 6.8. Блок-схема виконання прикладу 6.5

Так Z = 1

Закінчення ESI := ESI + 1

EDX ← AL

СХ ← 10

AL ← [ESI] AL – [ESI]

СX := СX – 1

Так 5

3

4

Ні

7

8

9

6 AL – [ESI] 10

Початок

0

Визнач. mas1 1

SI := адр mas1 2 M3:

M1:

M2:

Page 151: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

150

lea esi,mas1 ; завантаження адреси масиву mas1 mov cx,10 ; завантаження лічильника кількістю елементів

m1: mov al,[esi] ; завантаження числа movsx edx,al ; збереження максимуму

m2: dec cx ; зменшення лічильника jz m3; ; перехід на мітку m3, якщо сх = 0 inc esi ; збільшення адреси масиву чисел на одиницю cmp al,[esi] ; порівняння двох байтів jb m1 ; перейти, якщо al < [esi] jmp m2 ; продовження пошуку

m3: ret ; повернення керування ОС end start ; закінчення програми з іменем start Вікна налагоджувача OllyDbg з програмою з листингу 6.6 наведено

на рис. 6.9. Рис. 6.9. Вікна налагоджувача OllyDbg з програмою з листингу 6.6

Page 152: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

151

Максимальне число зберігається в Рг ЕАХ. В дампі пам’яті даних видно як розташовуються дані: початкові дані – за меншими адресами.

CALL операнд Виклик процедури 8086 Команда CALL зберігає поточну адресу в стеку і передає керування

за адресою, вказаною в операнді. Операндом може бути безпосереднє значення адреси (мітка в асемблерних програмах), регістр або змінна, що містить адресу переходу. Якщо за адресу переходу вказано тільки зсув, вважається, що адреса розташована в тому ж сегменті, що і коман-да CALL. При цьому так само, як й у випадку з командою JMP, викону-ється ближній виклик процедури. Процесор поміщає значення регістра EIP (IP при 16-бітовій адресації), відповідне до наступної за CALL ко-манди, в стек і завантажує в EIP нове значення, здійснюючи тим самим передачу керування. Якщо операнд CALL – регістр або змінна, то його значення розглядається як абсолютний зсув, а якщо операнд – ближня мітка в програмі, то асемблер указує її відносний зсув.

Щоб виконати далекий CALL в реальному режимі, режимі V86 або в захищеному режимі при переході в сегмент з тими ж привілеями, про-цесор поміщає в стек значення регістрів CS і EIP (IP при 16-бітовій ад-ресації) і здійснює далекий перехід аналогічно команді JMP.

RET число RETN число RETF число

Повернення з процедури 8086

Команда RETN прочитує зі стека слово (або подвійне слово, зале-

жно від режиму адресації) і завантажує його в IP (або EIP), виконуючи тим самим дії, протилежні ближньому виклику процедури командою CALL. Команда RETF завантажує зі стека IP (EIP) і CS, повертаючись з далекої процедури. Якщо в програмі вказана команда RET, асемблер замінить її на RETN або RETF залежно від того, як була описана проце-дура, яку ця команда завершує. Операнд для RET необов’язковий, але, якщо він присутній, після зчитування адреси повернення зі стека буде видалена вказана кількість байтів. Це потрібне, якщо при виклику про-цедури їй передавалися параметри через стек.

INT число Виклик переривання 8086

Page 153: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

152

Команда 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, що знаходиться в стеку, щоб, наприклад, повернути пра-порець CF, встановлений у разі помилки.

INT3 Виклик переривання 3 8086

Розмір команди INT3 – один байт (код 0CCh), що робить її зручною

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

INTО Виклик переривання 4 при переповнюванні 8086

Команда INTO – ще одна спеціальна форма команди INT. Вона ви-

Page 154: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

153

кликає обробник переривання 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 має вигляд, наведений на рис. 6.10.

Тепер процедура MAIN може визначати свої локальні змінні в пам’яті, використовуючи поточне значення ЕВР.

На першому рівні вкладеності процедура PROCA, як наведено на

рис. 6.11, може створювати свої локальні змінні, застосовуючи поточне значення ЕВР, і мати доступ до локальних змінних процедури MAIN, використовуючи значення ЕВР для MAIN, поміщене в стек командою ENTER.

Процедура PROCB на другому рівні вкладеності (рис. 6.12) має до-ступ як до локальних змінних процедури PROCA, застосовуючи зна-

Page 155: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

154

чення ЕВР для PROCA, так і до локальних змінних процедури MAIN, використовуючи значення ЕВР для MAIN.

LEAVE Вихід із процедури 80186 Команда LEAVE виконує дії, протилежні команді ENTER. Факти-

чно LEAVE тільки копіює вміст ЕВР в ESP, тим самим викидаючи зі стека весь кадр, створений останньою виконаною командою ENTER, і прочитує зі стека ЕВР для попередньої процедури, що одночасно відно-влює і значення, яке мав ESP до виклику останньої команди ENTER.

старий ЕВР

ЕВР для MAIN локальні

змінні для MAIN

ЕВР для MAIN ЕВР для MAIN

ЕВР для PROCA локальні

змінні для PROCA

Рис. 6.11. Стековий кадр процедури першого рівня

(PROCA)

ЕВР

ЕSP

старий ЕВР ЕВР для MAIN локальні змінні для MAIN

Рис. 6.10 Стековий кадр процедури ну-

льового рівня (MAIN)

ЕВР

ЕSP

старий ЕВР

ЕВР для MAIN локальні

змінні для MAIN

ЕВР для MAIN ЕВР для MAIN

ЕВР для PROCA локальні

змінні для PROCA

ЕВР для PROCA ЕВР для MAIN

ЕВР для PROCA ЕВР для PROCВ

локальні змінні

для PROCВA

Рис. 6.12. Стековий кадр процедури другого рівня

(PROCВ)

ЕВР

ЕSP

Page 156: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

155

7. ПРОЦЕДУРИ

7.1. Організація процедур та їх дослідження

Процедура – це відокремлена частина програми, яка виконує певне завдання. Процедури необхідні для зменшення складності програми, зменшення часу пошуку помилок в програмі, а також для того, щоб зро-бити програму зрозумілою і керованою. Якщо програму зробити з неза-лежних модулів-процедур [8] то час пошук помилок різко зменшується. На листингу 7.1 наведено програму з простою процедурою складання двох чисел.

Листинг 7.1. Програма з простою процедурою складання двох чи-

сел: ; командний файл для компіляції та компонування ; ml /c /coff "7_6L.asm" ; link /SUBSYSTEM:CONSOLE "7_6L.obj".

title CopyRight by Rysovaniy A. N. [email protected] .386 ; директива визначення типу мікропроцесора .model flat, stdcall ; завдання лінійної моделі пам’яті

; та угоди ОС Windows option casemap:none ; відмінність малих та великих літер

.code ; директива початку програми start: ; мітка початку програми з ім’ям start

mov ax,2 mov bx,3 call AddW ; виклик процедури AddW

AddW proc ; процедура AddW add ax,bx ret ; повернення керування ОС

AddW endp ; закінчення процедури AddW end start ; закінчення програми з ім’ям start

У цій програмі можна виділити заголовок AddW ргос, що склада-

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

Page 157: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

156

дається з імені і слова endp, та “тіло” процедури, тобто виконувані нею інструкції. Процедура викликається інструкцією call <ім’я>. Після ви-клику виконуються інструкції, з яких складається процедура, і потім процесор переходить до інструкцій, що йдуть безпосередньо за викли-ком процедури.

Регістр eip містить адресу поточної команди. Команда call за-пам’ятовує в стеку адресу повернення і завантажує на eip адресу першої інструкції процедури. Коли виконуються інструкції процедури, eiр мі-няється автоматично – залежно від самих інструкцій. Коли ж процесор доходить до команди ret, із стека береться адреса повернення, заванта-жується в eip і процесор прямує за вказаною адресою.

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

Розглянемо приклад передачі параметрів через стек з використан-

ням процедур (листинг 7.2). Листинг 7.2. Програма передачі параметрів через стек з викорис-

танням процедур: ; masm32: компiляцiя – ml /c /coff 7_2L.asm ; компонування – link /SUBSYSTEM:CONSOLE 7_2L.obj

.386 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap:none ; відмінність малих та великих літер .code ; директива початку програми

start: ; мітка початку програми з ім’ям start push dword ptr 3 push dword ptr 4 call AddW ; виклик процедури ret ; повернення керування ОС

Page 158: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

157

AddW proc ; початок процедури mov eax,[esp+8] ; eax = 3 add eax,[esp+4] ; eax = 7

ret 8 ; повернення з процедури та збільш. на 8 вказівника стека AddW endp ; закінчення процедури

end start ; закінчення програми з ім’ям start

Команда push dword ptr 3 записує в стек подвійне слово (4 байти), що містить число 3. Асемблер MASM записав би подвійне слово і за командою push 3, але надійніше указувати розмір числа явно.

У стеку зберігаються три 4-байтові числа, першим (його адреса найбільша) йде число 00000003, потім число 00000004 і, нарешті, на вершині стека знаходиться адреса повернення.

Таким чином, число 3, поміщене в стек першим, відстоїть від вер-шини на 8 байтів, а число 4 – на 4. Тому параметри процедури матимуть адреси esp+4 і esp+8 [8].

Команда ret 8 видаляє 8 байтів зі стека (очищує стек). Звичайно програмам допомагає спілкуватися з навколишнім світом

операційна система, яка бере на себе всі деталі взаємодії із зовнішніми пристроями. У системі Windows цьому служать процедури Windows API, які викликаються так само, як і будь-яка інша процедура асемблеру – інструкцією call. Параметри, необхідні цим функціям, передаються через стек.

Розглянемо процедуру ExitProcess, яку викликає кожна Windows-програма, щоб завершити свою роботу. Дотепер замість ExitProcess ми користувалися простою інструкцією повернення ret. Але ExitProcess діє набагато правильніше, не тільки повертаючи керування операційній системі, але і звільняючи зайняті програмою ресурси.

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

Листинг 7.3. Програма з правильним завершенням: ; командний файл для компіляції та компонування

; ml /c /coff "7_6L.asm" ; link /SUBSYSTEM:CONSOLE "7_6L.obj"

.386 ; директива визначення типу мікропроцесора

.model flat, stdcall ; завдання лінійної моделі пам’яті

Page 159: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

158

; та угоди ОС Windows option casemap:none ; відмінність малих та великих літер

ExitProcess proto :dword ; прототип функції includelib\masm32v9_0\lib\kernel32.lib ; виклик бібліот. kernel32.lib

.code ; директива початку програми start: ; мітка початку програми з ім’ям start push 0 ; запис у стек коду завершення програми для ExitProcess

call ExitProcess ; повернення керування ОС Windows ; та визволення ресурсів

end start ; закінчення програми з ім’ям start

Процедура ExitProcess (http://www.NikolayAM.narod.ru, http:// msdn.microsoft.com), що викликається в ній, вимагає одного параметра – коду завершення, який повертається операційній системі. Він переда-ється процедурі командою push 0. Число 0 вважається ознакою вдалого завершення. Код завершення залежно від обставин може бути іншим.

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

Відомості про адресу і параметри процедури зберігаються у файлі бібліотеки kernel32.1ib, який підключається до асемблерного тексту ди-рективою

Includelib \masm32v9_0\lib\kernel32.lib Перш ніж створити інструкцію виклику цієї процедури компонува-

льник порівнює відомості з бібліотеки з прот от ипом ExitProcess proto :DWORD, і якщо все збігається, створює придатний до виконання файл з розширенням .ехе. Прототип процедури дуже простий і складається з імені, слова proto і параметрів. У нашому випадку параметр один – це подвійне слово (тобто, 4 байти) DWORD. Якщо параметрів у процедури декілька, вони розділяються в списку комами.

Команди push <параметр> і виклик процедури call в асемблері фірми Microsoft можна скорочено записати як invoke <ім’я>. параметр, параметр... Мінімальна програма, що використовує виклик процедури invoke, має вигляд, наведений в листингу 7.4.

Листинг 7.4. Мінімальна програма, що використовує виклик про-

цедури invoke: ; masm32: компiляцiя – ml /c /coff 7_4L.asm ; компонування – link /SUBSYSTEM:CONSOLE 7_4L.obj

Page 160: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

159

.386 ; директива визначення типу мікропроцесора

.model flat, stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap: none ; відмінність малих та великих літер ExitProcess proto: dword ; прототип API-функції іncludelib \masm32v9_0\lib\kernel32.lib

.code ; директива початку програми start: ; мітка початку програми з ім’ям start

invoke ExitProcess, 0 ; повернення керування ОС Windows ; та визволення ресурсів

end start ; закінчення програми з ім’ям start Директива invoke – не команда процесора, а лише зручний запис

виклику процедури, яка буде перетворена асемблером в команди push (їх буде стільки, скільки параметрів у процедури) та call.

Розглянемо програму, яка обчислює суму і різницю двох цілих чи-сел з використанням двох процедур (листинг 7.5).

Листинг 7.5. Програма обчислення суми та різниці двох цілих чи-

сел з використанням процедур: ; masm32: компiляцiя – ml /c /coff 0_1L.asm ; компонування – link /SUBSYSTEM:CONSOLE 0_1L.obj

title CopyRight by Rysovaniy A. N. .686 ; директива визначення типу мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті

; та угоди ОС Windows option casemap: none ; відмінність малих та великих літер .data ; директива визначення даних op1 dd -27 ; запис у 32-розрядну комірку op1 першого операнда op2 dd 38 ; запис у 32-розрядну комірку op2 другого операнда rez dd 2 dup(0) ; резервування в пам’яті комірки 32 × 2 під rez .code ; директива початку програми

start: ; мітка початку програми з ім’ям start call Addw ; виклик підпрограми додавання mov rez,eax ; збереження в пам’яті результату додавання call Subw ; виклик підпрограми віднімання mov rez+4,eax ; збереження в пам’яті результату віднімання ret ; повернення керування ОС

Addw proc ; початок процедури з іменем Addw

Page 161: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

160

mov eax,op1 add eax,op2 ret ; повернення з процедури Addw endp ; закінчення процедури з ім’ям Addw

Subw proc ; початок процедури з іменем Subw clc ; скидання прапорця перенесення mov eax,op1 sbb eax,op2 ret ; повернення з процедури Subw endp ; закінчення процедури з ім’ям Subw

end start ; закінчення програми з ім’ям start Стан програми після виконання останньої команди основної про-

грами (ret) наведено на рис. 7.1. Мітка start необхідна, щоб компонувальник відрізняв початок та

кінець програми. Процедура Addw proc виконує додавання двох чисел розміром у 4 байти, процедура Subw proc – відповідне віднімання.

Рис. 7.1. Стан програми з листингу 7.5 після виконання останньої команди основної програми (ret)

Page 162: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

161

У програмі за адресою 00402008h розміщується результат виконан-ня процедури Addw proc, а за адресою 0040200Сh – результат виконан-ня процедури Subw proc.

В останній програмі використаємо процедури Windows API. Текст модернізованої програми розглядається в листингу 7.6.

Листинг 7.6. Модернізована програма з процедурою Windows API: ; командний файл для компіляції та компонування

; ml /c /coff "7_6L.asm" ; link /SUBSYSTEM:CONSOLE "7_6L.obj".

title CopyRight by Rysovaniy A. N. 686 ; директива визначення типу мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті

; та угоди ОС Windows option casemap: none ; відмінність малих та великих літер

ExitProcess proto: dword ; прототип API-функції includelib \masm32v9_0\lib\kernel32.lib

.data ; директива визначення даних op1 dd -27 ; визначення у пам’яті змінної op1 розміром у 32 розряди op2 dd 38 ; визначення у пам’яті змінної op2 розміром у 32 розряди

rez dd 2dup(0) .code ; директива початку програми start: ; мітка початку програми з ім’ям start

call Addw ; виклик процедури додавання mov rez,eax ; збереження в пам’яті результату додавання call Subw ; виклик процедури віднімання mov rez+4,eax ; збереження в пам’яті результату віднімання

invoke ExitProcess, 0 ; директива закінчення головної частини

Addw proc ; початок процедури Addw

mov eax,op1 add eax,op2 ret ; повернення з процедури

Addw endp ; закінчення процедури Addw

Subw proc ; початок процедури Subw

Page 163: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

162

clc ; скидання прапорця CF mov eax,op1 sbb eax,op2 ret ; повернення з процедури

Subw endp ; закінчення процедури Subw end start ; закінчення програми з ім’ям start Вікна налагоджувача OllyDbg з модернізованою програмою наве-

дено на рис. 7.2. При цьому можна побачити зміни, які з’являються при застосуванні

Windows API-функцій. Процедура invoke ExitProcess, 0 перетворюєть-ся у налагоджувачі у додаткову команду PUSH 0 для успішного завер-шення програми.

Рис. 7.2. Вікна налагоджувача OllyDbg з модернізованою програмою з листингу 7.6

Page 164: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

163

7.2. Windows АРІ-подібні процедури Відомо [8], що процедури Windows АРІ мають прототип та заголо-

вок, в якому вказуються її параметри. Тому якщо оформити самостійно написану процедуру як процедуру Windows АРІ, то вона стає Windows АРІ-подібною. Як приклад розглянемо програму додавання двох чисел (листинг 7.7).

Листинг 7.7. Програма додавання двох чисел з використанням ди-

рективи invoke: ; командний файл для компіляції та компонування ; ml /c /coff "7_6L.asm" ; link /SUBSYSTEM:CONSOLE "7_6L.obj".

title CopyRight by Rysovaniy A. N. .386 ; директива визначення типу мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті

; та угоди ОС Windows option casemap:none ; відмінність малих та великих літер includelib\masm32v9_0\lib\kernel32.lib ExitProcess proto :DWORD AddDD proto :DWORD, :DWORD ; прототип процедури

.code ; директива початку коду програми start: ; мітка початку програми з ім’ям start

invoke AddDD,2,3 ; виклик директиви AddDD з параметрами invoke ExitProcess,0

AddDD proc arg1:DWORD,arg2:DWORD mov eax,[esp+8] ; eax = 2 add eax,[esp+12] ; eax = 5 ret ; повернення керування ОС

AddDD endp ; закінчення процедури з ім’ям AddDD end start ; закінчення програми з ім’ям start

Стан програми після виконання команди add eax,[esp+12] наведе-но на рис. 7.3.

Page 165: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

164

Тепер в цій програмі перше число (2) відстоїть від вершини на 8

байт, а друге – на 12. Налагоджувач виявляє в створеній процедурі бага-то сторонніх інструкцій:

PUSH EBP MOV EBP,ESP MOV EAX,DWORD PTR SS:[ESP+8] ADD EAX,WORD PTR SS:[ESP+C] LEAVE RETN 8

Рис. 7.3. Стан програми після виконання команди add eax,[esp+12]

Page 166: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

165

Слово LEAVE еквівалентне парі інструкцій mov esp,ebp pop ebp Асемблер зберігає вказівник стека в регістрі ebp. Якщо ebp не мі-

няється усередині процедури, то esp можна відновити перед виходом з неї. Щоб при цьому зберегти ebp для зовнішнього світу, його спочатку відправляють в стек, а перед поверненням з процедури знову виймають звідти. Ось через те, що ebp зберігається в стеку, і міняється положення параметрів процедури. Першим в ст ек відправляєт ься число 3, пот ім 2, пот ім ebp, пот ім адреса повернення. Отже, ebp відстоїть на 4 байти від вершини, число 2 – на 8, а число 3 – на 12 байт.

Значення регістра esp зберігається в регістрі ebp, оскільки асемб-лер не знає, чи міняється вказівник стека, і тому зберігає його на випа-док, якщо стек використовується для зберігання локальних змінних.

Локальні змінні необхідні процедурі тільки у момент її виконання, от чому для них не слід займати місце в комп’ютерній пам’яті, виділене директивою .data. Але якщо зберігати їх в стеку, вони виникнуть при вході в процедуру і зникнуть при виході з неї.

В листингу 7.7 можна для простоти обійтися без передачі безпосе-

редніх даних через стек. Для цього необхідно замість команд mov eax,[esp+8] add eax,[esp+12]

використати команди mov eax,arg1 add eax,arg2.

Всі інші команди залишаються без зміни.

7.3. Непрямий виклик процедур

Непрямий виклик процедур дозволяє використовувати різноманітні їх способи адресації:

call ВХ ; адреса підпрограми знаходиться в регістрі ВХ саll [ВХ] ; адреса підпрограми знаходиться в елементі пам’яті,

; адреса якої розміщується в регістрі ВХ сall [BX][SI] ; у ВХ – адреса таблиці адрес підпрограм

; у SI індекс в цій таблиці

Page 167: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

166

tb1 [SI] ; змінна tbl містить адресу таблиці адрес підпрограм ; у SI – індекс в цій таблиці

Розглянемо програму, в якій потрібно проаналізувати масиви А та

В, в кожному з яких по 10 елементів типу WORD. Необхідно визначити кількість елементів масиву Ai, що задовольняють умову Ai ≤ Bi та вико-ристати передачу параметрів через таблицю адресів. Таку програму на-ведено у листингу 7.8.

Листинг 7.8. Передача параметрів через таблицю адресів: ; передача параметрів через таблицю адресів title CopyRight by Rysovaniy A. N.

.386 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

.data ; директива визначення даних A1 DW 0,1,2,3,4,5,6,7,8,9 ; збереження в масиві пам’яті з ім’ям А1

; чисел, кожне у 16-розрядну комірку B1 DW 9,8,7,6,5,4,3,2,1,0 N1 DW 10 _TA DD 4 DUP (0)

.code ; директива початку коду програми _start: ; мітка початку програми з ім’ям start

mov _TA,offset A1 ; завантажити адресу масиву А1 mov _TA+4,offset B1 ; завантажити адресу масиву В1 mov _TA+8,offset N1 ; завантажити адресу лічильника N1 mov ebx,[_TA] ; завантажити адресу початку таблиці адресів call prog1 ; ret ; повернення керування ОС prog1 proc mov cx,[ebx+40] ; лічильник = 0Ah (10) movzx ecx,cx ; заповнення старшої частини регістра нулями mov si,[ebx] ; вибрати 1-й елемент масиву А1 mov di,[ebx+20] ; вибрати 1-й елемент масиву В1 xor edx,edx ;

m1: cmp si,di ; порівняння елементів масивів

jl m2 ; перейти, якщо менше

Page 168: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

167

jmp m3 ; перейти в протилежному випадку m2: inc dx ; підрахувати кількість елементів m3: add si,2 ; підготовка наступного елемента масиву А1

add di,2 ; підготовка наступного елемента масиву В1 loop m1 ; перейти на m1, якщо СХ. ≠ 0 ret ; повернення керування ОС

prog1 endp ; закінчення процедури end _start ; закінчення програми з ім’ям start Стан програми після її виконання наведено на рис. 7.4. У цій програмі для того, щоб заповнити нулями старшу частину лі-

чильника, використано команду movzx ecx,cx, хоча можна попереду

Рис. 7.4. Стан програми з листингу 7.8 після її виконання

Page 169: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

168

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

У розглянутій програмі використовується одна процедура. Головну програму, з якої викликаються інші процедури також мо-

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

Листинг 7.9. Програма обчислення суми та різниці двох цілих чи-

сел з використанням непрямого виклику процедур: title CopyRight by Rysovaniy A. N. .686 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap: none ; відмінність малих та великих літер .data ; директива визначення даних

tbl label dword ; присвоєння tbl подвійного слова DD sub1 ; резервування під sub1 в пам’яті комірок

; розміром в подвійне слово (32 розряда) DD sub2 ; резервування під sub2 в пам’яті комірок

; розміром в подвійне слово op1 DD -29 ; –29 = FFFF FFE3h op2 DD 59 ; 59 = 0000 003Bh res DD 2 DUP(0) ; резервування в пам’яті комірок

; розміром в два подвійних слова .code ; директива початку коду програми

start: ; мітка початку програми з ім’ям start _main proc ; головна процедура

lea ESI, tbl ; занесення в ESI адреси tbl mov [ESI], offset sub1 ; занесення адреси процедури sub1 mov [ESI+4], offset sub2 ; call dword ptr [ESI] ; непрямий виклик процедури sub1 call dword ptr [ESI+4] ; непрямий виклик процедури sub2 lea EAX, res ; занесення адреси результату до ЕАХ ret ; повернення керування ОС

_main endp ; закінчення головної процедури sub1 proc

clc ; очищення прапорця перенесення mov EAX, op1

Page 170: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

169

adc EAX, op2 mov res, EAX ret ; повернення з процедури

sub1 endp sub2 proc

clc ; очищення прапорця перенесення mov EAX, op1 sbb EAX, op2 mov res+4, EAX ret ; повернення з процедури

sub2 endp ; закінчення процедури end start ; закінчення програми з ім’ям start Мітка start при виконанні декількох процедур є обов’язковою. Зна-

чення комірок пам’яті до моменту виконання програми наведено на рис. 7.5. Значенню sub1 привласнюється адреса 0040101F початку цієї процедури, значенню sub2 – адреса 00401031 початку відповідної про-цедури.

У цій програмі для простоти не застосовуються Windows API-

функції. Стан програми після виконання останньої команди основної програми (ret) наведено на рис. 7.6.

Програма, що розглядається, складається з трьох процедур: 1) го-ловної – з ім’ям _main; 2) такої, що виконує додавання – з ім’ям sub1; 3) такої, що виконує віднімання – з ім’ям sub2. Процедура sub1 обчис-лює суму чисел і1 та і2 та розташовує результат у молодше подвійне слово змінною res. Процедура sub2 виконує віднімання тих же чисел та розміщення результату у старше подвійне слово змінної res. Головна процедура _main викликає процедури за адресою, яка знаходиться у регістрі ESI. А регістр ESI отримує цю адресу з таблиці tbl, яка вміщує відповідну адресу. За командою lea ESI, tbl в ESI фактично заноситься адреса процедури sub1.

Рис. 7.5. Значення комірок пам’яті до моменту виконання програми

Page 171: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

170

7.4. Використання загальних змінних у процедурах

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

Загальні або, як їх ще називають, глобальні змінні дозволяють пра-цювати з даними при мінімальному використанні стека, що економить процесорний час. Крім того, фіксовані прив’язки загальних змінних на етапі компонування прискорюють доступ до ним.

Для роботи із загальними змінними в мові асемблеру використо-вуються директиви public і extern.

Директива public оголошує змінну або процедуру, яка доступна для інших модулів, директива extern указує на те, що змінна або проце-дура є зовнішньою по відношенню до виконуваної процедури. Обидві

Рис. 7.6. Стан програми з листингу 7.9 після виконання

Page 172: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

171

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

Глобальні змінні оголошуються таким чином: – у об’єктному модулі, де знаходиться така змінна, необхідно вка-

зати на можливість доступу до неї за допомогою директиви public; – у об’єктних модулях, з яких походить звернення до загальної

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

типу об’єкта та може кодуватися одним із слів: – BYTE; – WORD; – DWORD; – QWORD; – DQWORD. Розглянемо приклад. Хай потрібно обчислити вираз а1 + а2 – b3,

де а1, а2, b3, – цілі числа. Обчислення виконаємо за допомогою двох процедур, розташованих в різних файлах: _add1, яка обчислює суму а1 + а2 і _sub1, яка віднімає з цієї суми число b3.

Підкреслення спереду відображ ає ст андарт ANSI, який наказує всім зовнішнім іменам (дост упним декільком модулям) авт омат ично додават и символ підкреслення.

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

При об’єднанні декількох модулів першим повинен йти головний, а інші – в довільному порядку.

Результат обчислень повертається в головну процедуру (_add_sub). Всі три підпрограми реалізовано у вигляді окремих файлів ASM, які після компіляції утворюють три файли об’єктних модулів з розширенням .OBJ за допомогою команди

ml /c /coff 06_07L. asm 06_07_1L.asm 06_07_2L.asm <enter> За допомогою компонувальника (link або іншого) ці файли можна

включити в 32-розрядний додаток, наприклад: link /subsystem:console 06_07L.obj 06_07_1L.obj 06_07_2L.obj <enter>

Page 173: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

172

У підпрограмі _add_sub визначимо змінні al, a2, і b3 як подвійні числа, яким привласнимо конкретні значення. Оскільки всі змінні по-винні бути доступні з інших підпрограм, що знаходяться в інших об’єктних файлах, необхідно їх оголосити з директивою public. Крім того, зовнішні підпрограми _add1 і _sub1, використовувані процедурою _add_sub, повинні бути оголошені з директивою extern. Текст підпрог-рами _add_sub наведено в листингу 7.10.

Листинг 7.10. Початковий текст підпрограми _add_sub: title CopyRight by Rysovaniy A. N.

.686 ; директива визначення типу мікропроцесора

.model flat ; завдання лінійної моделі пам’яті

.stack 100h option casemap: none extern _add1:proc ; указання на зовнішню процедуру extern _sub1:proc ; указання на зовнішню процедуру public a1, a2, b3 ; доступ для інших модулів

.data ; директива визначення даних a1 DD 171 ; a1 = 0000 00ABh a2 DD 17 ; a2 = 0000 0011h b3 DD 34 ; b3 = 0000 0022h

.code ; директива початку коду програми _start: ; мітка початку програми з ім’ям start _add_sub proc

clc ; очищаємо прапорець перенесення call _add1 ; обчислюємо суму a1 + a2

push EAX ; проміжний результат a1 + a2 = 0000 00BCh поміщаємо ; в стек, оскільки він використовуватиметься

; процедурою _sub1 (esp = esp + 4) call _sub1 ; обчислюємо різницю одержаної суми (a1 + a2) ; і числа b3. Результат повертається в основну ; програму через регістр EAX ret ; повернення керування ОС

_add_sub endp ; закінчення процедури end _start ; закінчення програми з ім’ям start В головній програмі початок програми обов’язково позначається

міткою.

Page 174: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

173

Якщо не вказати процедури як зовнішні (extern), то компілятор, не виявивши їх в поточному модулі, видасть помилку. Якщо не вказати змінні з атрибутом public, то при компіляції цього ASM-файла ніяких помилок не буде, але вони з’являться в процесі компіляції інших моду-лів, де ці змінні використовуються (листинг 7.11).

Листинг 7.11. Текст процедури _add1: title CopyRight by Rysovaniy A. N.

.686 ; директива визначення типу мікропроцесора

.model flat ; завдання лінійної моделі пам’яті option casemap: none ; відмінність малих та великих літер

public _add1 ; доступ для інших модулів extern a1: DWORD ; указання на зовнішню процедуру extern a2: DWORD ; указання на зовнішню процедуру

.code ; директива початку коду програми _add1 proc

mov EAX, a1 ; EAX = 0000 00ABh add EAX, a2 ; EAX = 0000 00BCh ret ; повернення керування ОС (повернення з процедури)

_add1 endp ; закінчення процедури end ; закінчення програми Оскільки процедура _add1 використовується в підпрограмі

_add_sub, то вона повинна бути оголошена як загальна (public) для зо-внішніх по відношенню до даного об’єктного файла програм. Крім того, процедура _add1 має дві змінні, визначені в іншому об’єктному файлі (де визначена процедура _add_sub), тому вони повинні бути вказані як зовнішні (extern).

Результат складання повертається, як завжди, в регістр ЕАХ. Про-аналізуємо останню з трьох підпрограм – _sub1 (листинг 7.12).

Листинг 7.12. Текст процедури _sub1: title CopyRight by Rysovaniy A. N.

.686 ; директива визначення типу мікропроцесора

.model flat ; завдання лінійної моделі пам’яті option casemap: none ; відмінність малих та великих літер

extern b3: DWORD ; вказівка на зовнішню процедуру public _sub1 ; доступ для інших модулів

.code ; директива початку коду програми

Page 175: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

174

_sub1 proc push EBP ; збереження в стеку регістра бази (ESP = ESP + 8 – тому,

; що в головній програмі була команда push EAX) mov EBP, ESP ;

mov EAX, dword ptr [EBP+8] ; занесення a1 + a2 = 0000 00BCh в EAX sub EAX, b3 pop EBP

ret 4 ; відновлення початкових значень та повернення керув. ОС _sub1 endp ; закінчення процедури

end ; закінчення програми Процедура використовує змінну b3 з модуля, в якому знаходиться

підпрограма _add_sub, тому вона оголошена як зовнішня. Сама проце-дура _sub1 оголошена доступною для програм з інших модулів, оскіль-ки викликається із зовнішньої підпрограми _add_sub.

Процедура _sub1 викликається з _add_sub таким чином: push EAX call _subl Для звернення до пам’яті прийнято за умовчанням використовувати

регістр EBP. Тому команда push EBP необхідна на той випадок, якщо якась зовнішня процедура звертається до пам’яті. А для того, щоб зна-чення EBP не змінилося, його спочатку необхідно зберегти, а після ви-користання – відновити.

Стан програми після виконання команди pop ebp наведено на рис. 7.7. Значення змінних у шістнадцятковій системі числення можна побачити у вікні налагоджувача.

Процедурі передається один параметр через стек (сума a1 і а2). Для витягання параметра із стека в процедурі _sub1 використовується ре-гістр ЕВР. Перед поверненням в головну підпрограму в стеку знахо-диться один параметр, поміщений туди при виклику, тому команда ret повинна очистити стек. Потрібно видалити 4 байти, що і робить команда ret 4.

Як і в попередніх випадках, процедура повертає результат в регістр ЕАХ. Таким чином, головна підпрограма _add_sub перед інструкцією повернення міститиме результат в регістрі ЕАХ. Цей приклад демонст-рує основні аспекти використання загальних змінних в програмах на асемблері.

Page 176: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

175

Приклад 7.1. Написати програму на асемблері обчислення виразу

(а + b)с – d/c, де a – № в списку;

b – № навчальної групи; c – рр – дві останні цифри року народження; е – рррр – чотири цифри року народження; d – ддмм:

дд – день народження; мм – місяць народження.

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

Рис. 7.7. Стан програми після виконання команди pop ebp

Page 177: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

176

Приклад обчислення виразу (5 + 16)81 – 2209/81 без використання зовнішніх процедур наведено в листингу 7.13.

Листинг 7.13. Програма обчислення прикладу 7.1 з використанням

змінних розміром у байт: title CopyRight by Rysovaniy A. N.

.686 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

.data ; директива визначення даних _a db 5 ; збереження у 8-розрядній комірці з ім’ям _а числа 5 _b db 16 ; _b = 10h _c db 81 ; _c = 51h _d dw 2209 ; _d = 8A1 rez1 dw 0 ; запис у 16-розрядну комірку пам’яті значення 0 rez2 dw 0

.code ; директива початку коду програми start: ; мітка початку програми з ім’ям start

mov al,_a ; al = 05h add al,_b ; al = 15h mul _c ; ax = 15h × 51h = 06A5h push ax ; стек = ХХХХ06A5 mov ax,_d ; ax = 08A1h div _c ; ah,al = ax/_c = 16 1Bh movzx bx,ah ; bx = 0016h – залишок xor cx,cx ; cx = 0 (заповнювання нулями) sub cx,bx ; cx = cx – bx = FFEAh mov rez1,cx pop cx ; cx = 06A5h movzx ax,al ; al = 001Bh sbb cx,ax ; cx = 06A5h – 001Bh = 0689h mov rez2,cx

ret ; повернення керування ОС end start ; закінчення програми з ім’ям start Результатом виконання програми буде число 0689.FFEA, де 689h –

ціла частина, а FFEAh –остаток результату. Порядок розміщення даних у пам’яті та стан налагоджувача

OllyDbg з програмою прикладу 7.1 наведено на рис. 7.8. Збереження

Page 178: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

177

тимчасових результатів частини виразу (а + b)с виконується в стеку, хоча для цього можна використовувати як один із вільних регістрів, так й комірку пам’яті.

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

ром у слово наведено у листингу 7.14. Листинг 7.14. Програма обчислення прикладу 7.1 з використанням

змінних розміром у слово: title CopyRight by Rysovaniy A. N.

.686 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

.data ; директива визначення даних

Рис. 7.8. Стан налагоджува OllyDbg з програмою прикладу 7.1

Page 179: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

178

_a dw 5 ; збереження у 16-розрядній комірці з ім’ям _а числа 5 _b dw 16 ; _b = 10h _c dw 81 ; _c = 51h _d dw 2209 ; _d = 8A1 res dw 3 dup (0) ; запис у масив пам'яті з ім’ям res трьох слів

; з нульовими значеннями .code ; директива початку коду програми start:

mov ax,_a ; ax = 0005h add ax,_b ; ax = 0015h mul _c ; dx = 0000h, ax = 06A5h push dx ; стек := xxxx 0000h push ax ; стек := 0000 06A5h mov ax,_d ; ax = 08A1h div _c ; dx = 0016h, ax = 001Bh xor si,si ; si = 0 sub si,dx ; si := 0000 – 0016h = FFEAh – дріб mov res,si ; запис дробової частини pop si ; si = 06A5h – старша частина результату (а-b)c sbb si,ax ; mov res+2,si ; запис молодшої цілої частини pop si sbb si,0 mov res+4,si ; запис цілої старшої частини ret ; повернення керування ОС end start ; закінчення програми з ім’ям start Результат виконання прикладу не змінився та дорівнює

0000 0689, FFEAh. Порядок розміщення даних у пам’яті та стан налагоджувача

OllyDbg з програмою наведено на рис. 7.9. Приклад 7.1 також можна роз’єднати на декілька зовнішніх проце-

дур. Програма складається з трьох частин: головна процедура та дві зов-нішні з іменами _res1 та _res2. В листингах 7.15 – 7.17 наведено цю можливість.

Page 180: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

179

Листинг 7.15. Програма обчислення прикладу 7.1 з використанням

зовнішніх процедур: title CopyRight by Rysovaniy A. N.

; головна програма .686 ; директива визначення типу мікропроцесора .model flat ; завдання лінійної моделі пам’яті .stack 100h option casemap: none ; відмінність малих та великих літер extern _res1: proc ; указання на зовнішню процедуру extern _res2: proc ; указання на зовнішню процедуру public _a, _b, _c, _d ; доступ для інших модулів .data ; директива визначення даних

_a WORD 5 ; збереження у 16-розрядній комірці з ім’ям _а числа 5 _b WORD 16

_c WORD 81 _d WORD 2209

Рис. 7.9. Стан налагоджувача OllyDbg з програмою прикладу 7.1

Page 181: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

180

.code ; директива початку коду програми _start: ; початок програми з ім’ям start

_result proc clc ; скидання прапорця перенесення CF call _res1 ; виклик процедури _res1 call _res2 ; виклик процедури _res2 ret ; повернення керування ОС _result endp ; закінчення процедури

end _start ; закінчення програми з ім’ям start Листинг 7.16. Текст процедури _res1:

; (a-b)c .686 ; директива визначення типу мікропроцесора .model flat ; завдання лінійної моделі пам’яті option casemap: none ; відмінність малих та великих літер public _res1 ; об’ява змінної _res1 як внутрішньої extern _a: WORD ; об’ява змінної_a як зовнішньої extern _b: WORD ; об’ява змінної _b як зовнішньої extern _c: WORD ; об’ява змінної _c як зовнішньої

.code ; директива початку коду програми _res1 proc ; заголовок процедури

mov ax,_a ; занесення _a до ах add ax,_b ; обчислення _a + _b mul _c ; dx,ax = ax × _c mov si,ax ; запам’ятовування молодшої частини mov di,dx ; запам’ятовування старшої частини ret ; повернення до початку процедури

_res1 endp ; закінчення процедури з іменем _res1 end ; закінчення програми Листинг 7.17. Текст процедури _res2:

; -d/c .686 ; директива визначення типу мікропроцесора .model flat ; завдання лінійної моделі пам’яті

option casemap: none ; відмінність малих та великих літер public _res2 ; об’ява змінної _res2 як внутрішньої extern _d: WORD ; об’ява змінної _d як зовнішньої extern _c: WORD ; об’ява змінної _c як зовнішньої

.data ; директива визначення даних

Page 182: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

181

_res dw 3 dup (0) ; .code ; директива початку коду програми

_res2 proc ; заголовок процедури mov ax,_d ; занесення в ах змінної _d div _c ; ah,al := ax/_c xor bx,bx ; заповнювання нулями регістра sub bx,dx ; обчислення остачі mov _res,bx ; збереження остачі sbb si,ax ; обчислення молодших частин цілих чисел

; з урахуванням можливої позики сf при отриманні остачі mov _res+2,si ; збереження молодших частин цілих чисел sbb di,0 ; віднімання із старшої частини результату

; можливої позики від попередньої операції mov _res+4,di ; збереження старших частин цілих чисел ret ; повернення до початку процедури

_res2 endp ; закінчення процедури з іменем _res1 end ; закінчення програми Для кожної процедури спочатку отримують об’єктні файли з роз-

ширенням .obj. Ці файли можна отримати двома шляхами: послідовно, або одночасно. При послідовному отриманні в файловому менеджерові, наприклад FAR, виконують команди

ml /c /coff 03Р.asm де 03Р – ім’я одної програми.

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

ml /c /coff 03Р.asm 03_1P.asm 03_2P.asm Після отримання об’єктних файлів надається одна команда для

отримання файла з розширенням .ехе: link /SUBSYSTEM:CONSOLE 03Р.obj 03_1P.obj 03_2P.obj

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

правильність функціонування програми. Стан програми з декількома зовнішніми процедурами та порядок

розміщення даних у пам’яті наведено на рис. 7.10.

Page 183: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

182

Процес об’єднання декількох частин програми можна здійснити ще

на 1-й стадії трансляції. Це досягається за допомогою директиви INCLUDE. Наприклад, один файл міститиме код програми, а константи, дані (визначення змінних) і прототипи зовнішніх процедур поміщаються в окремі файли. Часто такі файли записують з розширенням .INC.

Саме таке розбиття демонструється в листингах 7.18 – 7.20). Листинг 7.18: ; файл CONS.INC

Рис. 7.10. Стан програми з декількома зовнішніми процедурами та порядок розміщення даних у пам’яті

Page 184: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

183

CONS1 EQU 1000 CONS2 EQU 2000 CONS3 EQU 3000 CONS4 EQU 4000 CONS5 EQU 5000 CONS6 EQU 6000 CONS7 EQU 7000 CONS8 EQU 8000 CONS9 EQU 9000 CONS10 EQU 10000 CONS11 EQU 11000 CONS12 EQU 12000 Листинг 7.19: ; файл DAT.INC DAT1 DWORD 0 DAT2 DWORD 0 DAT3 DWORD 0 DAT4 DWORD 0 DAT5 DWORD 0 DAT6 DWORD 0 DAT7 DWORD 0 DAT8 DWORD 0 DAT9 DWORD 0 DAT10 DWORD 0 DAT11 DWORD 0 DAT12 DWORD 0 Листинг 7.20: ; файл PROG1.ASM

.386p ; директива визначення типу мікропроцесора

.model flat, stdcall ; плоска модель include cons.inc ; підключити файл констант _data segment dword public use32 ‘data’ ; сегмент даних include dat.inc ; підключити файл даних _data ends _text segment dword public use32 ‘code’ ; сегмент коду

start: mov eax,cons1

Page 185: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

184

shl eax,1 ; множення на 2 mov dat1,eax mov eax,cons2 shl eax,2 ; множення на 4 mov dat2,eax mov eax, cons3 add eax, 1000 ; додавання 1000 mov dat3, eax mov eax, cons4 add eax, 2000 ; додавання 2000 mov dat4, eax mov eax, cons5 sub eax, 3000 ; віднімання 3000 mov dat5, eax mov eax, cons6 sub eax, 4000 ; віднімання 4000 mov dat6, eax mov eax, cons7 mov edx, 3 imul edx ; множення на 3 mov dat7, eax mov eax, cons8 mov edx, 7 ; множення на 7 imul edx mov dat8, eax mov eax, cons9 mov ebx, 3 ; ділення на 3 mov edx, 0 idiv ebx mov dat9, eax mov eax, cons10 mov ebx, 7 ; ділення на 7 mov edx, 0 idiv ebx mov dat10, eax mov eax, cons11 shr eax, 1 ; ділення на 2 mov dat11, eax mov eax, cons12

Page 186: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

185

shr eax, 2 ; ділення на 4 mov dat12, eax ret ; повернення керування ОС _text ends end start ; закінчення програми з ім’ям start Для запуску програми необхідно створити три файли, наприклад, з

іменами CONS.INC, DAT.INC, PROG1.ASM. З файла PROG1.ASM створити ехе-файл з відповідним іменем, а потім здійснити налаго-дження, як це наведено на рис. 7.11.

Результати виконання об’єднаної програми видні у вікні Address налагоджувача.

7.5. Лабораторна робота “ Передача параметрів через таблицю адресів ”

Мета заняття: – поглибити і закріпити знання з архітектури МП платформи х86 і

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

ня програм, написаних мовою асемблеру для програмування задач орга-нізації масивів для МП платформи х86.

Постановка задачі Згідно з останньою цифрою номера в групі вибрати варіант та на-

писати програму на асемблері обчислення одного з виразів: 1. Задано масиви А і В по N = 12 елементів. Навести алгоритм та

програму формування масиву С за правилом: якщо Аi ≤ Вi, то Сi = Вi – Аi; інакше – Сi = Аi + Вi.

2. Задано масив А з N = 55 елементів. Навести алгоритм та програму визначення кількості елементів масиву А, які задовольняють умову L ≥ Ai ≥ M, де L = 9 та M = 30.

3. Задано масив А з N = 45 елементів. Навести алгоритм та програму формування масиву В з останніх 13 елементів масиву А, які дорівнюють нулю.

4. Задано масив А з N = 55 елементів. Навести алгоритм та програму формування масиву В з елементів масиву А, які задовольняють умову Аi ≤ Е при Е = 12.

Page 187: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

186

5. Задано масив А з N = 70 елементів. Навести алгоритм та програму

визначення суми та кількості елементів масиву А, які задовольняють умову Аi ≤ Е при Е = – 13.

Рис. 7.11. Налагодження програми з іменем PROG1

Page 188: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

187

6. Задано масиви А і В по N = 50 елементів. Навести алгоритм та програму визначення кількості пар елементів, які задовольняють умову Аi ≤ Ві.

7. Задано масиви А і В по N = 65 елементів. Навести алгоритм та програму формування масиву С за правилом: якщо Аi – Вi ≤ 0, то Сj = Aі.

8. Задано масив А з N = 50 елементів. Навести алгоритм та програму визначення максимального з негативних елементів масиву А.

9. Задано масив А з N = 50 елементів. Структура масиву А: X1,Y1;X2,Y2; … . Навести алгоритм та програму визначення кількості пар, для яких виконується умова Хi < Yi.

9. Задано масив А з N = 28 елементів. Навести алгоритм та програму формування масиву В з елементів масиву А, у яких біти 0, 2 та 5 мають нулі.

10. Задано масив А з N = 40 елементів. Навести алгоритм та програ-му визначення суми елементів масиву А, для яких біти 2 та 10 збігають-ся.

11. Задано масив А з N = 80 елементів. Структура масиву А: X1,Y1;X2,Y2; … . Навести алгоритм та програму визначення кількості пар, для яких виконується умова Хi > Yi.

12. Задано масив А з N = 20 елементів. Навести алгоритм та програ-му визначення мінімального з позитивних елементів масиву А.

13. Задано масиви А і В по N = 30 елементів. Навести алгоритм та програму формування масиву С за правилом: якщо Аi + Вi > 0, то Сj = Ві.

14. Задано масиви А і В по N = 20 елементів. Навести алгоритм та програму визначення кількості пар елементів, які задовольняють умову Аi > Ві.

15. Задано масив А з N = 40 елементів. Навести алгоритм та програ-му визначення суми та кількості елементів масиву А, які задовольняють умову Аi > Е при Е = – 10.

16. Задано масив А з N = 22 елементів. Навести алгоритм та програ-му сформування масиву В з елементів масиву А, які задовольняють умо-ву Аi > Е при Е = 5.

17. Задано масив А з N = 30 елементів. Навести алгоритм та програ-му формування масиву В з перших 8 позитивних елементів масиву А.

18. Задано масив А з N = 20 елементів. Навести алгоритм та програ-му визначення кількості елементів масиву А, які задовольняють умову L < Ai ≤ M, де L = 2 та M = 10.

Page 189: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

188

19. Задано масиви А і В по N = 11 елементів. Навести алгоритм та програму формування масиву С за правилом: якщо Аi > Вi, то Сi = Аi + Вi; інакше – Сi = Аi – Вi.

20. Задано масив А з N = 50 елементів. Навести алгоритм та програ-му визначення кількості елементів масиву А, які задовольняють умову L > Ai > M, де L = 8 та M = 28.

21. Задано масиви А і В по N = 10 елементів. Навести алгоритм та програму формування масиву С за правилом: якщо Аi < Вi, то Сi = Вi – Аi; інакше – Сi = Аi + Вi.

Зміст звіту 1. Постановка задачі для конкретного варіанта. 2. Блок-схема алгоритму виконання прикладу з детальним комента-

рем та описом роботи. 3. Листинг програми з виведенням даних на екран монітора з вико-

ристанням API-функцій та з детальним коментарем і описом роботи. 4. Рrint screen екрана 32-розрядного налагоджувача з виконаною

програмою. 5. Висновки за результатами роботи.

7.6. Лабораторна робота “API-подібні процедури

Мета заняття: – поглибити і закріпити знання з архітектури МП платформи х86 і

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

ня програм, написаних мовою асемблеру для програмування API-подібних функцій для МП платформи х86.

Постановка задачі Згідно з останньою цифрою номера в групі вибрати варіант та на-

писати програму на асемблері обчислення одного з виразів: 1. b/с – сd 2. a – c/e 3. cb/a + a 4. a/b – d/c 5. b/c + ac 6. ab – c/d 7. 8d – b/c 8. a/b + c

Page 190: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

189

9. 2a/3b – c 0. b – 2c/d

де a – № в списку; b – № навчальної групи; c – рр – дві останні цифри року народження; е – рррр – чотири цифри року народження; d – ддмм:

дд – день народження; мм – місяць народження.

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

Зміст звіту

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

рем та описом роботи. 3. Листинг програми з виведенням даних на екран монітора з вико-

ристанням API-функцій та з детальним коментарем і описом роботи. 4. Рrint screen екрана 32-розрядного налагоджувача з виконаною

програмою. 5. Висновки за результатами роботи. Приклад 7.2. Написати програму на асемблері обчислення виразу

а × b +c, де a = 4, b = 5, c = 6, оформити її у вигляді API-подібної функції та результат виконання ви-разу зберегти у пам’яті.

Листинг 7.21. Програма обчислення прикладу 7.2: title CopyRight by Rysovaniy A. N. [email protected] .386 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap:none ; відмінність малих та великих літер includelib \masm32v9_0\lib\kernel32.lib ExitProcess proto :DWORD ; прототип процедури OperDigs proto :WORD, :WORD, :WORD ; прототип процедури

.data ; директива визначення даних res dw 2 dup(0) ; резервування комірок для результату

.code ; директива початку програми

Page 191: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

190

start: ; мітка початку програми з ім’ям start invoke OperDigs,4,5,6 ; виклик директиви з параметрами invoke ExitProcess,0 ; виклик директиви з параметрами OperDigs proc arg1:WORD,arg2:WORD,arg3:WORD

mov ax,arg1 `; ax := arg1 mul arg2 ; dx,ax = ax × arg1 add ax, arg3 jc m1 ; перейти, якщо є перенесення jmp m2

m1: inc dx ; dx + 1, якщо перенесення є m2:

mov res,ax ; запам’ятовування в пам’яті mov res+2,dx ; запам’ятовування в пам’яті ret ; повернення з процедури

OperDigs endp ; закінчення процедури OperDigs end start ; закінчення програми з ім’ям start У зв’язку з тим, що числа вибрані не великі, то для їх визначення

вибрано слово WORD. Порядок розміщення даних у пам’яті та стан налагоджувача

OllyDbg з програмою з листингу 7.21 наведено на рис. 7.12. Результат виконання операції прикладу 7.2 розташовано у двох ре-

гістрах: EAX = 001А, та EDX = 0000.

7.7 Лабораторна робота “Зовнішні процедури”

Мета заняття: – поглибити і закріпити знання з архітектури МП платформи х86 і

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

ня програм, написаних мовою асемблеру з використанням зовнішніх процедур для МП платформи х86.

Постановка задачі Згідно з останньою цифрою номера в групі вибрати варіант та на-

писати програму на асемблері обчислення одного з виразів:

Page 192: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

191

1. 2(a – b/с) – cd; 2. a – (c/e – a)b; 3. 4(a – cb)/b + d; 4. 8d – a/b – d/a; 5. a – b/c + ac; 6. 8c – ad – b/e; 7. (a – e/d)b – c/d; 8. (a – b)a/b – de; 9. (b – 2d)/4a – с; 0. ae – b – 2b/c. Вимоги до програм: 1. Передбачити ситуацію, при якій числа змінюються від мінімаль-

ного до максимального значень (урахувати можливі переповнення роз-рядної сітки та позики);

Рис. 7.12. Порядок розміщення даних у пам’яті та стан налагоджувача OllyDbg з програмою з листингу 7.21

Page 193: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

192

2. Для перших десяти за списком студентів змінні повинні мати ро-змір байта, для других десяти за списком студентів – розмір слова, а для третіх десяти за списком студентів – розмір подвійного слова;

3. Привести програму з використанням зовнішніх процедур. Зміст звіту 1. Постановка задачі для конкретного варіанта. 2. Блок-схема алгоритму виконання прикладу з детальним комента-

рем та описом роботи. 3. Листинг програм: головної та зовнішньої процедури з детальним

коментарем та описом роботи. 4. Рrint screen екрана 32-розрядного налагоджувача з виконанням

програми та результатами виконання виразу. 5. Висновки за результатами роботи. Приклад 7.3. Хай потрібно обчислити вираз ab – c/d , де а, b, с, d

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

шована у файлі 9_14_1L.asm, що обчислює ab – cd. В головній програмі виконується тільки виклик зовнішньої процедури.

Складемо схему виконання прикладу (рис. 7.13). Остаток результату запам’ятовується у комірці пам’яті з ім’ям

res[0], а щодо цілої частини, то старша – у комірці res[8], а молодша – у res[4].

Згідно зі схемою складемо головну та додаткову програми. Голов-ну програму з іменем 9_14L.asm наведено у листингу 7.22.

еdx eax ст. мол.

eax := a ebx := b ×

edi esi

eax := c ebx := d /

edx eax дріб ціле

ecx 0…0

eax edx ціле дріб

res[8] res[4] , res[0]

Рис. 7.13. Схема виконання прикладу 7.3

Page 194: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

193

Листинг 7.22. Головна програма обчислення виразу ab – c/d. title CopyRight by Rysovaniy A. N. .386 ; директива визначення типу мікропроцесора

.model flat ; завдання лінійної моделі пам’яті Extern _abcd:proc ; указання на зовнішню процедуру Public _a, _b,_c, _d, _res ; доступ для інших модулів .data ; директива визначення даних (ab – c/d) _a dd 0FFFFFFFFh ; запис у 32-розрядну комірку з ім’ям _а _b dd 0FFFFFFFFh ; 4294967295 _c dd 0FFFFFFFFh ; запис у 32-розрядну комірку з ім’ям _с _d dd 0FFFFFFFh ; запис у 32-розрядну комірку з ім’ям _d _res dd 3 dup(0) ; комірки для збереження результату

.code ; директива початку програми _start: ; мітка початку програми з ім’ям start

call _abcd ; виклик процедури ret ; повернення керування ОС

end _start ; директива закінчення програми з ім’ям start Як команда асемблеру програма з листингу 7.22 складається з

однієї команди call _abcd. Всі інші команди наведено у іншому файлі, який містить процедуру обчислення виразу ab – c/d (листинг 7.23).

Листинг 7.23. Текст процедури з іменем _abcd: title CopyRight by Rysovaniy A. N. .386 ; директива визначення типу мікропроцесора

.model flat ; завдання лінійної моделі пам’яті public _abcd extern _a:dword, _b:dword, _c:dword,_d:dword,_res:dword

.code ; директива початку програми _abcd proc ; ab - c/d

mov eax,_a ; пересилання з комірки пам’яті з ім’ям _а в eax mov ebx,_b ; пересилання з комірки пам’яті з ім’ям _b в ebx mul ebx ; edx, eax := eax × ebx mov esi,eax mov edi,edx mov eax,_c mov ebx,_d xor edx,edx ; підготування до ділення div ebx

Page 195: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

194

mov ecx,0 sub ecx,edx ; віднімання остатка з цілого числа mov _res[0],ecx ; запам’ятання остатка у пам’яті sbb esi,eax ; віднімання цілої молодшої частини

mov _res[4],esi ; запам’ятовування молодшої цілої частини у пам’яті sbb edi,0 ; віднімання позики, якщо вона є mov _res[8],edi ; запам’ятовування старшої цілої частини у пам’яті

ret _abcd endp

end ; директива закінчення програми

При написанні програми слід звернути увагу на команду ділення, яка потребує перед її виконанням ініціювати (обнулити) регістр EDX. Якщо цього не зробити, то не зважаючи на те, що буде створено exe-файл, при покроковому виконанні здійсниться зависання програми.

Результатом виконання програми, розташованої двох файлах є число FFFF FFFD FFFF FFF0,FFFF FFF1h, яке можна побачити на рис. 7.14 у вікнах налагоджувача.

Приклад 7.4. Хай потрібно обчислити вираз 3(a + b/4) – cd , де а,

b, с, d – цілі числа. Обчислення виконаємо за допомогою однієї процедури,

розташованої у файлі 9_12L.asm, яка обчислює cd. Перед тим, як почати запис програми, необхідно повністю уявляти

схему виконання прикладу (рис. 7.15). Остаток результату запам’ятовується у пам’яті з ім’ям resR, знак

числа – у res[0ch]. Головний об’єктний модуль на початку сегмента коду містить

мітку початку програми, наприклад START. Це ж ім’я указується після директиви END – транслятор повинен знати точку входу програми, щоб вказати її в заголовку завантажуваного модуля.

При об’єднанні декількох модулів першим повинен йти головний, а інші – в довільному порядку.

Page 196: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

195

Рис. 7.14. Процес виконання програми та одержання результату

xxxx xxxx := b

Рис. 7.15. Схема виконання прикладу

/ 4 edx, eax дріб ціле resR

+ a

ecx eax × 3 × 3

edx, eax

edi, esi edx, eax

res[0ch] res[8] res[4] res[0] , resR[0] resR[4]

+

res_cd[4] res_cd[0]

Знак edi

resR × 3

edx, eax

Page 197: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

196

Всі файли мають розширення .ASM, які після компіляції утворюють файли об’єктних модулів з розширенням .OBJ за допомогою команди:

ml /c /coff 9_12L.asm 9_12_1L.asm <enter> За допомогою компонувальника (link або іншого) ці файли можна

включити в 32-розрядний додаток, наприклад: link /subsystem:console 9_12L.obj 9_12_1L.obj <enter>

Текст підпрограми _add_sub наведено в листингу 7.24.

Листинг 7.24. Загальний текст програми обчислення 3(a+b/4) – cd:

title CopyRight by Rysovaniy A. N., обчислення 3(a+b/4) – cd .386 ; директива визначення типу мікропроцесора .model flat ; завдання лінійної моделі пам’яті Extern _cd:proc ; указання на зовнішню процедуру Public _c, _d, res_cd ; доступ для інших модулів

.data _a dd 0FFFFFFFFh ; _b dd 0FFFFFFFFh ; 4294967295 _c dd 0FFFFFFFFh ; 4294967295 _d dd 0FFFFFFFFh ; 4294967295 res_cd dd 2 dup(0) resR dd 2 dup(0) ; для збереження залишку res dd 4 dup(0)

.code ; директива початку програми

_start: ; мітка початку програми з ім’ям start mov eax,_b ; mov ebx,4 ; xor edx,edx ; підготовка до ділення (заповнювання нулями) div ebx ; edx – залишок, eax – ціла частина (b/4) mov resR,edx ; збереження залишку у пам’яті add eax,_a ; (a + b/4) jc m1 ; перейти на m1, якщо є перенесення (CF = 0) mov ecx,0 ; якщо немає перенесення jmp m2 ; йти далі

m1: mov ecx,1 ; якщо є перенесення m2: mov ebx,3 ; підготовка до перемноження на 3

Page 198: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

197

mul ebx ; 3(a + b/4) mov esi,eax ; збереження мол. частини mov edi,edx ; збереження старшої частини mov eax,ecx ; підготовка до перемноження перенесення mul ebx ; add edi, eax ; jc m3 ; jmp m4 ;

m3: inc edx ; додати 1, якщо є перенесення m4: mov eax,resR ; множення остатка на 3

mul ebx mov resR[0],edx mov resR[4],eax

push edx ; підготовка до виклику процедури push edi push esi push ecx

call _cd ; виклик процедури pop ecx ; повернення значень pop esi pop edi pop edx cmp eax,res_cd[7] ; порівняння зменшуваного і від’ємника

jc m5 ; перейти на m5, якщо зменшуване менше від’ємника ; інакше, виконувати, якщо зменшуване > від’ємника

sub esi, res_cd[0] ; mov res[0],esi ; запам’ятовування молодшої цілої частини sbb eax, res_cd[4] ; mov res[4],edi ; запам’ятовування старшої цілої частини sbb edx,0 ; mov res[8],edx mov res[0ch],0 ; знак jmp m7 ; перехід на закінчення

m5: sub res_cd[0],esi ; mov esi,res_cd[0] ; запам’ятовування молодшої цілої частини mov res[0],esi ; sbb res_cd[4],edi mov eax,res_cd[4] ; підготування для запам’ятовування

; старшої цілої частини

Page 199: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

198

mov res[4],eax ; запам’ятовування старшої цілої частини sbb edx,0 ; mov res[8],edx mov res[0ch],1 ; знак

m7: ret ; повернення керування end _start ; закінчення програми В листингу 7.25 наведено текст процедури _cd обчислення добутку

cd. Листинг 7.25. Текст процедури _cd: title CopyRight by Rysovaniy A. N.

.386 ; директива визначення типу мікропроцесора

.model flat ; завдання лінійної моделі пам’яті public _cd extern _c:dword,_d:dword,res_cd:dword

.code ; директива початку програми

_cd proc mov eax,_c mov ebx,_d mul ebx ; eax × ebx = edx, eax

mov res_cd[0],eax ; запам’ятовування молодшої цілої частини mov res_cd[4],edx ; запам’ятовування старшої цілої частини

ret _cd endp ; закінчення процедури end Результат виконання програми прикладу наведено на рис. 7.16. Результатом виконання програми є число

1 00000000 FFFF FFFA 4000 0007,09. Залишок виконання прикладу запам’ятовується у комірках, що

починаються з номера 0040201C, молодше ціле – з 00402020, старше ціле – з 00402024, а знак – з 0040202C.

Page 200: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

199

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

Page 201: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

200

8. ОРГАНІЗАЦІЯ ВВЕДЕННЯ – ВИВЕДЕННЯ В WIN32

8.1. Загальні відомості Операційна система Windows на відмінну від MS-DOS функціонує

в 32-розрядних додатках і запускається в захищеному режимі (Protected mode), тоді як програми для MS-DOS працюють в режимі реальних адрес (Real-address mode). Тому використовуються абсолютно різні бібліотеки. 32-розрядні додатки працюють з тими ж бібліотеками функцій, які використовують і графічні додатки Windows, а програми для MS-DOS використовують BIOS і переривання MS-DOS, які існують з дня появи перших персональних комп’ютерів IBM-PC.

Системні програми – це програми загального користування, виконувані разом із прикладними й службовими для керування ресурсами комп’ютера – центральним процесором, пам’яттю, процесом введення-виведення. Звернення до клавіатури і монітора (консольне введення-виведення) в Windows здійснюється за допомогою виклику функцій, а не переривань, характерних для DOS. Тут немає передачі параметрів в регістрах при зверненні до сервісних функцій і, відповідно, немає і безлічі результуючих значень повертаних в регістрах загального призначення і регістрі прапорців. В Win32 не можна безпосередньо працювати з апаратним рівнем, як було прийнято для програм DOS.

Операційні системи MS-DOS і Windows підтримують дві абсолютно різні ідеології програмування. Програма DOS після свого запуску повинна бути постійно активною. Якщо їй щось потрібно (наприклад, одержати чергову порцію даних з пристрою введення-виведення), то вона сама повинна виконувати відповідні запити до операційної системи. При цьому програма DOS працює за певним алгоритмом і вона завжди знає, що і коли їй слід робити.

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

Page 202: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

201

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

Для забезпечення нормального функціонування своєї програми програміст повинен уміти ефективно використовувати функції інтерфейсу прикладного програмування (API, Application Program Interface) операційної системи.

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

функцій (API), що становлять графічний інтерфейс користувача (GUI, Graphic User Interface). Віконний додаток є програмою, яка виведення на екран проводить в графічному вигляді. Першим результатом роботи віконного додатка є відображення на екрані спеціального об’єкта – вікна. Після відображення вікна на екрані, вся робота додатка спрямовується на те, щоб підтримувати його в актуальному стані;

– невіконний додат ок, або консольний, який є програмою, що працює в текстовому режимі. Робота консольного додатка забезпечується спеціальними функціями Windows.

У переважній більшості випадків програма повинна взаємодіяти з користувачем, одержуючи від нього дані за допомогою клавіатури і видаючи результати своєї роботи на екран (консоль – клавіатура і монітор). Для здійснення введення-виведення програма використовує можливості самого комп’ютера (переривання BIOS) і операційної системи, в середовищі якої ця програма працює.

Таким чином, Windows підтримує роботу двох типів додатків – віконних, що повною мірою використовують всі достоїнства графічного інтерфейсу, і консольних, що працюють виключно в текстовому режимі.

Консоль складається з одного вхідного і декількох екранних

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

Черга вхідного буфера містить інформацію про такі події: – натиснення і відпуск клавіш; – маніпуляцію мишею – рух, натиснення-відпуск кнопок; – зміну розміру активного екранного буфера, стан прокрутки. Функції Win API які працюють в текстовому режимі надають два

рівні доступу до консолі – високий і низький. Консольні функції

Page 203: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

202

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

Функції API Win32 високого рівня забезпечують простоту процесу введення-виведення шляхом використання стандартних дескрипторів введення-виведення [8]. Функції низького рівня вимагають обліку більшої кількості деталей і об’єму коду, але це компенсується більшою гнучкістю програми.

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

При запуску додатка для Windows він створює або консольне вікно (консоль), або графічне вікно.

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

/SUBSYSTEM:CONSOLE. У програмі для консолі читання і запис відбуваються в стандартні

входи і виходи. Помилки також записуються в стандартний файл помилок. Консоль має один вхідний буфер і один або декілька екранних буферів.

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

Екранний буфер містить двовимірний масив символів і даних про колір, які необхідні для відображення символів на екрані.

8.2. Набір символів і функції Windows API

При виклику функцій Win32 API можна використовувати один з

двох наборів символів. Це набір 8-розрядних символів ASCII/ANSI і

Page 204: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

203

набір 16-розрядних символів Unicode (доступні в Windows NT, 2000 і ХР). Функції Windows API, що працюють з текстом, звичайно мають дві версії: одна з них призначена для роботи з 8-розрядними символами ASCII/ANSI (імена закінчуються символом А), а інша – для роботи з розширеним набором символів, включаючи Unicode (імена закінчуються символом W). Наприклад, для відображення інформації на консолі використовуються такі функції:

WriteConsoleA WriteConsoleW Імена функцій, що закінчуються на W, не підтримуються в

Windows 95 або 98. Навпаки, в Windows NT, 2000 і ХР набір символів Unicode є вбудованим для цих систем. Тому коли викликається така функція, як WriteConsoleA, операційна система спочатку перетворює символи з набору ANSI в Unicode, а потім викликає функцію WriteConsoleW.

8.3. Типи даних Windows

Функції Win32 API базуються на синтаксисі, використовуваному

для мов С або C++. У оголошенні функцій Win32 API типи всіх параметрів засновані на стандартних типах С або на зумовлених типах MS-Windows, як наведено у табл. 8.1. Необхідно відрізняти дані типу "значення" від даних типу "вказівник". Типи, імена яких починаються з букв "LP", є дальніми вказівниками об’єктів.

Таблиця 8.1

Відповідність типів MS-Windows і MASM Типи MS-Windows

Типи MASM

Опис

BOOL BYTE Булеве значення BSTR PTR BYTE 32-розрядний вказівник символів BYTE BYTE 8-розрядне ціле число без знаку

COLORREF DWORD 32-розрядне число, використовуване як характеристика кольору

DWORD DWORD 32-розрядне ціле число без знаку або адреса сегмента і пов’язаний з ним зсув

Page 205: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

204

Продовження табл. 8.1 HANDLE DWORD 32-розрядне ціле число без знака LONG SDWORD 32-розрядне ціле число із знаком LPARAM DWORD 32-розрядне значення, яке передається як

аргумент у віконні процедури або функції зворотного виклику (може бути вказівником)

LPCSTR PTR BYTE 32-розрядний вказівник константи типу "символьний рядок"

LPSTR PTR BYTE 32-розрядний вказівник символьного рядка LPCTSTR DWORD 32-розрядний вказівник константи типу

‘‘символьний рядок", який складений з символів Unicode або з набору двобайтових символів

LPTSTR DWORD 32-розрядний вказівник символьного рядка, який складений з символів Unicode або з набору двобайтових символів

LPVOID DWORD 32-розрядний вказівник невизначеного типу LRESULT DWORD 32-розрядне значення, яке повертається

віконною процедурою або функцією зворотного виклику

UINT DWORD 32-розрядне ціле число без знака WNDPROC DWORD 32-розрядний вказівник віконної процедури WORD WORD 16-розрядне ціле число без знака WPARAM DWORD 32-розрядне значення, яке передається як

аргумент у віконні процедури або у функції зворотного виклику

LPCRECT PTR RECT 32-розрядний вказівник структури RECT, що не модифікується (на константу)

8.4. Дескриптори консолі

Майже всі функції для роботи з консоллю вимагають передачі дескриптора як першого аргументу. Дескрипт ор є 32-розрядним цілим числом без знака, яке унікально ідент ифікує об’єкт , такий, як растрове зображення (bitmap) або креслярське перо, або вхідні і вихідні пристрої. Найчастіше використовуються дескриптори для таких пристроїв:

Page 206: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

205

STD_INPUT_HANDLE – стандартний вхід; STD_OUTPUT_HANDLE – стандартний вихід; STD_ERROR_HANDLE – стандартний вихід помилок. Функція GetStdHandle повертає дескриптор потоку для консолі:

вхід, вихід або вихід помилок. Дескриптор необхідний для створення входу-виходу в програмах, що працюють з консоллю. Прототип функції GetStdHandle

GetStdHandle PROTO nStdHandle:DWORD

Він розміщений у файлі windows.inc. Функція GetStdHandle може набувати значення STD_INPUT_

HANDLE, STD_OUTPUT_HANDLE або STD_ERROR_HANDLE. Ці константи описані в стандартних заголовних файлах і мають значення -10, -11 і -12 відповідно. Функція повертає значення дескриптора в регістр ЕАХ, яке повинне бути збережене для подальшого використання. Нижче показаний невеликий приклад.

.DATA директива визначення даних inputHandle DWORD ? ; резервування 32-розрядної комірки

.CODE ; директива початку коду програми invoke GetStdHandle, STD_OUTPUT_HANDLE ; одержання дескриптора

mov inputHandle, EAX ; запис дескриптора в пам’ять Оскільки константа STD_INPUT_HANDLE визначає пристрій, для

якого в Windows використовується чисельне значення -10, то в даному випадку замість ідентифікатора STD_INPUT_HANDLE можна підставити число -10. Проте використання зрозумілого ідентифікатора значно полегшує роботу і звільняє від запам’ятовування абсолютно неінформативних чисел. До того ж ідентифікатору STD_INPUT_HANDLE десь повинно бути привласнено значення -10. Звичайне це робиться в заголовних (що підключаються) файлах, які мають розширення .inc і які повинні бути підключені до бібліотеки або програми за допомогою ключового слова INCLUDE.

8.5. Функції консолі Win32

У табл. 8.2 наводиться короткий опис всіх функцій для роботи з

консоллю Win32. Повні описи API-функцій можна знайти в бібліотеці MSDN (http://msdn.microsoft.com/library/).

Page 207: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

206

Таблиця 8.2 Функції консолі Win32

Функція Опис AllocConsole Створює нову консоль CreateConsoleScreen-

Buffer Створює екранний буфер консолі

FillConsoleOutputAttribute Установлює атрибути тексту і фону для вказаних символів

FillConsoleOutput-Character

Записує символ в екранний буфер задане число раз

FlushConsolelnputBuffer Виводить весь вміст буфера консолі FreeConsole Відключає консоль від процесу, що

викликав її GenerateConsoleCtrlEvent Посилає спеціальний сигнал в процеси,

пов’язані з консоллю, для дозволу доступу додатково до процесу, що викликав її

GetConsoleCP Витягує вхідну кодову сторінку, використовувану консоллю процесу, що викликав її

GetConsoleCursorlnfо Витягує інформацію про розмір і видимість курсора для вказаного екранного буфера консолі

GetConsoleMode Витягує інформацію про поточний режим введення буфера консолі або про режим виведення для екранного буфера консолі

GetConsoleOutputCP Витягує вихідну кодову сторінку, використовувану консоллю процесу, що викликав її

GetConsoleScreen-Bufferlnfо

Витягує інформацію про вказаний екранний буфер консолі

GetConsoleTitle Витягує рядок заголовка вікна для поточного вікна консолі

GetConsoleWindow Витягує дескриптор вікна консолі GetLargestConsoleWindow

Size Витягує найбільший допустимий розмір

вікна консолі

Page 208: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

207

Продовження табл. 8.2 GetNumberOfConsolelnput

Events Витягує число непрочитаних вхідних

записів у вхідний буфер консолі GetNumberOfConsole-

MouseButtons Повертає число кнопок миші,

використовуваних з консоллю GetStdHandle Повертає дескриптори для стандартного

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

MessageBox Cтворення вікна консолі HandlerRoutine Оголошує в додатку функцію,

використовувану з функцією PeekConsolelnput Прочитує дані з вхідного буфера консолі

без видалення даних з буфера ReadConsole Прочитує дані з вхідного буфера консолі

і видаляє дані з буфера ReadConsolelnput Прочитує дані з вхідного буфера консолі

і видаляє дані з буфера ReadConsoleOutput Прочитує символи і атрибути кольору з

вказаного прямокутного блока в екранному буфері консолі

ReadConsoleOutput-Attribute

Копіює вказане число послідовних колірних атрибутів для тексту і фону з екранного буфера консолі

ReadConsoleOutput-Character

Копіює вказане число послідовних символів з екранного буфера консолі

ScrollConsoleScreenBuffer Переміщає блок даних в екранний буфер SetConsoleActiveScrecn-

Buffer Встановлює вказаний екранний буфер

як поточний екранний буфер консолі SetConsoleCP Встановлює вхідну кодову сторінку,

використовувану консоллю для процесу, що викликав її

SetConsoleCtrIHandler Додає або видаляє певні дескриптори в додатку HandlerRoutine із списку обробників функцій для процесу, що викликається

SetConsoleCursorInfо Встановлює розмір і видимість курсора для екранного буфера консолі

Page 209: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

208

Закінчення табл. 8.2 SetConsoleCursorPosition Встановлює позицію курсора в

екранному буфері консолі SetConsoleMode Встановлює режим введення для

вхідного буфера консолі або режим виведення для екранного буфера консолі

SetConsoleOutputCP Встановлює використовувану консоллю кодову сторінку для виведення, пов’язану з процесом, що викликається

SetConsoleScreenBufferSize Змінює розмір екранного буфера консолі SetConsoleTextAttribute Встановлює колірні атрибути тексту і

фону символів, записуваних в екранний буфер консолі

SetConsoleTitle Встановлює заголовок поточного вікна консолі

SctConsoleWindowInfо Встановлює поточний розмір і положення вікна для екранного буфера консолі

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

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

WriteConsolelnput Записує дані безпосередньо у вихідний буфер консолі

WriteConsoleOutput Записує символ і колірні атрибути у вказаний прямокутний блок в екранному буфері консолі

WriteConsoleOutputAttribut Копіює декілька колірних атрибутів для тексту і фону в послідовні осередки екранного буфера консолі

WriteConsoleOutput- Character

Копіює декілька символів в послідовні осередки екранного буфера консолі

Page 210: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

209

8.6. Виведення повідомлень

Для виведення повідомлень розглянемо функцію WriteConsoleA. Функція WriteConsoleA Функція (процедура) WriteConsoleA, що виводить символи на

екран, має прототип WriteConsoleA proto :dword,:dword,:dword,:dword,:dword

та п’ять параметрів, але п’ятий завжди дорівнює нулю. Перші чотири параметри такі:

1. stdout – це дескриптор стандартного пристрою виведення (екрана монітора), одержаний процедурою

GetStdHandle. 2. ADDR msg – адреса початку повідомлення. Щоб одержати його,

використовується спеціальний оператор отримання адреси ADDR. 3. SIZEOF msg – розмір повідомлення, тобто число байтів в ньому.

Наше повідомлення, поміщене в лапки, складається з 18 байтів (16 байтів займають букви і два байти – символи 0dh, 0ah, які командують процедурі WriteConsoleA перевести рядок). Розмір повідомлення (число байтів від вказаної мітки msg до наступної CWritten) програма-асемблер обчислює під час компіляції.

4. ADDR cWritten – адреса ділянки пам’яті, де процедура WriteConsoleA зберігає число виведених на екран символів.

Прототип функції WriteConsoleA розміщений у файлі kernel32.lib. Розглянемо невеликий приклад виведення на консоль тексту

(листинг 8.1). Листинг 8.1. Виведення повідомлення на екран монітора: title виведення повідомлення .386 ; директива визначення типу мікропроцесора

.model flat, stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap:none ; відмінність малих та великих літер ExitProcess proto :dword ; прототип функції GetStdHandle proto :dword ; прототип функції WriteConsoleA proto :dword,:dword,\

:dword,:dword,:dword ; прототип функції includelib\masm32v9_0\lib\kernel32.lib

.data ; директива визначення даних stdout dd ? ; комірка для збереження дескриптора

Page 211: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

210

msg db «He могу молчать!»,0dh,0ah cWritten dd ? ; адреса для збереження виведених символів

.code ; директива початку коду програми start: ; мітка початку програми з ім’ям start invoke GetStdHandle, -11 ; завдання дескриптора станд. пристрою

mov stdout, eax ; збереження одержаного дескриптора у пам’яті

invoke WriteConsoleA, \ ; АРІ-функція виведення на екран stdout, \ ; дескриптор стандартного пристрою виведення

ADDR msg,\ ; адреса початку повідомлення sizeof msg, \ ; розмір повідомлення

ADDR cWritten, \ ; адреса, де зберігається число символів 0 ;

invoke ExitProcess, 0 ; повернення керування ОС Windows

; та визволення ресурсів end start ; закінчення програми Для прискорення виконання програми рекомендується створити

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

ml /c /coff "01L.asm" link /SUBSYSTEM:CONSOLE "01L.obj"

Після утворення .exe-файла необхідно виконати його, натиснувши

кнопку Enter. У файловому менеджерові FAR буде відображене таке (рис. 8.1):

Рис. 8.1. Відображення на екрані процесу виконання програми листингу 8.1

Page 212: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

211

У програмі викликаються дві процедури: GetStdHandle і WriteConsoleA. Їх прототипи наводяться на початку програми. Якщо прототип процедури не уміщався на одному рядку, опис процедури може продовжуватися на наступному рядку при використанні косої межі.

Процедура GetStdHandle одержує дескрипт ор ст андарт ного прист рою – 32-розрядне число, яке потрібно указувати іншим процедурам, що взаємодіють з цим пристроєм. Щоб, наприклад, дізнатися продескриптор стандартного пристрою виведення, куди буде відправлена фраза “Не могу молчать”, параметр повинен бути дорівнювати –11. Рядок

invoke GetStdHandle, -11 замінюється на команду push -0B та виклик процедури call (рис. 8.2).

Процедура GetStdHandle розміщує результат своєї роботи в

регістрі еах. Тому команда mov stdout. eах зберігає одержаний дескриптор в пам’яті.

У програмі з листингу 8.2 прототипи процедур розміщені у файлах

відповідних бібліотек.

Рис. 8.2. Стан програми листингу 8.1 після її завершення

Page 213: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

212

Листинг 8.2. Використання готових прототипів процедур: title готові прототипи процедур .386 ; директива визначення типу мікропроцесора .model flat, stdcall ; завдання лінійної моделі пам’яті

; та угоди ОС Windows option casemap:none ; відмінність малих та великих літер

include \masm32v9_0\include\windows.inc include \masm32v9_0\include\kernel32.inc includelib \masm32v9_0\lib\kernel32.lib

.data ; директива визначення даних stdout DWORD ? ; резервування в пам’яті 32-розрядної комірки

; з ім’ям stdout для збереження дескриптора виведення msg db "Не могу молчать!",0dh,0ah cWritten dd ? ; адреса для збереження виведених символів

.code ; директива початку коду програми start: ; мітка початку програми з ім’ям start

invoke GetStdHandle, STD_OUTPUT_HANDLE mov stdout, eax ; збереження одержаного дескриптора у пам’яті

invoke WriteConsoleA, \ ; АРІ-функція виведення на екран stdout, \ ; дескриптор стандартного пристрою виведення

ADDR msg,\ ; адреса початку повідомлення sizeof msg, \ ; розмір повідомлення

ADDR cWritten, \ ; адреса, де зберігається число символів 0 ;

invoke ExitProcess, 0 ; повернення керування ОС Windows ; та визволення ресурсів

end start ; закінчення програми Прототипи процедур переселилися у файл kernel32.inc, що

підключається. А файл windows.inc містить всього один рядок програми STD_OUTPUT_HANDLE equ -11, що говорить асемблеру, що всі імена STD_OUTPUT_HANDLE, зустрінуті в програмі, потрібно замінити на -11.

Розглянемо програму визначення парного числа та виведення результату на монітор (листинг 8.3).

Листинг 8.3. Програма визначення парного числа: .386 ; директива визначення типу мікропроцесора .model flat, stdcall ; завдання лінійної моделі пам’яті

Page 214: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

213

; та угоди ОС Windows option casemap:none ; відмінність малих та великих літер

include \masm32v9_0\include\windows.inc include \masm32v9_0\include\kernel32.inc includelib \masm32v9_0\lib\kernel32.lib

.data ; директива визначення даних FellowDig BYTE "Парне",13,10 NFellowDig BYTE "Непарне",13,10

stdout DWORD ? ; резервування в пам’яті 32-розрядної комірки ; з ім’ям stdout для збереження дескриптора виведення

cWritten DWORD ? ; резервування 32-розрядної комірки пам’яті ; з ім’ям cWritten для адреси символів виведення

.code ; директива початку коду програми start: ; мітка початку програми з ім’ям invoke GetStdHandle, STD_OUTPUT_HANDLE ; запис дескриптора в еах mov stdout, eax ; збереження одержаного дескриптора у пам’яті

mov ah, 43 ; завантаження числа, яке аналізується test ah, 00000001b ; виділяємо молодший біт jz next ; перейти, якщо парне

invoke WriteConsoleA, stdout, \ ; АРІ-функція виведення на екран ADDR NFellowDig, sizeof NFellowDig, ADDR cWritten, NULL

jmp exit ; безумовний перехід на мітку exit next:

invoke WriteConsoleA, stdout, ADDR FellowDig,\ sizeof FellowDig, ADDR cWritten, NULL

exit: invoke ExitProcess, 0 ; повернення керування ОС Windows

; та визволення ресурсів end start ; директива закінчення програми з ім’ям start Програма обчислює парність числа, яке записане в регістр ah.

Команда test ah, 00000001b виконує логічну операцію “І”, але не змінює вмісту регістра ah, а лише встановлює прапорці виконання операції.

Всі символи, що відображаються на екрані терміналу або

виводяться на друк, мають закріплені за ними коди, які називаються кодами ASCII. Кожен код ASCII займає один байт і може приймати

Page 215: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

214

значення від 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 щонайменше незручно. В той же час для виведення на екран псевдографічних зображень або інших піктограм, для яких немає відповідних клавіш, доводиться користуватися кодами ASCII. Проте мати на увазі відповідність символів і кодів ASCII доводиться досить часто. Наприклад, впорядковування символів або символьних рядків за абеткою фактично виконується за кодами ASCII.

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

Page 216: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

215

заповнений кодами алфавітно-цифрових і псевдографічних символів. Ці символи мають коди від 32 (пропуск) до 254 (суцільний квадратик). Такий масив можна створити вручну в полях даних програми за допомогою оператора db:

symbols db 32,33,34,35,36,37,38,39... проте простіше заповнити його даними програмним чином.

Листинг 8.4. Виведення символьного масиву, заповненого кодами

алфавітно-цифрових і псевдографічних символів: title CopyRight by Rysovaniy A. N. .386 ; директива визначення команд мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті

; та угоди ОС Windows option casemap:none ; відмінність малих та великих літер includelib \masm32\lib\kernel32.lib include \masm32\include\kernel32.inc include \masm32\include\windows.inc

.data ; директива визначення даних output db 223 dup(‘*’) ; заповнюваний масив

.code ; початок сегмента-даних _st: ; мітка початку програми

mov ecx,223 ; кількість кроків у циклі mov esi,0 ; індекс елемента, що адресується mov al,32 ; код першого символу – пропуску

a1: mov output[esi],al ; занесення чергового коду в масив inc al ; створення коду наступного символу inc esi ; зрушення в масиві

loop a1 ; есх – 1 та перехід на а1, якщо есх ≠ 0 invoke GetStdHandle, STD_OUTPUT_HANDLE ; одержання дескриптора

invoke WriteConsoleA, \ ; АРІ-функція виведення на екран eax, \ ; дескриптор стандартного пристрою виведення

offset output, \ ; адреса початку повідомлення 223d, \ ; розмір повідомлення

NULL, \ ; адреса, де зберігається число символів NULL

invoke ExitProcess,0 ; виклик процедури повернення керування ; ОС Windows та визволення ресурсів

end _st ; директива закінчення програми з ім’ям _st

Page 217: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

216

Результат роботи програми з листингу 8.4 наведено на рис. 8.4.

У полях даних програми оголошений масив байтів (оператор db), який ініціалізовано кодами символу “*”. Це дуже зручний і поширений прийом, який полегшує налагодження програми. Якщо через якісь помилки в програмі масив буде заповнений не весь або не заповнений взагалі, на екран будуть виведені зірочки. Якщо ж програма працює правильно, початкові зірочки зітруться.

У цій програмі виконується пряме звернення до комірок сегмента даних (речення 8, де заповнюється масив з ім’ям symbols).

Лічильником кроків циклу служить регістр ЕСХ. Тому в регістр

ЕСХ треба занести необхідне число кроків циклу, що дорівнює довжині заповнюваного масиву. Робота з масивом здійснюється, як правило, за допомогою одного з індексних регістрів (ЕSI або ЕDI), в яких зберігається і нарощується індекс елемента масиву, що адресується, тобто номер байта масиву, до якого здійснюється звернення в даному кроці циклу. Оскільки починаємо обробляти масив із самого початку, то в регістр ЕSI заноситься 0. Регістр AL вибраний для зберігання поточного коду символу, що відправляється в масив. З таким же успіхом цю роль міг би виконати будь-який інший байтовий регістр АН, BL, BH, DL або DH (регістри CL і СН, що входять до складу регістра СХ, вже зайняті). В регістр AL заноситься код першого символу – пропуску. Підготувавши всі необхідні регістри, можна скласти саме тіло циклу. Для цього, код з AL відправляється в елемент (байт) масиву output, номер якого визначається вмістом індексного регістра ЕSI. Це так звана індексна адресація, у якої існує декілька різновидів. Зокрема, як індексний регістр з тим же успіхом можна було використовувати регістри ЕВХ або ЕDI. У першому кроці циклу заповниться елемент масиву з індексом 0. У наступних двох реченнях виконується інкремент (збільшення на 1) коду чергового символу і індексу в масиві. Нарешті, команда loop (петля) повертає керування на мітку а1. Причому робить це рівно 223 рази, відповідно до початкового вмісту регістра ЕСХ.

На рис. 8.5. наведено вікна налагоджувача після виведення результату виконанням програми з листингу 8.4.

Рис. 8.4. Результат роботи програми з листингу 8.4

Page 218: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

217

В дампі пам’яті наведені коди символів, які виводяться.

8.7. Виведення чисел Для виведення чисел спочатку потрібно перетворити числа в

послідовність символів, а потім виводити цю послідовність на екран процедурою WriteConsoleA.

Рис. 8.5. Вікна налагоджувача після виведення результату виконанням програми з листингу 8.4

Page 219: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

218

Для такого перетворення в системі Windows є спеціальна процедура wsprintf.

Функція wsprintf Функція (процедура) wsprintf необхідна для перетворення 32-

розрядного числа в послідовність символів. Функція має такі параметри: адреса буфера, де процедура зберігає число у вигляді

послідовності символів; адреса форматного рядка, що вказує процедурі, яке слід

виконати перетворення; перетворюване число. Прототип функції wsprintf зберігається у файлах user32.inc та

user32.lib. На відміну від багатьох інших процедур, число параметрів wsprintf

змінюється і залежить від кількості перетворюваних чисел. Програма, що виводить на екран ціле число 123456, показана в листингу 8.5.

Листинг 8.5. Виведення чисел на екран монітора: .386 ; директива визначення типу мікропроцесора

.model flat, stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap:none ; відмінність малих та великих літер include \masm32v9_0\include\windows.inc include \masm32v9_0\include\user32.inc include \masm32v9_0\include\kernel32.inc includelib \masm32v9_0\lib\user32.lib includelib \masm32v9_0\lib\kernel32.lib BSIZE equ 15 ; завдання реальної кількості байтів

.data ; директива визначення даних Ifmt db "%d",0 ; завдання перетворення одного символу buf db BSIZE dup(?) ; резервування пам’яті для буфера dig dd 123456 ; число, яке необхідно вивести на консоль

stdout DWORD ? ; резервування в пам’яті 32-розрядної комірки ; з ім’ям stdout для збереження дескриптора виведення

cWritten DWORD ? ; резервування 32-розрядної комірки пам’яті ; з ім’ям cWritten для адреси символів виведення

.code ; директива початку коду програми start: ; мітка початку програми з ім’ям start

Page 220: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

219

invoke GetStdHandle, STD_OUTPUT_HANDLE mov stdout, eax ; збереження одержаного дескриптора у пам’яті

invoke wsprintf, \ ; АРІ-функція перетворення числа ADDR buf, \ ; адреса буф., куди буде записана послід. символів

ADDR ifmt, \ ; адреса рядка перетворення формату dig ; число, яке перетворюється

invoke WriteConsoleA, \ ; АРІ-функція виведення на екран stdout, \ ; дескриптор стандартного пристрою виведення

ADDR buf, \ ; адреса початку повідомлення BSIZE, \ ; розмір повідомлення

ADDR cWritten, \ ; адреса, де зберігається число символів NULL

invoke ExitProcess, 0 ; повернення керування ОС Windows ; та визволення ресурсів

end start ; директива закінчення програми з ім’ям start У цій програмі використовуються файли user32.inc і user32.lib,

що зберігають інформацію про функцію wsprintf. Число її параметрів у нас поки дорівнює трьом. Перший параметр ADDR buf – адреса буфера, куди буде записана послідовність символів. Пам’ять для буфера виділяється рядком buf db BSIZE dup(?), який резервує кількість байтів, заданих змінною BSIZE. Про резервування байтів пам’яті говорить слово dup – скорочене від англійського слова duplication (повторення). Знак питання в дужках після dup свідчить про те, що значення байтів наперед не визначене.

Розмір буфера позначений ім’ям BSIZE, є реальним числом (яким асемблер замінить BSIZE) що задається рядком BSIZE equ 15.

Другий параметр функції wsprlntf – ADDR ifmt – це адреса рядка формату, яка задає тип перетворення. Цей рядок складається з символів і завжди завершується нульовим байтом. Рядок “%d”,0 задає перетворення одного цілого числа в послідовність символів, а рядок “%d%d”,0 – перетворення двох чисел.

Після виклику функції wsprintf асемблер додає інструкцію add esp, 12. Це свідчить про те, що програма завантажує в стек три параметри процедури wsprintf, які здійснює інструкція add esp, 12.

Програму, яка показує виведення чисел на екран від 1 до 10,

наведено в листингу 8.6. Листинг 8.6. Виведення на екран чисел від 1 до 10:

Page 221: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

220

.386 ; директива визначення команд мікропроцесора .model flat, stdcall ; завдання лінійної моделі пам’яті

; та угоди ОС Windows option casemap:none ; відмінність малих та великих літер include \masm32v9_0\include\windows.inc include \masm32v9_0\include\user32.inc include \masm32v9_0\include\kernel32.inc includelib \masm32v9_0\lib\user32.lib includelib \masm32v9_0\lib\kernel32.lib BSIZE equ 15

.data ; директива визначення даних frmt db "%d",0 ; завдання перетворення одного символу buf db BSIZE dup(?) ; резервування пам’яті для буфера crlf db 0dh,0ah

stdout DWORD ? ; резервування в пам’яті 32-розрядної комірки ; з ім’ям stdout для збереження дескриптора виведення

cWritten DWORD ? ; резервування 32-розрядної комірки пам’яті ; з ім’ям cWritten для адреси символів виведення

.code ; директива початку коду програми start: ; мітка початку програми з ім’ям start

invoke GetStdHandle, STD_OUTPUT_HANDLE mov stdout, eax ; запам’ятання отриманого дескриптора mov edx,1 ; занесення первинного значення mov ecx,10 ; занесення максимального значення

nxt: ; початок циклу push ecx push edx

invoke wsprintf, \ ; АРІ-функція перетворення числа ADDR buf, \ ; адреса буф., куди буде записана послід. символів

ADDR frmt, \ ; адреса рядка перетворення формату edx ; регістр, вміст якого перетворюється

invoke WriteConsoleA, \ ; АРІ-функція виведення на екран stdout, \ ; дескриптор стандартного пристрою виведення

ADDR buf, \ ; адреса початку повідомлення BSIZE, \ ; розмір повідомлення

ADDR cWritten, \ ; адреса, де зберігається число символів NULL

invoke WriteConsoleA, stdout, \ ; АРІ-функція виведення на екран ADDR crlf, 2, ADDR cWritten, NULL

Page 222: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

221

pop edx inc edx pop ecx

loop nxt ; ecx – 1 та перевірка есх. Якщо ecx = 0, то – вихід invoke ExitProcess, 0 ; повернення керування ОС Windows

; та визволення ресурсів end start ; директива закінчення програми з ім’ям start У цій програмі функція wsprintf перетворює число, яке знаходиться

у регістрі edx, в послідовність символів. Процедура WriteConsoleA виводить ці символи на екран. За

першим параметром цієї функції (stdout) перетворене у символ число виводиться через консоль, за другим (параметр ADDR buf) – вказується адреса початку повідомлення, за третім (BSIZE) – вказується розмір повідомлення, за четвертим (ADDR cWritten) – вказується адреса ділянки пам’яті, де процедура WriteConsoleA зберігає число виведених на екран символів

Другий виклик процедури WriteConsoleA потрібен для переведення рядка і повернення до лівого краю екрана (цим відають символи 0dh, 0ah або в десятковому уявленні – символи 13, 10). Цією процедурою параметр ADDR crlf вказує на те, що виконуватиметься звернення до змінної crlf, яка має опис db 0dh, 0ah. Третій параметр (2) вказує на те, що в змінній crlf є два символи.

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

перед виконанням програми листингу 8.6. Відображення на екрані процесу виконання програми наведено на

рис. 8.7. Перед початком циклу в регістр есх посилається число 10, а в

регістрі edx опиняється одиниця. Далі обидва регістри зберігаються в стеку. Робиться це через те, що процедури Windows самі використовують ці регістри для своїх внутрішніх потреб.

Після збереження регістрів на екран виводиться поточне число. Розглянемо АРІ-функцію MessageBox, що створює вікно консолі,

в яке можна занести результат виконання програми. Приклад використання цієї функції наведено у програмі з листингу 8.7.

Page 223: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

222

Рис .8.6. Команди асемблеру та вікна налагоджувача перед виконанням програми листингу 8.6

Page 224: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

223

Листинг 8.7. Програма з використанням АРІ-функції MessageBox: title CopyRight by Rysovaniy A. N. .386 ; директива визначення типу мікропроцесора .model flat, stdcall ; завдання лінійної моделі пам’яті

; та угоди ОС Windows include \masm32v9_0\include\windows.inc include \masm32v9_0\include\kernel32.inc includelib \masm32v9_0\lib\kernel32.lib include \masm32v9_0\include\user32.inc includelib \masm32v9_0\lib\user32.lib ExitProcess proto: dword ; прототип API-функції

.data ; директива визначення даних st1 db " amount ",0 ; назва вікна консолі st2 db 10 dup(?),0 ; місце у вікні для виведення повідомлення

Рис . 8.7. Відображення на екрані процесу виконання програми листингу 8.6

Page 225: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

224

ifmt db "%d",0 ; завдання перетворення одного символу .code ; директива початку сегмента-даних start: ; мітка початку програми з ім’ям start

mov edx,777 invoke wsprintf, \ ; АРІ-функція перетворення числа

ADDR st2, \ ; адреса буф., куди буде записана послід. символів ADDR ifmt, \ ; адреса рядка перетворення формату

edx ; регістр, вміст якого перетворюється invoke MessageBox, \ ; АРІ-функція виведення вікна консолі

NULL, \ ; hwnd – ідентифікатор вікна addr st2, \ ; адреса рядка, яка містить текст повідомлення

addr st1, \ ; адреса рядка, яка містить заголовок повідомлення MB_OK ; вид діалогового вікна

invoke ExitProcess, 0 ; повернення керування ОС Windows ; та визволення ресурсів

end start ; директива закінчення програми з іменем start У програмі заноситься число 777 до регістра edx, яке потім

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

Виведенням цього вікна відповідає АРІ-функція MessageBox, яка

має прототип int MessageBox( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType ) Параметри:

Рис. 8.8. Результат виконання програми

з листингу 8.7

Page 226: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

225

hwnd – ідентифікатор вікна, з якого викликається Messagebox; lptext – адреса рядка, яка містить текст повідомлення; lpcaption – адреса рядка, яка містить заголовок повідомлення; utype – вид діалогового вікна. Суфікс A у Messagebox означає, що функція працює з

однобайтовими рядками ANSI. Для двобайтових Unicode рядків додається суфікс W: Messageboxw.

Константи NULL та MB_OK, які використані у функції Messagebox, покращують читабельність коду, завдяки чому до них можна звертатися безпосередньо.

Оператор addr використовується для передачі адреси мітки функції. Він дійсний тільки в контексті директиви invoke.

8.8. Введення з консолі

Консоль Win32 має вхідний буфер, що містить масив вхідних

записів. Кожна подія, така як натиснення клавіші, переміщення миші або клацання кнопкою миші, створює запис у вхідному буфері консолі. Функції високого рівня ReadConsole фільтрують і обробляють вхідні дані, повертаючи тільки потік вхідних символів.

Функція ReadConsole Функція ReadConsole використовується для зчитування

текстових даних і приміщення їх в буфер. Прототип цієї функції ReadConsole PROTO

handle:DWORD, ; Дескриптор входу pBuffer:PTR BYTE ; Вказівник буфера maxBytes:DWORD, ; Кількість символів для читання pBytesRead:PTR :DWORD ; Вказівник символів notUsed::DWORD ; He використовується Параметр handle – це дескриптор, який повертається функцією

GetStdHandle. Параметр pBuffer представляє адресу символьного масиву. Параметр maxBytes є 32-розрядним цілим числом і указує на максимальну кількість символів, які повинні бути зчитані. Параметр pBytesRead указує на подвійне слово, яке означає число зчитаних символів. Останній параметр не використовується і його можна замінювати будь-яким числом, наприклад нулем.

Page 227: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

226

Процедура ReadConsole схожа з процедурою WriteConsoleA. Програма, показана в листингу 8.8, вводить з клавіатури послідовність символів і потім відображає її на екрані.

Листинг 8.8. Введення з клавіатури і відображення на екрані

символів: .386 ; директива визначення типу мікропроцесора .model flat, stdcall ; завдання лінійної моделі пам’яті

; та угоди ОС Windows option casemap:none ; відмінність малих та великих літер include \masm32v9_0\include\windows.inc include \masm32v9_0\include\kernel32.inc includelib \masm32v9_0\lib\user32.lib includelib \masm32v9_0\lib\kernel32.lib BSIZE equ 128

.data ; директива визначення даних buf BYTE BSIZE dup(?) ; резервування пам’яті для буфера stdout DWORD ? ; комірка для збереження дескриптора виведення stdin DWORD ? ; комірка для збереження дескриптора введення

cRead DWORD ? cWritten DWORD ?

.code ; директива початку коду програми start: ; мітка початку програми з ім’ям start

; отримання дескриптора виведення invoke GetStdHandle, STD_OUTPUT_HANDLE mov stdout, eax ; збереження дескриптора виведення у пам’яті

; отримання дескриптора введення invoke GetStdHandle, STD_INPUT_HANDLE ; mov stdin, eax ; збереження дескриптора введення у пам’яті

NewLine: invoke ReadConsole, stdin, ADDR buf, BSIZE,\

ADDR cRead, NULL ; читання символу з клавіатури invoke WriteConsoleA, stdout, ADDR buf, cRead,\

ADDR cWritten, NULL ; відображення символу на екрані cmp cRead,2 jnz NewLine invoke ExitProcess, 0 ; повернення керування ОС Windows

; та визволення ресурсів end start ; закінчення програми

Page 228: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

227

У програмі з листингу 8.8 використовуються дескриптори двох стандартних пристроїв – екрана (stdout) і клавіатури (stdin). Процедура ReadConsole приймає ті ж параметри, що і WriteConsoleA: дескриптор пристрою (stdin), адреса масиву байтів, куди потраплять введені символи (ADDR buf), розмір масиву (BSIZE), адреса подвійного слова, куди процедура запише число прочитаних символів (ADDR cRead), та нічого не значуще значення NULL (просто нуль).

Введення символів завершується клавішею Enter. При натисканні клавіші Enter вводиться два символи: 0Dh та 0Ah. Перший символ повертає курсор до лівого краю екрана, а другий переводить курсор на новий рядок. Змінна cRead := 2 свідчить про закінчення введення.

Після натиснення клавіші Enter функція ReadConsole закінчує роботу і за справу береться процедура WriteConsoleA, що повторює введені символи на екрані.

На рис. 8.9. наведено команди асемблеру та вікна налагоджувача перед виконанням програми листингу 8.8.

Рис. 8.9. Вікна налаголжувача перед виконанням програми з листингу 8.8

Page 229: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

228

Відображення на екрані процесу виконання програми наведено на рис. 8.10.

8.9. Лабораторна робота “Масиви”

Мета заняття: – поглибити і закріпити знання з архітектури МП платформи х86 і

навички його програмування; – придбати практичні навички складання, налагодження і

виконання програм з використанням масивів, написаних мовою асемблеру для програмування розгалужених процесів в МП платформи х86 з консольним введенням-виведенням даних.

Постановка задачі Згідно з останньою цифрою номера в групі вибрати варіант та

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

1. Задано масив А з N = 4 елементів. Навести алгоритм та програму визначення суми елементів масиву А, для яких біти 0 та 5 збігаються.

2. Задано масив А з N = 5 елементів. Навести алгоритм та програму визначення суми елементів масиву А, для яких біти 2 та 7 збігаються.

3. Задано масиви А і В з N = 6 елементів. Навести алгоритм та програму формування масиву С за правилом: якщо у елементів Аі та Ві біти 0 та 9 збігаються, то Сі = Аi + Вi.

Рис .8.10. Відображення на екрані процесу виконання програми листингу 8.8

Page 230: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

229

4. Задано масив А з N = 7 елементів. Навести алгоритм та програму формування масиву В з елементів масиву А, у яких 0, 2 та 5 біти мають нулі.

5. Задано масиви А і В з N = 8 елементів. Навести алгоритм та програму формування масиву С за правилом: якщо у елементів Аі та Ві біти 0, 1 та 2 збігаються, то Сі = Аi + Вi.

6. Задано масиви А і В з N = 4 елементів. Навести алгоритм та програму формування масиву С за правилом: якщо Аi + Вi ≤ 0, то Сj = Ві.

7. Задано масив А з N = 5 елементів. Навести алгоритм та програму визначення кількості елементів масиву А, які задовольняють умову L ≤ Ai < M, де L = –3 та M = 15.

8. Задано масив А з N = 6 елементів. Навести алгоритм та програму визначення кількості елементів масиву А, які задовольняють умову L < Ai < M, де L = 4 та M = 18.

9. Задано масив А з N = 7 елементів. Навести алгоритм та програму визначення кількості елементів масиву А, які задовольняють умову L ≤ Ai ≤ M, де L = –5 та M = 19.

0. Задано масив А з N = 8 елементів. Навести алгоритм та програму визначення кількості елементів масиву А, які задовольняють умову L ≥ Ai > M, де L = 6 та M = 20.

Зміст звіту 1. Постановка задачі для конкретного варіанта. 2. Блок-схема алгоритму виконання прикладу з детальним

коментарем та описом роботи. 3. Листинг програми та коментарі до всіх команд. 4. Рrint screen екрана 32-розрядного налагоджувача з виконанням

програми та результатами виконання. 5. Висновки за результатами роботи. Приклад 8.1. Для функції Y = 40Х + 15 одержати перше значення,

що перевищує 512, починаючи з Х = 2. Значення аргументу та функції записати в комірки пам’яті.

Листинг 8.9. Програма виконання прикладу 8.1: title CopyRight by Rysovaniy A. N. and Gorbatenko E.V. KIT-26б

.386 ; директива визначення типу мікропроцесора .model flat, stdcall ; завдання лінійної моделі пам’яті

Page 231: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

230

; та угоди ОС Windows option casemap:none ; відмінність малих та великих літер

includelib \masm32v9_0\lib\kernel32.lib include \masm32v9_0\include\kernel32.inc include \masm32v9_0\include\windows.inc

.data ; директива визначення даних x dd 40 ; збереження у 32-розрядній комірці пам’яті з ім’ям х числа 40

y dd ? ; резервування 32-розрядної комірці пам’яті для змінної y output db "x= y= "

.code ; директива початку коду програми print_int proc pop ecx mov ax, dx mov bx, 000Ah

lp: xor dx, dx ; заповнювання нулями (додавання за модулем два)

div bx add dl,’0’ push dx or ax, ax jnz lp push ecx ret print_int endp

start: xor eax,eax ; заповнювання нулями xor ebx,ebx ; заповнювання нулями xor edx,edx ; заповнювання нулями xor ecx,ecx ; заповнювання нулями mov eax,2 ; завантаження початкового значення аргументу mov ebx,eax ; збереження аргументу a1: mul x add eax,15 ; отримання результату функції cmp eax,512 ; порівняння з умовою ja a2 ; перейти, якщо вище inc ebx mov eax,ebx loop a1 ; цикл виконання умови a2: mov x,ebx mov y,eax ; кінцевий результат обчислення функції

Page 232: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

231

mov edx,x ; кінцевий аргумент call print_int

pop ax mov [output+2],al pop ax mov [output+3],al mov edx,y

call print_int pop ax mov [output+7],al pop ax mov [output+8],al pop ax mov [output+9],al invoke GetStdHandle, STD_OUTPUT_HANDLE

invoke WriteConsoleA, \ ; АРІ-функція виведення на екран

eax, \ ; дескриптор стандартного пристрою виведення offset output, \ ; адреса початку повідомлення

10d, \ ; розмір повідомлення NULL, \ ; адреса, де зберігається число символів

NULL invoke Sleep, 2000d ; АРІ-функція затримки invoke ExitProcess, 0 ; повернення керування ОС Windows

; та визволення ресурсів end start ; закінчення програми Результат виконання програми наведено у вікні налагоджувача

OllyDbg на рис. 8.11.

У програмі використовується АРІ-функція Sleep затримки

відображення інформації.

Рис. 8.11. Результат виконання програми з листингу 8.9

Page 233: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

232

9. РЯДКИ

9.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.

Під час виконання повторюваної елементарної команди індексні регістри SІ, DІ і лічильник повторень (СХ) змінюються після кожного повторення, а лічильник команд буде, як і раніше, містити зміщення байта префікса (у припущенні, що він безпосередньо передує команді над рядками). Перервана команда над рядками буде вірно продовжена

Page 234: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

233

після повернення керування з перериваючої програми, якщо перед елементарною командою розміщений тільки один префікс. Тому варто уникати використання двох інших префіксів разом з префіксом-повторювачем у командах роботи з рядками, тобто префікса сегмента і префікса LOCK. Це пов’язано з тим, що після виходу з перериваючої програми, виконання відновиться з адреси, на один байт меншої від адреси команди (тобто адреси, у якій приблизно розміщений префікс-повторювач, а додаткові префікси будуть ігноруватись).

Префікс REP використовується з командами MOVS і STOS і ініціює дію “повторювати, поки не буде досягнутий кінець ланцюжка”, тобто доти, поки вміст регістра СХ не досягне нуля. Префікси REPE і REPZ діють аналогічно і є таким же байтом, як і префікс REP. Вони використовуються з командами CMPS і SCAS і оперують з прапорцем ZF = 1, стан якого визначається результатом виконання цих команд. Префікси REPNE і REPNZ діють аналогічно попереднім префіксам, але прапорець ZF повинен дорівнювати нулю. Інакше повторення закінчується.

Існує п’ять елементарних команд роботи з рядкам, які наведено у табл. 9.1 (http://www.intel.com/techtrends/technologies/hyperthreading.htm, документ 25366717.pdf).

Таблиця 9.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 235: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

234

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

Кожна з рядкових команд може додатково використовувати такі літери: B – робота з байтом; W – з словом; D – з подвійним словом (для МП Intel386+).

Команда MOVS пересилає байт (слово) з поля, що вказується Рг

ESІ, в поле, що задається Рг EDІ (MOVS [EDI],[ESI]). При використанні команди з префіксом RET команда MOVS здійснює блокову передачу ланцюжка (поки СХ ≠ 0), елементами якого є байти.

При використанні з префіксом REP команда MOVS виконує блокову передачу пам’ять – пам’ять.

Прапорець напряму. Рядкові команди використовують прапорець

напряму DF регістра Flags, щоб визначити, який з регістрів (ESI або EDI) буде інкрементуватись або декрементуватись при виконанні команди.

Значення прапорця Дія на ESI або EDI Напрям 0 Інкрементується від низу до верху 1 Декрементується зверху вниз

Прапорець напряму змінюється командами CLD і STD: CLD ; скинути прапорець напряму, напрям – вгору STD ; встановити прапорець напряму, напрям – вниз Наступна програма переміщує 10 байт із області пам’яті mas1 в

область пам’яті mas2: CLD ; напрям – вгору MOV ESI, offset mas1 ; занесення адреси передавача MOV EDI, offset mas2 ; занесення адреси приймача MOV CX, 10 ; встановлює лічильник в 10

REP MOVSB ; переміщення 10 байт …

mas1 DB ‘ABCDEFGHIJ’ ; резервування в пам’яті комірок ; розміром у байт для кожної літери масиву mas1

mas2 DB 10 dup(?) ; резервування в пам’яті десяти комірок ; розміром у байт кожну для збереження невизначених

; елементів масиву mas2

Page 236: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

235

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

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

mas2 без використання команд обробки рядків. Листинг 9.1. Програма виконання прикладу 9.1: ; командний файл для компіляції та компонування ; ml /c /coff "8_1L.asm" ; link /SUBSYSTEM:CONSOLE "8_1L.obj". title CopyRight by Rysovaniy A. N.

.386 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap:none ; відмінність малих та великих літер includelib\masm32v9_0\lib\kernel32.lib ExitProcess proto :DWORD ; прототип API-функції

.data ; директива визначення даних mas1 dw -1h,5h,10h,15h,20h ; визначення масиву з ім’ям mas1 mas2 dw 5 dup(1) ; масив mas2, всі елементи якого дорівнюють 1

.code ; директива початку сегмента даних _st: ; мітка початку програми з ім’ям _st

mov ecx,5 ; кількість слів у масиві lea esi, mas1 ; завантаження адреси масиву mas2 lea edi, mas2 ; завантаження адреси масиву mas2

m1: mov bx,[esi] ; завантаження числа з масиву mas1 mov [edi],bx ; завантаження з bx в пам'ять,

; адреса комірки якої знаходиться в Рг edi add esi,2 ; вирівнювання вмісту Рг esi на границю слова add edi,2 ; вирівнювання вмісту Рг edi на границю слова

loop m1 ; перейти на m1, якщо есх не нуль invoke ExitProcess,0 ; виклик процедури повернення керування

; ОС Windows та визволення ресурсів end _st ; директива закінчення програми з ім’ям _st Початкові значення дампа пам’яті даних для наочності наведено на

рис. 9.1. Вікна налагоджувача OllyDbg при налагодженні програми

прикладу 9.1 без використання рядкових команд наведено на рис. 9.2.

Page 237: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

236

В директиві завдання моделі пам’яті .model при використання

АРІ-функцій використання угоди stdcall є обов’язковим. В цьому прикладі такою функцією є функція ExitProcess.

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

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

mas2 з використанням команд обробки рядків. Листинг 9.2. Програма виконання прикладу 9.1 з використанням

команд обробки рядків: ; командний файл для компіляції та компонування ; ml /c /coff "8_2L.asm" ; link /SUBSYSTEM:CONSOLE "8_2L.obj". title CopyRight by Rysovaniy A. N.

.386 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap:none ; відмінність малих та великих літер

Рис. 9.2. Вікна налагоджувача OllyDbg при налагодженні програми прикладу 9.1 без використання рядкових команд

Рис. 9.1. Початкові значення дампа пам’яті даних прикладу 9.1

Page 238: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

237

includelib\masm32v9_0\lib\kernel32.lib ExitProcess proto :DWORD ; прототип API-функції

.data ; директива визначення даних mas1 dw -1h,5h,10h,15h,20h ; визначення масиву з ім’ям mas1 mas2 dw 5 dup(1) ; масив mas2, всі елементи якого дорівнюють 1

.code ; директива початку сегмента даних _st: ; мітка початку програми з ім’ям _st

mov ecx,5 ; кількість слів у масиві lea esi, mas1 ; завантаження адреси масиву mas1 lea edi, mas2 ; завантаження адреси масиву mas2 cld ; напрям – вгору

rep movsw invoke ExitProcess,0 ; виклик процедури повернення керування

; ОС Windows та визволення ресурсів end _st ; директива закінчення програми з ім’ям _st Вікна налагоджувача OllyDbg при налагодженні програми

прикладу 9.1 з використанням команд обробки рядків наведено на рис. 9.3.

Масив даних mas2 розташовується, починаючи з адреси

0040300Аh, та повністю повторює елементи масиву mas1.

Рис. 9.3. Вікна налагоджувача OllyDbg при налагодженні програми прикладу 9.1 з використанням команд обробки рядків

Page 239: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

238

Команда CMPS здійснює порівняння (віднімання) байта (слова), який адресується другим операндом (з [DI]), з байтом (словом), який адресується першим операндом (з [ЕSI]) (CMPS [ЕSI], [ЕDI]). Команда впливає на біти умов, але не формує результат. Вона призначена для порівняння рядків. При відповідному префіксі-повторювачі можливо визначити, після якого елемента два рядки починають відрізнятись один від одного і, таким чином, установити порядок, в якому вони повинні розміщуватись.

Коли перед командою CMPS знаходиться префікс REPE (або REPZ), операція інтерпретується як “порівнювати, поки не буде досягнутий кінець ланцюжків або поки елементи ланцюжків не будуть рівні”. За наявності префікса REPNE (або REPNZ) операція набуває сенсу “порівнювати не до кінця, а до першого виконання умови слідкуючої команди (або поки елементи ланцюжків будуть рівні)”. Таким чином, команду CMPS зручно застосовувати для знаходження однакових або таких, що розрізняються, елементів ланцюжків.

Прапорець напряму визначає інкремент або декремент регістрів ЕSI і ЕDI. Таким чином можуть бути використані такі префікси повторення:

REP ; Повторювати, поки ЕСХ > 0 REPE, REPZ ; Повторювати, поки відправник = одержувачу REPNE, REPNZ ; Повторювати, поки відправник >< одержувача

Якщо рядок операнда-відправника менший, ніж рядок операнда-

одержувача, то CF = 1. Якщо рядки рівні, то ZF = 1. Якщо рядок операнда-відправника більший, ніж рядок операнда-

одержувача, то ZF = 0 та CF = 0. Умовні переходи, використовувані з командою CMPS, наведено в табл. 9.2.

Таблиця 9.2

Умова Без знака Із знаком Одержувач < відправник JB JL Одержувач <= відправник JBE JLE Одержувач < > відправник JNE (JNZ) JNE (JNZ) Одержувач = відправник JE (JZ) JE (JZ) Одержувач >= відправник JAE JGE Одержувач > відправник JA JG

Page 240: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

239

Приклад 9.3. Порівняти літери двох змінних. У випадку, якщо кількість літер у першій змінній менша, ніж кількість літер другої змінної, то записати у комірку пам’яті res ← 1. В протилежному випадку – у res завантажити 0.

Листинг 9.3. Програма виконання прикладу 9.3: title CopyRight by Rysovaniy A. N.

.386 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap:none ; відмінність малих та великих літер includelib\masm32v9_0\lib\kernel32.lib ExitProcess proto :DWORD ; прототип API-функції

.data ; директива визначення даних mas1 db 'MARTIN' ; збереження в пам’яті з ім’ям mas1 слова

; MARTIN, кожна літера якого займає один байт mas2 db 'MARTINEZ' ; визначення масиву з ім’ям mas2

res db (17) .code ; директива початку сегмента даних _st: ; мітка початку програми з ім’ям _st

mov ecx,8 ; кількість слів у масиві lea esi, mas1 ; завантаження адреси масиву mas2 lea edi, mas2 ; завантаження адреси масиву mas2 cld ; напрям – вгору

repne cmpsb jb min ; перехід, якщо mas1 < mas2 mov res, 0 jmp m1 ; безумовний перехід на m1

min: mov res, 1 m1: invoke ExitProcess,0 ; виклик процедури повернення керування

; ОС Windows та визволення ресурсів end _st ; директива закінчення програми з ім’ям _st Початкові значення дампа пам’яті даних для наочності наведено на

рис. 9.4. Вікна налагоджувача OllyDbg при налагодженні програми

прикладу 9.3 наведено на рис. 9.5.

Page 241: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

240

Для наочності початкове значення комірки пам’яті при запису

результату res процесу порівняння дорівнює 17 = 11h. Для явного указання типу елементів ланцюжків звичайно

допускаються мнемокоди CMPSB і CMPSW; при цьому операнди в команді відсутні.

Порівняння чисел із знаком. Команда CMPS може порівнювати

два списки цілих чисел із знаком до першого незбіжного числа. Приклад 9.4. Порівняти два списки цілих чисел із знаком до

першого незбіжного числа. Якщо перший масив чисел менший, ніж другий, то записати в комірку пам’яті результату одиницю, а в противному випадку – 0.

Листинг 9.4. Програма виконання прикладу 9.4: title CopyRight by Rysovaniy A. N. .386 ; директива визначення типу мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті

Рис. 9.4. Початкові значення дампа пам’яті даних прикладу 9.3

Рис. 9.5. Вікна налагоджувача OllyDbg при налагодженні програми прикладу 9.3

Page 242: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

241

; та угоди ОС Windows option casemap:none ; відмінність малих та великих літер

includelib\masm32v9_0\lib\kernel32.lib ExitProcess proto :DWORD ; прототип API-функції .data ; директива визначення даних

mas1 db 12,2,-3,4 ; визначення масиву з ім’ям mas1 mas2 db 12,2,3,-4 ; визначення масиву з ім’ям mas2

res db (17) ; резервування комірки під результат .code ; директива початку сегмента даних _st: ; мітка початку програми з ім’ям _st

mov ecx,4 ; кількість слів у масиві lea esi, mas1 ; завантаження адреси масиву mas1 lea edi, mas2 ; завантаження адреси масиву mas2 cld ; напрям – вгору

repe cmpsb ; повторювати, поки CF = 0 та СХ > 0 jl min ; перехід, якщо mas1 (і) < mas2 (і) mov res, 0 ; res ← 0, якщо mas1 (і) > mas2 (і) jmp m1 ; безумовний перехід на мітку m1

min: mov res, 1 ; res ← 1, якщо mas1 (і) < mas2 (і) m1: invoke ExitProcess,0 ; виклик процедури повернення керування

; ОС Windows та визволення ресурсів end _st ; директива закінчення програми з ім’ям _st У прикладі кожне число в масиві a1 порівнюється з відповідними

числами з масиву а2. Початкова частина масиву a1 вважається меншою, оскільки його третє число буде -3, а відповідне число з масиву а2 буде дорівнювати 3. Числа в пам’яті комп’ютера зберігаються у додаткових числах. Порівняння четвертих елементів масивів не відбувається.

Вікна налагоджувача OllyDbg при налагодженні програми прикладу 9.4 наведено на рис. 9.6.

Результат порівняння записаний у комірку 0040300Сh. Команда SCAS виконує віднімання з операнда, адреса якого

розташовується в регістрі DI операнда з регістра AL (АХ чи EAX), впливає на біти умов, але не формує результату (SCAS [DI], AL/AX/EAX). У випадку ітеративного використання цю команду можна застосовувати для пошуку входження деякої величини в рядок.

Page 243: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

242

З префіксом REPE (або REPZ) дану команду можна

використовувати для пошуку елемента ланцюжка із значенням, що відрізняється від заданого значення. Якщо перед командою SCAS знаходиться префікс REPNE (або REPNZ), то операція інтерпретується як “переглядати доти, поки не буде досягнутий кінець ланцюжка або значення елемента ланцюжка не буде дорівнювати відшукуваному значенню”.

Час виконання команди SCAS без префікса повторення складає 15 тактів, а з префіксом повторення – 9+15* (число повторень) тактів синхронізації.

Для явного указання типу елементів ланцюжка звичайно

використовуються мнемокоди SCASВ і SCASW; при цьому операнд в команді відсутній.

Сканування для збіжних символів Приклад 9.5. Сканувати рядок символів доти, поки символ F не

буде знайдений. Коли символ F буде виявлений, регістр EDI указуватиме на адресу

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

Рис. 9.6. Вікна налагоджувача OllyDbg при налагодженні програми прикладу 9.4

Page 244: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

243

Листинг 9.5. Програма виконання прикладу 9.5: title CopyRight by Rysovaniy A. N. .386 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap:none ; відмінність малих та великих літер includelib\masm32v9_0\lib\kernel32.lib ExitProcess proto :DWORD ; прототип API-функції .data ; директива визначення даних

mas1 db 'abcdefgh' ; масив байтів із символами коду ASCII .code ; директива початку сегмента даних

_st: ; мітка початку програми з ім’ям _st lea edi, mas1 ; завантаження адреси масиву mas1 mov al, 'f' ; завантаження символу ‘f’ mov ecx, 8 ; встановити в лічильник max значення літерів cld ; напрям – вгору repne scasb ; повторювати поки не буде дорівнювати dec edi ; знайдений: декременувати DI invoke ExitProcess,0 ; виклик процедури повернення керування

; ОС Windows та визволення ресурсів end _st ; директива закінчення програми з ім’ям _st Вікна налагоджувача OllyDbg при налагодженні програми

прикладу 9.5 наведено на рис. 9.7. Відразу після того як команда SCASB буде виконана, ЕDI вкаже на

символ, що іде за шуканим символом. Використання команд умовного переходу. Відразу після

виконання команди CMPSB ще не можна визначити, що саме стало причиною її завершення: те, що СХ = 0, або те, що відповідний символ вже знайдений, причому і те, і інше може відбутися одночасно.

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

Page 245: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

244

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

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

repnz cmpsb jnz not_found

або: repnz cmpsb jz found

Може виникнути помилка при використанні команди JCXZ при ухваленні рішення після того як символ знайдений. Символ може бути знайдений в самій останній позиції, і СХ стане дорівнювати нулю після останнього порівняння. Тому наступні команди будуть помилковими:

repnz scasb jcxz exit

Приклад 9.6. Задано рядки А і В (констант типу BYTE). У всіх

байтах рядка А замінити символи Х на відповідні символи із масиву В. Листинг 9.6. Програма виконання прикладу 9.6: title CopyRight by Rysovaniy A. N. .386 ; директива визначення типу мікропроцесора

Рис. 9.7. Вікна налагоджувача OllyDbg при налагодженні програми прикладу 9.5

Page 246: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

245

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap:none ; відмінність малих та великих літер includelib\masm32v9_0\lib\kernel32.lib ExitProcess proto :DWORD ; прототип API-функції

.data ; директива визначення даних mas1 db 'atxfx' ; масив байт із символами коду ASCII mas2 db 'abcef'

.code ; директива початку сегмента даних _st: ; мітка початку програми з ім’ям _st

cld ; напрям – вгору lea edi,mas1 ; завантаження адреси масиву a в di lea esi,mas2 ; завантаження адреси масиву b в si mov al,'x' ; завантаження символу ‘x’ mov ecx,5 ; кількість слів у масиві

a2: scasb ; [di] – al jnz m1 ; перейти, якщо не нуль dec di ; повернення di mov bl,[esi] mov [edi],bl inc edi ; встановлення di для порівняння

m1: inc esi ; просування si loop a2 ; цикл, поки сх ≠ 0

invoke ExitProcess,0 ; виклик процедури повернення керування ; ОС Windows та визволення ресурсів

end _st ; директива закінчення програми з ім’ям _st Початкові значення дампа пам’яті даних для наочності наведено на

рис. 9.8. Вікна налагоджувача OllyDbg при налагодженні програми

прикладу 9.6 наведено на рис. 9.9.

Рис. 9.8. Початкові значення дампа пам’яті даних для прикладу 9.8

Page 247: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

246

При порівнянні дампа пам’яті до та після виконання порівняння видно, які байти поміняні.

Видалення додаткових пропусків. Команда SCASB може

використовуватися для видалення зайвих пропусків в рядку з кодуванням ASCIIZ. У наступному прикладі регістри ES:DI указують на останній байт рядка, а СХ дорівнює довжині рядка, AL = 20h (символ пропуску) і DF = 1. Для повторення циклу використовується префікс REРЕ, поки значення регістра AL збігається із значенням в пам’яті.

.data dest db "DESTINATION STRING ",0 destlen = $ - dest ; розрахунок довжини в байтах

.code mov di, seg dest mov es, di mov di,offset dest ; встановити зсув рядка add di, destlen ; вказати на останній байт mov ex, destlen ; встановити лічильник mov al, 20h ; порівняння з пропусками std ; напрям – вниз

Рис. 9.9. Вікна налагоджувача OllyDbg при налагодженні програми прикладу 9.6

Page 248: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

247

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 і ЕDI.

Префікси повторення рідко використовуються з командами LODS, тому що кожне нове значення, що завантажується в регістри AL або АХ, руйнує їх колишні значення. Замість окремої команди LODSB можна використовувати такі дві команди:

mov al, [si] ; перемістити байт за адресою DS:SI у AL inc si ; вказати на наступний байт Приклад 9.7. Просканувати буфер buffer та при цьому очистити

старший біт кожного байта і отримане значення зберегти в масиві output.

Листинг 9.7. Програма виконання прикладу 9.7: title CopyRight by Rysovaniy A. N. .386 ; директива визначення типу мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті

Page 249: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

248

; та угоди ОС Windows option casemap:none ; відмінність малих та великих літер includelib\masm32v9_0\lib\kernel32.lib ExitProcess proto :DWORD ; прототип API-функції .data ; директива визначення даних

mas1 db 0C8h, 0FBh, 0F5h, 0CAh, 41h, 42h, 43h, 64h, 87h, 8Ch mas2 db 10 dup(1) ; попереднє заповнення масиву одиницями .code ; директива початку сегмента даних _st: ; мітка початку програми з ім’ям _st

cld ; напрям – вгору lea esi,mas1 ; завантаження адреси масиву a в di lea edi,mas2 ; завантаження адреси масиву b в si mov al,'x' ; завантаження символу ‘x’ mov ecx,10 ; кількість слів у масиві cld ; напрям – вгору

L1: lodsb ; AL < DS: [SI] and al, 7Fh ; логічне перемноження stosb ; AL < [DI] loop L1 ; цикл, поки СХ ≠ 0

invoke ExitProcess,0 ; виклик процедури повернення керування ; ОС Windows та визволення ресурсів

end _st ; директива закінчення програми з ім’ям _st

Вікна налагоджувача OllyDbg при налагодженні програми прикладу 9.7 наведено на рис. 9.10.

Попереднє заповнення масиву output одиницями корисно

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

Команда STOS пересилає байт (чи слово) з регістра АН/AX/EAX за

адресою ES:DI (STOS [DI], AL/AX/EAX). З допомогою префікса-повторювача вона може використовуватись для заповнення рядка визначеною величиною.

З префіксом повторення ця команда є зручним засобом ініціалізації ланцюжка на фіксоване значення, наприклад нуль або пропуск. Час виконання команди STOS без префікса повторення складає 11 тактів, а з префіксом повторення 9+10 * (число повторень) тактів синхронізації.

Page 250: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

249

Регістри ES:DI містять адресу операнда-одержувача. З командою

STOSB використовується 8-розрядний операнд, з командою STOSW – 16-розрядний операнд, з командою STOSD – 32-розрядний.

Прапорець напряму визначає інкрементування або декрементування регістрів ЕSI та ЕDI.

Також можна використовувати STOS для ініціалізації пам’яті єдиним значенням.

Приклад 9.8. Заповнити кожен байт рядка mas1 значенням 0FFh. Листинг 9.8. Програма виконання прикладу 9.8: title CopyRight by Rysovaniy A. N. .386 ; директива визначення типу мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті

; та угоди ОС Windows option casemap:none ; відмінність малих та великих літер includelib\masm32v9_0\lib\kernel32.lib ExitProcess proto :DWORD ; прототип API-функції .data ; директива визначення даних

mas1 db 10 dup(1) ; попереднє заповнення масиву одиницями

Рис. 9.10. Вікна відображення пам’яті налагоджувача OllyDbg при налагодженні програми прикладу 9.7

Page 251: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

250

.code ; директива початку сегмента даних _st: ; мітка початку програми з ім’ям _st

lea edi,mas1 ; завантаження адреси масиву в edi mov al,0FFh mov ecx,10 ; кількість слів у масиві cld ; напрям – вгору rep stosb ; заповнити вмістом AL invoke ExitProcess,0 ; виклик процедури повернення

; керування ОС Windows та визволення ресурсів end _st ; директива закінчення програми з ім’ям _st Початкові значення дампа пам’яті даних для наочності наведено на

рис. 9.11.

Вікна налагоджувача OllyDbg при налагодженні програми

прикладу 9.8 наведено на рис. 9.12.

Рис. 9.11. Початкові значення дампа пам’яті даних прикладу 9.8

Рис. 9.12. Вікна налагоджувача OllyDbg при налагодженні програми прикладу 9.8

Page 252: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

251

Приклад 9.9. Необхідно порівняти два масиви байт, що знаходяться в пам’яті, і при рівності елементів вийти з циклу.

Припустимо, що регістр SI адресує поточний елемент першого

масиву, регістр DI – поточний елемент другого масиву, а вміст регістра СХ є довжиною масивів. Тоді стандартна програма порівняння масивів байт набуває такого вигляду:

A1: MOV AL, [SI] ; елемент першого масиву CMP [DI], AL ; порівняти JZ A2 ; елементи рівні INC SI ; просунути вказівники INC DI DEC СХ ; перевірити закінчення JNZ A1

A2: … При розподілі регістрів завдання порівняння масивів розв’язується

набагато коротшим фрагментом: REPNZ CMPSB

JZ A2 Команда STOS зручна для ініціалізації областей даних на

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

LES DI, ARRAY ; адреса в ES: DI MOV СХ, LENGTH ; довжина в СХ MOV АХ, 0 ; початкове значення

REP STOSW ; ініціалізація

9.2. Лабораторна робота “Рядки”

Мета заняття: – поглибити і закріпити знання з архітектури МП платформи х86 і

навички його програмування; – придбати практичні навички складання, налагодження і

виконання програм з використанням команд обробки рядків, написаних мовою асемблеру для програмування МП платформи х86.

Page 253: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

252

Постановка задачі Згідно з останньою цифрою номера в групі вибрати варіант та

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

Постановка задачі Згідно з номером в групі вибрати варіант та написати програму на

асемблері: 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 слів, розділених пропуском. Визначити кількість слів, в яких буква “А” зустрічається більш 3-х разів.

14. Задано текст із 10 слів, розділених пропусками (одним і більш).

Page 254: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

253

Визначити кількість слів, що містять більше 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 символи.

Зміст звіту 1. Постановка задачі для конкретного варіанта. 2. Блок-схема алгоритму виконання прикладу з детальним

коментарем та описом роботи. 3. Листинг програми з виведенням даних на екран монітора з

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

4. Рrint screen екрана 32-розрядного налагоджувача з виконаною програмою.

5. Висновки за результатами роботи.

Page 255: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

254

10. ЛОГІЧНІ СТРУКТУРИ ВИСОКОГО РІВНЯ

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

MASM забезпечує можливість використання логічних структур високого рівня через засоби макро. Макро є "суперкомандами", які розвантажують MASM від тієї частини команд, що часто повторюється.

10.1. Директива IF

У асемблері Microsoft (MASM) визначено директиву .IF, яка дозволяє записувати логічні вирази так, як це робиться в мовах високого рівня.

Конструкція 1: .IF умова_1 вираз .ENDIF

Конструкція 1 означає, що якщо умова_1 виконується, то вираз обчислюється; якщо умова_1 не виконується, то вираз не обчислюється, про що свідчить директива .ENDIF.

Конструкція 2: .IF умова_1

вираз_1 [.ELSEIF умова_2

вираз_2] ... [.ELSE

вираз_n] .ENDIF

Page 256: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

255

Конструкція 2 означає, що якщо умова_1 виконується, то обчислюється вираз_1, а якщо умова_1 не виконується, то відбувається перевірка наступної умови і так далі. Інакше обчислюється вираз_n.

Під словами "умова_1" і "умова_n" ховаються булеві вирази, які використовують такі оператори, як <, >, == або !=.

Можна використовувати як одинарну умову, так і складену, які можуть мати такий вигляд:

(ЕАХ < 10h) && (ЕАХ > l00h) (ор1 <= 100) || (ор2 <= 100} (ор1 != EDX) && SIGN?

Повний список операторів відносин наведено в табл. 10.1.

Таблица 10.1

Оператор відносин і логічні оператори Оператор Описание

вираз1 == вираз2 Вирази рівні між собою вираз1 != вираз2 Вирази не рівні між собою вираз1 > вираз2 Вираз1 більше виразу2 вираз1 >= вираз2 Вираз1 більше або дорівнює виразу2 вираз1 < вираз2 Вираз1 менше виразу2 вираз1 <= вираз2 Вираз1 менше або дорівнює виразу2 ! вираз Вираз неправдивий Вираз1 && вираз2 Логічне І між виразами Вираз1 || вираз2 Логічне АБО між виразами Вираз1 & вираз2 Порозрядне І між виразами CARRY? Прапорець перенесення встановлений ? OWERFLOW? Прапорець переповнення встановлений ? PARITY? Прапорець парності встановлений ? ZERO? Прапорець нуля встановлений ? SIGN? Прапорець знака встановлений ?

Page 257: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

256

Приклад 10.1. Порівняти число з трьома операндами. Якщо це число більше першого операнда, більше або дорівнює другому та дорівнює третьому, то слід додати всі ці операнди, інакше – на вихід.

У листингу 10.1 наведено таку програму, яка є послідовністю умовних переходів без використання директиви .IF.

Листинг 10.1. Програма розв’язання прикладу 10.1 з послідовністю

умовних переходів без використання директиви .IF: ; командний файл для компіляції та компонування:

; ml /c /coff "001LL.asm" ; link /SUBSYSTEM:CONSOLE "001LL.obj".

title CopyRight by Rysovaniy A. N. .386 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap:none ; відмінність малих та великих літер includelib\masm32v9_0\lib\kernel32.lib ExitProcess proto :DWORD ; прототип API-функції

.data ; директива визначення даних op dd 23 ; 17h – операнд для порівняння op1 dd 22 ; 16h – перший операнд розміром у подвійне слово op2 dd 21 ; 15h – другий операнд розміром у подвійне слово op3 dd 23 ; 17h – третій операнд розміром у подвійне слово

.code ; директива початку сегмента-даних start: ; мітка початку програми з ім’ям start

mov eax, op ; занесення операнда, з яким порівнюються cmp eax,op1 ; порівняння з першим операндом jg L1 ; перехід до L1 якщо AL > op1 (зі знаком) jmp L2 ; безумовний перехід

L1: cmp eax,op2 ; порівняння з другим операндом jge L3 ; перехід до L1 якщо AL >= op2 jmp L2 ; безумовний перехід

L3: cmp eax,op3 ; порівняння з третім операндом je L4 ; перехід до L1 якщо AL = ор3 jmp L2 ; інакше перехід до L2

L4: add eax,op1 ; додавання першого операнда adc eax,op2 ; додавання другого операнда з урахуванням CF adc eax,op3 ; додавання третього операнда з урахуванням CF

L2: invoke ExitProcess, 0 ; повернення керування ОС Windows

Page 258: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

257

; та визволення ресурсів end start ; директива закінчення програми з ім’ям start

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

після виконання програми з листингу 10.1.

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

EAX = 0000 0069h.

Рис. 10.1. Програма з послідовністю умовних переходів без використання директиви .IF

Page 259: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

258

Для налагодження програм у налагоджувачі OllyDbg, які мають функції, що не потребують перевірки функціонування, доцільніше використовувати у покроковому режимі клавішу F8. Такими функціями можуть бути функції API Win32 або функції, раніше використані та перевірені. В такому випадку використання клавіші F8 різко прискорює процес перевірки програми. Модернізовану програму з листингу 10.1 з використанням директиви IF наведено в листингу 10.2.

Листинг 10.2. Програма розв’язання прикладу 10.1 з

використанням директиви IF: ; командний файл для компіляції та компонування:

; ml /c /coff "002LL.asm" ; link /SUBSYSTEM:CONSOLE "002LL.obj".

title CopyRight by Rysovaniy A. N. .386 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap:none ; відмінність малих та великих літер includelib\masm32v9_0\lib\kernel32.lib ExitProcess proto :DWORD ; прототип API-функції

.data ; директива визначення даних

op dd 23 ; операнд для порівняння op1 dd 22 ; перший операнд розміром у подвійне слово op2 dd 21 ; другий операнд розміром у подвійне слово op3 dd 23 ; третій операнд розміром у подвійне слово

.code ; директива початку сегмента-даних start: ; мітка початку програми з ім’ям start

mov eax, op ; занесення операнда, з яким порівнюються .IF (eax > op1) && (eax >= op2) && ( eax == op3)

add eax, op1 ; додавання першого операнда adc eax,op2 ; додавання другого операнда з урахуванням CF

adc eax,op3 ; додавання третього операнда з урахуванням CF .ENDIF

invoke ExitProcess, 0 ; повернення керування ОС Windows

; та визволення ресурсів end start ; директива закінчення програми з ім’ям start

Page 260: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

259

У програмі директивою високого рівня .IF виконуються операції

логічного порівняння. Вікна нагоджувача OllyDbg при налагодженні програми

прикладу 10.1 з використання директиви .IFнаведено на рис. 10.2. Результатом виконання програми з листингу 10.2 є EAX= 0000

0069h, що дорівнює результату виконання програми з листингу 10.1 без використання директиви .IF.

Наступна програма (листинг 10.3) обчислює різницю двох чисел з

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

Листинг 10.3. Програма обчислення різниці двох операндів та

виведення повідомлення на консоль: ; командний файл для компіляції та компонування

Рис. 10.2. Програма з листингу 10.2 з використанням директиви IF

Page 261: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

260

; ml /c /coff "003LL.asm" ; link /SUBSYSTEM:CONSOLE "003LL.obj".

title CopyRight by Rysovaniy A. N. .386 ; директива визначення типу мікропроцесора

.model flat, stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap:none ; відмінність малих та великих літер include \masm32v9_0\include\windows.inc include \masm32v9_0\include\kernel32.inc includelib \masm32v9_0\lib\kernel32.lib

.data ; директива визначення даних op1 dd 25h ; значення 1-го операнда у форматі подвійного слова op2 dd 21h ; значення 2-го операнда у форматі подвійного слова z db "равно нулю", 13, 10 ; ім’я повідомлення z

zsize dd ($-z) ; кількість байтів повідомлення z nz db "не равно нулю", 13, 10 ; ім’я повідомлення nz nzsize dd ($-nz) ; кількість байтів повідомлення nz

stdout DWORD ? ; резервування в пам’яті 32-розрядної комірки ; з ім’ям stdout для збереження дескриптора виведення

cWritten DWORD ? ; резервування 32-розрядної комірки пам’яті ; з ім’ям cWritten для адреси символів виведення

.code ; директива початку сегмента-даних start: ; мітка початку програми з ім’ям start

invoke GetStdHandle, STD_OUTPUT_HANDLE mov stdout, eax ; збереження одержаного дескриптора у пам’яті

mov edx,op1 ; занесення першого операнда sub edx,op2 ; віднімання другого операнда

.IF edx == 0 ; виконувати, якщо edx = 0 invoke WriteConsoleA, \ ; АРІ-функція виведення на екран

stdout, \ ; дескриптор стандартного пристрою виведення ADDR z, \ ; адреса початку повідомлення

zsize, \ ; розмір повідомлення ADDR cWritten, \ ; адреса, де зберігається число символів

NULL .ELSE ; виконувати, якщо edx ≠ 0

invoke WriteConsoleA, stdout, ADDR nz, \ nzsize, ADDR cWritten, NULL

.ENDIF ; закінчення директиви

Page 262: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

261

invoke ExitProcess, 0 ; повернення керування ОС Windows

; та визволення ресурсів end start ; директива закінчення програми з ім’ям start Директива .data? означає, що дані, описані після директиви, по-

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

В наведеній програмі операнд ор1 заноситься у регістр edx, а у наступній команді виконується віднімання з регістра edx другого операнда. Залежно від вмісту цього регістра за допомогою директиви .IF формується одне з двох повідомлень.

Процес отримання повідомлення через файловий менеджер FAR наведено на рис. 10.4. Вигляд налагоджувача до виконання цієї програми наведено на рис. 10.5.

Функція (процедура) WriteConsoleA, що виводить символи на

екран, має п’ять таких параметрів: 1. stdout –дескриптор стандартного пристрою виведення (екрана

монітора), одержаний процедурою GetStdHandle.

Рис. 10.4. Процес отримання повідомлень з листингу 10.3

Page 263: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

262

2. ADDR z – адреса початку повідомлення. Щоб одержати його, використовується спеціальний оператор отримання адреси ADDR.

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

повідомлення, поміщене в лапки, складається з 18 байтів (16 байтів займають букви і два байти – символи 0dh, 0ah, які дають команду процедурі WriteConsoleA перевести рядок). Розмір повідомлення (число байтів від вказаної мітки msg до наступної CWritten) програма-асемблер обчислює під час компіляції.

Рис. 10.5. Вигляд налагоджувача до виконання програми з листингу 10.3

Page 264: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

263

4. ADDR cWritten – адреса ділянки пам’яті, де процедура WriteConsoleA зберігає число виведених на екран символів.

10.2. Логічні структури .REPEAT та .WHILE

У структурі .WHILE відбувається перевірка умови перед

виконанням групи команд. Доти, поки умова залишається іст инною, виконання цієї групи команд повторюється.

.WHILE умова ; перевірка умови твердження .ENDW Директива .REPEAT повторює тіло циклу доти, поки результат

виконання умовного виразу для директиви .UNTIL не набуде помилкового значення.

.REPEAT твердження .UNTIL умова Перед циклом .WHILE у регістр есх посилається число. А далі

перевіряється, чи дорівнює есх нулю. Якщо так – цикл завершується, якщо ні – здійснюється новий оборот. Природно, есх потрібно міняти усередині циклу. Тому перед . ENDW розміщують інструкцію dec есх.

У .REPEAT і .UNTIL перевірка робиться не на початку, а в кінці циклу.

Приклад 10.2. В масиві з 10 чисел зі знаками вибрати числа, які менше 5 та вивести їх на екран

Розв’язання цього прикладу без використання директив високого рівня наведено у листингу 10.4.

Листинг 10.4. Програма розв’язання прикладу 10.2 без

використання директив високого рівня: title CopyRight by Rysovaniy A. N. .386 ; директива визначення типу мікропроцесора

.model flat, stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap:none ; відмінність малих та великих літер include \masm32v9_0\include\windows.inc

Page 265: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

264

include \masm32v9_0\include\user32.inc include \masm32v9_0\include\kernel32.inc includelib \masm32v9_0\lib\user32.lib includelib \masm32v9_0\lib\kernel32.lib BSIZE equ 10 ; розмір буфера

.data ; директива визначення даних mas1 db 1, -1, 25, 4, 37, 6, 0, -17, 86, -2 ; масив чисел len equ $-mas1 ; визначення кількості байтів масиву mas1 frmt db "%d",0 ; завдання перетворення одного числа у

; послідовність символів buf db BSIZE dup(?) ; резервування пам’яті для буфера crlf db 0dh,0ah ; резервування пам’яті для переведення рядка

stdout DWORD ? ; резервування в пам’яті 32-розрядної комірки ; з ім’ям stdout для збереження дескриптора виведення

cWritten DWORD ? ; резервування 32-розрядної комірки пам’яті ; з ім’ям cWritten для адреси символів виведення

.code ; директива початку сегмента-даних start: ; мітка початку програми з ім’ям start

invoke GetStdHandle, STD_OUTPUT_HANDLE mov stdout, eax ; збереження дескриптора mov ecx,len ; занесення кількості байтів масиву mas1 lea esi, byte ptr mas1 ; занесення адреси масиву mas1

nxt: mov eax, [esi] ; занесення числа з пам’яті, адреса якого в esi cmp al,5 ; порівняння числа з 5 jl m1 ; перейти, якщо менше (для чисел зі знаками) jmp m2 ;

m1: push esi ; push ecx ; movsx eax,al ; розширення числа до подвійного слова

invoke wsprintf, \ ; АРІ-функція перетворення 32-розр. числа ADDR buf, \ ; адреса буф., куди буде записана послід. символів

ADDR frmt, \ ; адреса рядка перетворення формату eax ; регістр, зміст якого необхідно перетворити

invoke WriteConsoleA, \ ; АРІ-функція виведення на екран stdout, \ ; дескриптор стандартного пристрою виведення

ADDR buf, \ ; адреса початку повідомлення BSIZE, \ ; розмір повідомлення

ADDR cWritten, \ ; адреса, де зберігається число символів NULL

Page 266: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

265

invoke WriteConsoleA, stdout, ADDR crlf,\ 2, ADDR cWritten, NULL pop ecx pop esi

m2: inc esi ; підготовка нової комірки масиву loop nxt ; перейти на nxt, якщо ecx ≠ 0 invoke ExitProcess, 0 ; повернення керування ОС Windows

; та визволення ресурсів end start ; директива закінчення програми з ім’ям start Процес отримання повідомлень при розв’язанні прикладу 10.2

через файловий менеджер FAR наведено на рис. 10.6. Перед початком циклу в регістр есх заноситься кількість байтів

масиву. Перед викликом процедур Windows зберігаються регістри, тому що вони можуть бути змінені при обробці цих процедур. Другий виклик

Рис. 10.6. Процес отримання повідомлень при розв’язанні прикладу 10.2

Page 267: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

266

процедури WriteConsoleA необхідний для переведення рядка на другу позицію.

Перший параметр функції wsprintf – це ADDR buf – адреса буфера, куди буде записана послідовність символів.

Другий параметр функції wsprlntf – ADDR ifmt – це адреса рядка формату, яка задає тип перетворення.

Вигляд налагоджувача до виконання цієї програми наведено на рис. 10.7.

Рис. 10.7. Вигляд налагоджувача до виконання програми прикладу 10.2

Page 268: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

267

При перевірці правильності функціонування програми у налагоджувачі OllyDbg при використанні функцій, які не потрібно перевіряти, у покроковому режимі треба нажимати кнопку F8.

Разом з числом, яке виводиться можна вивести й текст. Для цього

необхідно в команді frmt db "%d",0 в скобках навести текст, наприклад frmt db "digit = %d",0

Спробуємо замінити команду loop в листингу 10.4 директивами .WHILE і .ENDW, за допомогою яких виведення на екран чисел може виглядати так, як у листингу 10.5.

Листинг 10.5. Програма розв’язання прикладу 10.2 з

використанням директив високого рівня: title CopyRight by Rysovaniy A. N. .386 ; директива визначення типу мікропроцесора

.model flat, stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap:none ; відмінність малих та великих літер include \masm32v9_0\include\windows.inc include \masm32v9_0\include\user32.inc include \masm32v9_0\include\kernel32.inc includelib \masm32v9_0\lib\user32.lib includelib \masm32v9_0\lib\kernel32.lib BSIZE equ 10

.data ; директива визначення даних mas1 db 1, -1, 25, 4, 37, 6, 0, -17, 86, -2 len equ $-mas1 ; обчислення кількості байтів у масиві mas1 frmt db "%d",0 ; завдання перетворення одного числа

; у послідовність символів buf db BSIZE dup(?) ; резервування пам’яті для буфера crlf db 0dh,0ah ; резервування пам’яті для переведення рядка

stdout DWORD ? ; резервування в пам’яті 32-розрядної комірки ; з ім’ям stdout для збереження дескриптора виведення

cWritten DWORD ? ; резервування 32-розрядної комірки пам’яті ; з ім’ям cWritten для адреси символів виведення

.code ; директива початку сегмента-даних start: invoke GetStdHandle, STD_OUTPUT_HANDLE

mov stdout, eax ; збереження дескриптора mov ecx,len ; занесення кількості байтів масиву mas1

Page 269: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

268

lea esi, byte ptr mas1 ; занесення адреси масиву mas1 .WHILE ecx!=0 ; продовжувати, якщо есх ≠ 0

mov eax, [esi] cmp al,5 ; порівняння числа з 5 jl m1 ; перейти, якщо менше (для чисел зі знаками) jmp m2

m1: push esi push ecx movsx eax,al

invoke wsprintf, \ ; АРІ-функція перетворення 32-розрядного числа ADDR buf, \ ; адреса буф., куди буде записана послід. символів

ADDR frmt, \ ; адреса рядка перетворення формату eax ; регістр, зміст якого необхідно перетворити

invoke WriteConsoleA, \ ; АРІ-функція виведення на екран stdout, \ ; дескриптор стандартного пристрою виведення

ADDR buf, \ ; адреса початку повідомлення BSIZE, \ ; розмір повідомлення

ADDR cWritten, \ ; адреса, де зберігається число символів NULL

invoke WriteConsoleA, stdout, ADDR crlf,\ 2, ADDR cWritten, NULL

pop ecx pop esi

m2: inc esi ; підготовка нової комірки масиву dec ecx ; зменшення кількості проходжень циклу

.ENDW ; закінчення директиви invoke ExitProcess, 0 ; повернення керування ОС Windows

; та визволення ресурсів end start ; директива закінчення програми з ім’ям start Вигляд налагоджувача після виконання цієї програми наведено на

рис. 10.8. У табл. 10.2 перераховані директиви умов. У випадках, якщо

директива дозволяє т рансляцію, то це означає, що транслюватиметься вся послідовність команд до директиви ENDIF.

Page 270: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

269

Рис. 10.7. Вигляд налагоджувача до виконання програми прикладу 10.2

Page 271: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

270

Таблиця 10.2

Директиви умов Директиви Призначення

IF вираз Дозволяє трансляцію, якщо значення виразу істинно (не нуль). Допустимі оператори відношення LT, GT, EQ, NE, LE і GE

IFB <аргумент> Дозволяє трансляцію, якщо аргумент пропущений. Ім’я параметра повинне бути поміщене в кутові дужки (<>)

IFNB <аргумент> Дозволяє трансляцію, якщо аргумент не пропущений. Ім’я параметра повинне бути поміщене в кутові дужки (<>)

IFIDN <арг1>, <арг2>

Дозволяє трансляцію, якщо обидва аргументи рівні. Порівняння можна зробити чутливим до регістра, якщо використовується директива IFIDNI

IFDIF <арг1>, <арг2>

Дозволяє трансляцію, якщо аргументи не рівні. Порівняння можна зробити чутливим до регістра, якщо використовується директива IFIDNI

IFDEF ім’я Дозволяє трансляцію, якщо ім’я визначене IFNDEF ім’я Дозволяє трансляцію, якщо ім’я не визначене ENDIF Кінець блока, який починався з директиви

умови ELSE Транслювати всі команди до ENDIF, якщо

умова попередньої директиви IF помилковоа EXITM Негайний вихід з макроозначення

10.3. Лабораторна робота

“Директиви умовного асемблювання”

Мета заняття: – поглибити і закріпити знання з архітектури МП платформи х86 і

навички його програмування; – придбати практичні навички складання, налагодження і

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

Page 272: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

271

написаних мовою асемблеру для програмування арифметичних виразів для МП платформи х86.

Постановка задачі Згідно з останньою цифрою номера в групі вибрати варіант та

написати програму з використанням директив умовного асемблювання:

1. Задано масив А з N = 40 елементів. Навести алгоритм та програму визначення суми елементів масиву А, для яких біти 2 та 10 збігаються. Вивести відповідні повідомлення.

2. Проаналізувати масив даних mas1 з 10 елементів. Підрахувати і зберегти в комірках пам’яті кількість елементів масиву, якщо їх значення менше або більше першого елемента та дорівнюють останньому. Вивести відповідні повідомлення.

3. Задано масив А з N = 28 елементів. Навести алгоритм та програму формування масиву В з елементів масиву А, у яких 0, 2 та 5 біти мають нулі.

4. Проаналізувати масив даних з 10 елементів. Додавати елементи масиву доти, поки значення суми не перевищить 512 та не буде менше 510. Зберегти номер елемента, на якому відбулося переповнення. Якщо сума елементів не досягла значення 512, то видати відповідне повідомлення.

5. Проаналізувати масив даних з 16 елементів. Елементами масиву є числа 32 та 128. Підрахувати та вивести на екран кількість елементів, які за значенням знаходяться у середині цього діапазону.

6. Проаналізувати масив даних A з 12 елементів. Створити масив B, до якого входять елементи першого масиву, що задовольняють умову -1 ≤ Bi > 128. Перервати виконання програми, якщо буде знайдено 5 елементів зі значенням 12. Вивести відповідні повідомлення.

7. Проаналізувати 2 масиви, що складаються з 15 елементів кожен. Підрахувати кількість елементів першого масиву, що мають рівні значення в другому масиві. Вивести відповідні повідомлення.

8. Проаналізувати масив даних з 14 елементів. Підрахувати кількість елементів, значення яких дорівнює 55h. Рахунок перервати, якщо кількість елементів перевищить 3. Вивести відповідні повідомлення.

9. Задано масиви А і В по N = 30 елементів. Навести алгоритм та програму формування масиву С за правилом: якщо у елементів Аі та Ві біти 4 та 9 збігаються, то Сі = Аi + Вi. Вивести відповідні повідомлення.

Page 273: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

272

10. Проаналізувати масив даних з 20 елементів. Підрахувати кількість елементів, які находяться у діапазонах 10 – 20 та 30 – 40. Вивести відповідні повідомлення.

12. Задано масив А з N = 20 елементів. Структура масиву А: X1,Y1;X2,Y2; … . Навести алгоритм та програму визначення кількості пар, для яких виконується умова Хi ≤ Yi. Вивести відповідні повідомлення.

13. Задано масив А з 5 елементів. Навести алгоритм та програму визначення елементів масиву А, які задовольняють умову 6 ≤ Аі < 3А, та розмістити їх в новому масиві. Вивести відповідні повідомлення.

14. Задано масиви А і В по N = 65 елементів. Навести алгоритм та програму сформування масиву С за правилом: якщо Аi – Вi ≤ 0, то Сj = Aі.

15. Задано масив А з N = 50 елементів. Навести алгоритм та програму визначення суми та кількості елементів масиву А, які задовольняють умову Аi ≥ Е при Е = – 11. Вивести відповідні повідомлення.

Вимоги до програм: – для перших десяті за списком студентів змінні повинні мати

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

використанням API-функцій. Зміст звіту 1. Постановка задачі для конкретного варіанта. 2. Блок-схема алгоритму виконання прикладу з детальним

коментарем та описом роботи. 3. Листинг програми та коментарі до всіх команд. 4. Рrint screen екрана 32-розрядного налагоджувача з виконанням

програми та результатами виконання. 5. Висновки за результатами роботи. Приклад 10.3 Проаналізувати масив даних з 10 елементів розміром у подвійне

слово. Додавати елементи масиву доти, поки значення суми не перевищить 15 та не буде менше 7. Зберегти номер елемента, на якому відбулося переповнення. Видати повідомлення на екран монітора (текстове або/чи) числове.

Page 274: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

273

Блок-схему алгоритму виконання прикладу наведено на рис. 10.8. При розв’язанні цієї задачі рекомендується спочатку написати та

налагодити програму без використання директив високого рівня. Розв’язання прикладу 10.3 без використання директив високого рівня наведено у листингу 10.6.

Листинг 10.6. title CopyRight by Rysovaniy A. N. [email protected] .386 ; директива визначення типу мікропроцесора

.model flat, stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

Кінець

Початок

Визначення констант

Визначення кільк. байтів в mas1

ecx := len start:

ecx := ecx/4

esi := [mas1]

eax := [esi]

.IF(eax<op1)&&(eax>op2)

Виведення повідомлення

esi := esi + 4

ebx := ebx + 4

ecx := ecx – 1

eax := eax + ebx

ebx := [esi + 4]

ecx = 0 ні

так

ні

Рис. 10.8. Блок-схема алгоритму виконання прикладу 10.3

Page 275: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

274

option casemap:none ; відмінність малих та великих літер .data ; директива визначення даних

mas1 dd 1,4,5,4,6,7,3,8,2,10 ; масив чисел len equ $-mas1 ; визначення кількості байтів в масиві op1 dd 15 ; запис у 32-розрядну комірку пам’яті з ім’ям op1

; числа 15 (максимальна межа) op2 dd 7 ; мінімальна межа

.code ; директива початку сегмента-даних start: ; мітка початку програми з ім’ям start

mov ecx,len ; завантаження лічильника shr ecx,2 ; визначення кількості подвійних слів lea esi, mas1 ; завантаження адреси початку масиву mov eax, [esi] ; завантаження числа

m1: .IF(eax<op1)&&(eax>op2) ; складна умова

.ELSE ; інакше

mov ebx,[esi+4] ; завантаження нового числа з масиву add eax,ebx ; додавання елементів add esi,4 ; розрахунок адреси нового числа add ebx,4 ; розрахунок адреси наступного числа

loop m1 ; перейти, якщо ecx ≠ 0

.ENDIF ; закінчення директиви високого рівня ret ; повернення керування ОС end start ; директива закінчення програми з ім’ям start В наведеній програмі при виникненні необхідності додавання двох

чисел одного масиву необхідно використати додатковий регістр (для зберігання адреси другого числа). Таким регістром вибрано регістр ebx. Завантаження в цей регістр значення адреси другого числа виконується командою mov ebx,[esi+4].

У зв’язку з тим, що за завданням вибрано формат регістрів в 32 розряди ( 4 байти), то для підготовки зчитування нових слів виконуються команди

add esi,4 add ebx,4.

Page 276: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

275

Після директиви .IF(eax<op1)&&(eax>op2) в початковому варіанті не використовуються ніякі команди, щоб не внести ніякої помилки.

Вікна налагоджувача після налагодження програми з листингу 10.6

наведено на рис.10.9. Для виконання другої частини роботи необхідно організувати

виведення даних на екран. Для цього доцільно використати АРІ-функцію WriteConsoleA, фрагмент використання якої може бути таким:

.386

.model flat, stdcall option casemap:none include \masm32v9_0\include\windows.inc include \masm32v9_0\include\user32.inc include \masm32v9_0\include\kernel32.inc includelib \masm32v9_0\lib\user32.lib includelib \masm32v9_0\lib\kernel32.lib BSIZE equ 15

Рис. 10.9. Вікна налагоджувача після налагодження програми з листингу 10.6

Page 277: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

276

.data ; директива визначення даних stdout dd ? ; дані для дескриптора виведення, що не визначені buf db BSIZE dup(?) ; резервування пам’яті для буфера frmt db "%d",0 ; завдання перетворення одного символу

cWritten dd ? ; комірки пам’яті для адрес ; символів виведення

. . . .code ; директива початку сегмента-даних start: ; мітка початку програми з ім’ям start . . .

invoke GetStdHandle, STD_OUTPUT_HANDLE ; отриманого дескриптора mov stdout, eax ; запам’ятання отриманого дескриптора

. . . invoke wsprintf, \ ; АРІ-функція перетворення числа

ADDR buf, \ ; адреса буфера, куди буде записана послід. символів ADDR frmt, \ ; адреса рядка перетворення формату

edx ; регістр, вміст якого перетворюється invoke WriteConsoleA, \ ; АРІ-функція виведення на екран

stdout, \ ; дескриптор стандартного пристрою виведення ADDR buf,\ ; адреса початку повідомлення

BSIZE, \ ; розмір повідомлення ADDR cWritten, \ ; адреса, де зберігається число символів

NULL invoke ExitProcess, 0 ; повернення керування ОС Windows

; та визволення ресурсів end start ; директива закінчення програми з іменем start У цій програмі використовуються файли user32.inc і user32.lib,

що зберігають інформацію про функцію wsprintf. Число її параметрів поки дорівнює трьом:

– параметр ADDR buf – адреса буфера, куди буде записана послідовність символів. Пам’ять для буфера виділяється рядком buf db BSIZE dup(?), який резервує кількість байтів, заданих змінною BSIZE. Про резервування байтів пам’яті, говорить слово dup – скорочене від англійського слова duplication (повторення). Знак питання, в дужках після dup, свідчить про те, що значення байтів наперед не визначене.

Розмір буфера, позначений ім’ям BSIZE, є реальним числом, яким асемблер замінить BSIZE та задається рядком BSIZE equ 15.

Page 278: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

277

– параметр функції wsprlntf – ADDR ifmt – це адреса рядка формату, яка задає тип перетворення. Цей рядок складається з символів і завжди завершується нульовим байтом. Рядок “%d”,0 задає перетворення одного цілого числа в послідовність символів, а рядок “%d%d”,0 – перетворення двох чисел.

– параметр edx вказує функції wsprintf, що число, яке потребує перетворення в послідовність символів знаходиться, наприклад, у регістрі edx.

Процедура WriteConsoleA виводить ці символи на екран. За першим параметром цієї функції (stdout) перетворене у символ число виводиться через консоль, за другим (параметр ADDR buf) вказується адреса початку повідомлення, за третім (BSIZE) розмір повідомлення, за четвертим (ADDR cWritten) адреса ділянки пам’яті, де процедура WriteConsoleA зберігає число виведених на екран символів.

10.4. Лабораторна робота

“Двовимірні масиви”

Мета заняття: – поглибити і закріпити знання з архітектури МП платформи х86 і

навички його програмування; – придбати практичні навички складання, налагодження і

виконання програм для програмування двовимірних масивів, написаних мовою асемблеру для МП платформи х86 з організацією виведення результату на з використанням АРІ-функцій.

Постановка задачі Згідно з останньою цифрою номера в групі вибрати варіант та

написати програму з виведенням даних на екран монітора: 1. Ввести двовимірний масив А(N,N). Скласти алгоритм і програму

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

2. Ввести двовимірний масив А(N,N). Скласти алгоритм і програму підрахунку середнього арифметичного значення двовимірного масиву. Обчислити відхилення від середнього для всіх елементів двовимірного масиву.

Page 279: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

278

3. Ввести двовимірний масив А(N,N). Скласти алгоритм і програму заміни всіх негативних елементів на середнє арифметичне значення елементів двовимірного масиву.

4. Скласти алгоритм і програму знаходження числа рядків двовимірного масиву А(N,N), кількість негативних елементів в яких більше M.

5. Ввести двовимірний масив розміром 7 × 4. Знайти найбільший елемент двовимірного масиву. Видалити рядок з максимальним елементом.

6. Ввести двовимірний масив розміром 3 × 4. Поміняти стовпець з максимальним елементом з першим стовпцем двовимірного масиву .

7. Ввести двовимірний масив розміром 4 × 7. Знайти максимальний елемент двовимірного масиву, розташований нижче за побічну діагональ.

8. Ввести двовимірний масив розміром 5 × 4. Знайти найменший елемент двовимірного масиву. Перенести рядок, що містить цей елемент, в кінець.

9. Ввести двовимірний масив розміром 6 × 4. Знайти максимальний елемент двовимірного масиву. Перенести рядок, що містить цей елемент, в кінець.

10. Ввести двовимірний масив розміром 7 × 4. Знайти мінімальний елемент двовимірного масиву. Переставляючи рядки і стовпці, добитися того, щоб він опинився в правому нижньому кутку.

11. Скласти алгоритм обчислення суми елементів двовимірного масиву А(1.. N, 1..М), розташованих вище за головну діагональ.

12. Скласти алгоритм обчислення кількості непарних елементів в кожному рядку двовимірного масиву А(1.. N, 1..М).

13. Скласти алгоритм пошуку максимального значення в двовимірному масиві А(N,M).

Зміст звіту 1. Постановка задачі для конкретного варіанта. 2. Блок-схема алгоритму виконання прикладу з детальним

коментарем та описом роботи. 3. Листинг програми та коментарі до всіх команд. 4. Рrint screen екрана 32-розрядного налагоджувача з виконанням

програми та результатами виконання. 5. Висновки за результатами роботи.

Page 280: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

279

11. МАКРОВИЗНАЧЕННЯ

11.1. Введення в макровизначення

Макровизначення – це одне або декілька затверджень мови асемблеру, яким привласнено символічне ім’я і які можна викликати по цьому імені. При виклику макровизначення копія команд, що представляють дане макровизначення вставляється в програму.

Достоїнством застосування макровизначення є те, що програма виконується швидше, ніж процедура. Це відбувається тому, що в макросах відсутні команди CALL і RET, які примушують процесор організовувати перехід на іншу гілку і робити повернення з неї в початкову точку.

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

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

У макровизначенні є можливість включення параметрів. Макровизначення викликається при розміщенні його імені в

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

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

Макровизначення може бути створене в будь-якому місці програми за допомогою директив MACRO і ENDM.

Синтаксис: mІм’я MACRO parameter_l, parameter_2...

список команд ENDM

Page 281: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

280

Мала буква "m" в префіксі імені застосовується для зручності ідентифікації макровизначення.

Для виділення коментарів в макровизначеннях двічі ставиться крапка з комою (;;). При цьому коментарі з’являються тільки в написаному макровизначенні, а не в тих фрагментах, які вставляються в тіло програми.

При багатократному використанні макросу і за наявності внутрішніх міток в ньому необхідно використовувати директиву LOCAL <мітка>. В цьому випадку компілятор формує кожного разу унікальну мітку. Директива LOCAL повинна бути записана відразу після заголовка макровизначення.

Приклад 11.1. Скласти програму знаходження максимального

елемента для трьох чисел за допомогою макросів. Листинг 11.1. Програма виконання прикладу 11.1: .386 ; директива визначення типу мікропроцесора

.model flat, stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap:none ; відмінність малих та великих літер includelib\masm32v9_0\lib\kernel32.lib ExitProcess proto :DWORD ; прототип API-функції

mMax macro x,y,z ; макрос з ім’ям mMax local m1,m2 mov eax,x ;; завантаження першого операнда cmp eax,y ;; завантаження другого операнда jge m1 ;; перейти на m1, якщо op1 >= op2 mov ebx,y ;; збереження у тимчасовому регістрі mov v,ebx ;; запис у комірку пам’яті jmp m2 ;; перейти на закінчення

m1: mov v,eax ;; m2: endm ;; закінчення макросу

.data ; директива визначення даних x dd 4 ; записати в 32-розрядну комірку пам’яті число х = 4 y dd 3 ; записати в 32-розрядну комірку пам’яті число y = 3 z dd 5 ; записати в 32-розрядну комірку пам’яті число z = 5

v dd ? ; резервувати в пам’яті 32-розрядну комірку для змінної v .code ; директива початку програми

start: ; мітка початку програми з ім’ям start

Page 282: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

281

mMax [x],[y],[v] ; виклик макросу mMax mMax [v],[z],[v] ; виклик макросу mMax

invoke ExitProcess, 0 ; повернення керування ОС Windows ; та визволення ресурсів

end start ; директива закінчення програми з ім’ям start На рис. 11.1. наведено команди асемблера та вікна налагоджувача

після виконанням програми листингу 11.1. Використовуючи специфікатор REQ, можна задати обов’язкову

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

mMax macro x:req,y:req,z:req ;; Необхідний параметр ... ENDM Якщо в макроозначенні декілька необхідних параметрів, кожен

параметр повинен включати специфікатор REQ.

Рис. 11.1. Команди асемблеру та вікна налагоджувача після виконанням програми з листингу 11.1

Page 283: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

282

11.2. Булеві вирази

У асемблері MASM дозволені оператори відносин такі ж, як й при використанні директив високого рівня: ==, != , > , >=, <, <= та інші.

Приклад 11.2. Написати програму з використанням макросу, який

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

Ця програма може бути такою (листинг 11.2):

Листинг 11.2. Програма виконання прикладу 11.2: .386 ; директива визначення типу мікропроцесора

.model flat, stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap:none ; відмінність малих та великих літер includelib\masm32v9_0\lib\kernel32.lib ExitProcess proto :DWORD ; прототип API-функції mMulD macro digit ; макрос з ім’ям mMulD

.IF digit == 2 ;; якщо digit = 2, то shl eax,1 ;; зсув ліворуч на 1 розряд .ELSEIF digit == 4 ;; якщо digit = 4, то shl eax,2 ;; зсув ліворуч на 2 розряди .ELSEIF digit == 8 ;; якщо digit = 8, то shl eax,3 ;; зсув ліворуч на 3 розряди .ELSEIF digit == 16 ;; якщо digit = 16, то shl eax,4 ;; зсув ліворуч на 4 розряди .ELSE ;; інакше mov ebx, digit mul ebx ;; eax, edx = eax*ebx – звичайне перемноження

.ENDIF endm ;; закінчення макросу

.data ; директива визначення даних digit dd 6 ; запис у 32-розрядну комірку з ім’ям digit числа 6

.code ; директива початку програми _start: ; мітка початку програми з ім’ям start

mov eax,digit ; занесення в еах числа з комірки пам’яті з ім’ям digit mMulD [digit] ; виклик макросу invoke ExitProcess, 0 ; повернення керування ОС Windows

Page 284: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

283

; та визволення ресурсів end _start ; директива закінчення програми з ім’ям start Команди асемблеру та вікна налагоджувача після виконанням

першої команди зсуву регістра ЕАХ програми з листингу 11.2 наведено на рис. 11.2.

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

чисел ступеня двійки, для множення яких виконуються зсуви. Приклад 11.3. Написати програму на асемблері з використанням

макросу обчислення виразу x/4a +2x/a.

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

Перед початком написання програми доцільно розробити схему виконання прикладу (рис. 11.3):

Рис. 11.2. Команди асемблеру та вікна налагоджувача після виконанням першої команди зсуву регістра ЕАХ програми з листингу 11.2

Page 285: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

284

Приклад обчислення виразу x/4a + 2x/a наведено в листингу 11.3.

Листинг 11.3. Програма обчислення прикладу 11.3 з використанням

макросів та змінних розміром у байт: title CopyRight by Rysovaniy A. N. .386 ; директива визначення типу мікропроцесора

.model flat, stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap:none ; відмінність малих та великих літер includelib\masm32v9_0\lib\kernel32.lib ExitProcess proto :DWORD ; прототип API-функції

mDivB macro x,a ; макрос з ім’ям mDivB mov ah,0 ;; підготовка до ділення mov al,x ;; завантаження операнда div a ;; ah,al = 0112h mov res1_1,al ;; ст. частина mov res1_2,ah ;; мол. частина

endm ;; закінчення макросу .data ; директива визначення даних

x db 55 ; записати в байт пам’яті число х = 37h a db 3 ; записати в байт пам’яті число а = 3 res1_1 db 0 ; для збереження старшої частини x/a res1_2 db 0 ; для збереження молодшої частини res2_1 db 0 ; для збереження цілої частини x/4a res2_2 db 0 ; для збереження остатка x/4a resH db 0 ; для збереження старшої частини результату resL db 0 ; для збереження молодшої частини результату

.code ; директива початку програми

x/a

res1_1 al = 12h

ціла частина

res1_2 ah = 01h залишок

x/a 1/4

res1_1 al = 12h res2_1

ціла частина

res1_2 ah = 01h res2_2

залишок

+

Рис. 11.3. Схема виконання прикладу 11.3

Page 286: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

285

start: ; мітка початку програми з ім’ям start mDivB [x],[a] ; виклик макросу

; ділення цілої частини mov al,res1_1 ; старша частина = 12h movzx ax,al ; розширення до dw mov bl,04h ; div bl ; ax = 0204, 04h – ціла частина mov res2_1,al ; збереження цілої частини результату x/4a mov al,res1_2 ; залишок від попереднього ділення = 01h

div bl ; ділення остатка cmp ah,08 ; порівняння для округлення jae m1 ; якщо >= jmp m2 ; безумовний перехід на мітку m2

m1: inc al ; збільшення на одиницю остатка m2: mov res2_2,al ; залишок, який округлили

mDivB [x],[a] ; виклик макросу mov bl,res1_2 ; add bl,res2_2 ; обчислення остатка mov bh,res1_1 ; adc bh,res2_1 ; обчислення цілої частини mov resL,bl ; збереження остаточного залишку mov resH,bh ; збереження остаточної цілої частини

invoke ExitProcess, 0 ; повернення керування ОС Windows ; та визволення ресурсів

end start ; директива закінчення програми з ім’ям start У програмі для її налагодження передбачено додаткові комірки

пам’яті, які в остаточному варіанті можна не використовувати, але при цьому змінити програму. Ділення x/a виконується у макросі mDivB [x],[a] з двома аргументами, а ділення на 4 цього макроса – в два етапи. На першому етапі виконується ділення на 4 цілої частини попереднього результату, а на другому етапі отриманий остаток при діленні на 4 пристиковується до залишку, отриманого раніше, й процес ділення продовжується.

Командою cmp ah,08 виконується порівняння молодшого залишку з половиною максимального значення регістра, що у шістнадцятковій системі числення дорівнює 8. При цьому якщо результат порівняння молодшої частини залишку більше або дорівнює 8, то до старшої частини остатку додається одиниця.

Page 287: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

286

Налагоджувач на етапі трансляції програми замість імен комірок пам’яті підставляє конкретні значення. Результат виконання прикладу дорівнює 16,81h. Остаток результату розміщена у комірці пам’яті 00403007, а ціла частина – у комірці 00403006.

Стан програми з листингу 11.3 після її виконання наведено на рис. 11.4.

11.3. Оператори в макровизначеннях

В макровизначеннях можуть використовуватися такі оператори: & – оператор заміни; <>– оператор виділення тексту; ! – оператор виділення символу; % – оператор виразу; ;; – коментар макровизначення.

Рис. 11.4. Стан програми з листингу 11.3 після її виконання

Page 288: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

287

11.4. Оператор заміни

Оператор заміни (&) дозволяє замінювати параметр значенням, яке передається як аргумент. Синтаксис оператора заміни такий:

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

формального параметра. В цьому випадку послідовність символів формального аргументу відокремлюють з двох сторін від решти контексту за допомогою спеціального символу &. Цей прийом часто використовується для завдання ідентифікаторів, що модифікуються, і кодів операцій.

Приклад 11.4. Скласти програму для обміну місцями даних за

допомогою макросів. У листингу 11.4 наведено приклад без використання оператора

заміни. Листинг 11.4. Програма виконання прикладу 11.4: title CopyRight by Rysovaniy A. N. .386 ; директива визначення типу мікропроцесора

.model flat, stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap:none ; відмінність малих та великих літер includelib\masm32v9_0\lib\kernel32.lib ExitProcess proto :DWORD ; прототип API-функції mExchange macro a, b ; макрос з ім’ям mExchange

push eax ; запам’ятовування у стеку eax push ebx ; запам’ятовування у стеку ebx mov eax, a ; занесення до регістра eax операнда а mov ebx, b ; занесення до регістра ebx операнда b mov a, ebx ; обміну місцями даних mov b, eax ; обміну місцями даних pop ebx ; зчитування з стеку ebx pop eax ; зчитування з стеку eax endm ;; закінчення макросу

.data ; директива визначення даних op1 dd 1 ; записати в 32-розрядну комірку пам’яті з іменем op1 число 1 op2 dd 2 ; записати в 32-розрядну комірку пам’яті з іменем op2 число 2

.code ; директива початку програми

Page 289: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

288

start: ; мітка початку програми з ім’ям start mExchange [op1], [op2] ; виклик макросу invoke ExitProcess, 0 ; повернення керування ОС Windows

; та визволення ресурсів end start ; директива закінчення програми з ім’ям start В листингу 11.4 виконується обмін даними між комірками пам’яті

a та b через регістри EAX EBX. Стан програми з листингу 11.4 після її виконання наведено на

рис. 11.5. У листингу 11.5 наведено приклад програми з використанням

операторів заміни в макросах. Параметр, який може бути замінений, виділяється з двох сторін символом &.

Листинг 11.5: title CopyRight by Rysovaniy A. N. .386 ; директива визначення типу мікропроцесора

.model flat, stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap:none ; відмінність малих та великих літер includelib\masm32v9_0\lib\kernel32.lib ExitProcess proto :DWORD ; прототип API-функції mExchange macro a, b, t ; макрос з ім’ям mExchange push eax

Рис. 11.5. Стан програми з листингу 11.4 після її виконання

Page 290: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

289

push ebx mov &t&ax,a mov &t&bx,b mov a,&t&bx mov b,&t&ax pop ebx pop eax endm ;; закінчення макросу .data ; директива визначення даних

op1d dd 0Bh ; записати в 32-розр. комірку пам’яті з іменем op1d число 11 op2d dd 16h ; 16h = 22 op1w dw 21h ; 21h = 33 op2w dw 2Ch ; 2Ch = 44

.code ; директива початку програми start: ; мітка початку програми з ім’ям start mExchange [op1w], [op2w] ; виклик макросу з двома параметрами mExchange [op1d], [op2d],e ; виклик макросу з 3 параметрами

invoke ExitProcess, 0 ; повернення керування ОС Windows ; та визволення ресурсів

end start ; директива закінчення програми з іменем start При першому виклику макросу виконується обмін словами, а при

другому виклику – подвійними словами, причому, замість параметра t виконується підставлення символу e. Це приводить не до виклику регістра АХ, а вже до ЕАХ.

Стан програми з листингу 11.5 після її виконання наведено на рис. 11.6.

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

11.5. Оператор виразу

Оператор виразу (%) дозволяє розрахувати результат виразу і

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

Page 291: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

290

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

У наступному прикладі обчислюється вираз (4+count) і

повертається значення 14 як символьний текст. count = 10 sumV TEXTEQU %(4 + count) ; = "14" Якщо в макровизначенні потрібен цілочисельний аргумент,

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

Коли оператор виразу (%) – перший символ в рядку, то препроцесор повинен розвернути всі тексти макровизначення і знайти рядок.

11.6. Оператор виділення тексту

Оператор виділення тексту (<>) об’єднує разом рядки символів. Це

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

Рис. 11.6. Стан програми з листингу 11.5 після її виконання

Page 292: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

291

і IFIDN. Він також використовується, коли рядок включає спеціальні символи (",","%","&" та ";"), які самі по собі можуть бути інтерпретовані як макрооператори. У наступному прикладі написано макровизначення з ім’ям mMessage:

mMessage MACRO text DB "&text",0

ENDM Наприклад, макровизначення можна викликати так: mMessage <A1 50% &A2;>

і асемблер запише: DB "A1 50% &A2;",0

11.7. Оператор виділення символу

Оператор виділення символу (!) використовується для тих же цілей, що і оператор виділення тексту. Він примушує асемблер інтерпретувати окремий символ тільки як символ, а не як оператор.

11.8. Додаткові макровизначення і директиви

Директива REPT Одну або декілька команд можна повторити з використанням

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

REPT вираз блок команд

ENDM Вираз визначає кількість повторень і задається 16-розрядним

числом без знаку. Припустимо, необхідно використовувати REPT для розподілу таблиці, що включає 100 записів про співробітників.

index LABEL byte ; початок таблиці REPT 100 ; початок циклу REPT

DB 7 DUP (?) ; номери співробітників DB 20 DUP (‘ ‘) ; прізвище DW ? ; відповідність

ENDM

Page 293: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

292

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

mSHL MACRO dest,count REPT count

SHL dest,1 ENDM

ENDM Макровизначення можна викликати так: mSHL AX,1 mSHL BX,4 Код, що при цьому був згенерований асемблером, буде такий: SHL АХ,1 SHL ВХ,1 SHL ВХ,1 SHL ВХ,1 SHL ВХ,1

Директива IRP Директива IRP створює блок, що повторюється, де кожне

повторення включає різні значення. Синтаксис цієї директиви такий: IRP аргумент,< аргумент [, аргумент] ...>

команди ENDM Блок повторюється тільки для кожного аргументу. При кожному

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

IRP parm,<10,20,30,40>

DW parm, parm * 2, parm * 3, parm * 4 ENDM

Page 294: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

293

Згенерувало. DW 10, 10 * 2, 10 * 3, 10 * 4 DW 20, 20 * 2, 20 * 3, 20 * 4 DW 30, 30 * 2, 30 * 3, 30 * 4 DW 40, 40 * 2, 40 * 3, 40 * 4 За допомогою директиви IRP можна створити таблицю зсувів

процедур, що використовується для вибору декількох гілок за індексом: MOV BX,indexvalue ; вибір розділу таблиці CALL proctable[BX] ; непрямий виклик У наступному фрагменті з використанням директиви IRP як

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

proctable LABEL word IRP procname,<MOVup,MOVdn,MOV1ft,MOVrt> DW procname

ENDM Асемблер згенерує такі команди: proctable LABEL word DW MOVup DW MOVdn DW MOVlft DW MOVrt Поєднання зсувів і повторень Раніше використовувалася директива REPT для створення

макровизначення mSHL, яке зрушувало операнд вліво на задане число біт. Для того щоб такі ж можливості створити для всіх інших команд зсуву і циклічного зсуву, необхідно написати вісім різних макровизначень. Проте є набагато кращий шлях: можна скомбінувати директиву IRP з написанням макровизначення, щоб одержати різні варіанти. Наступне макровизначення генерує вісім різних макроозначень з іменами mSHL, mSHR, mSAL, mSAR, mROL, mROR, mRCL та mRCR:

IRP Styp,<SHL,SHR,SAL,SAR,ROL,ROR,RCL,RCR> m&styp MACRO dest,count

Page 295: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

294

PUSH СX MOV CL,count styp dest,CL POP CX ENDM ENDM Параметр dest може бути 8-, 16- або 32-розрядним регістром або

змінною, окрім регістрів CL, СХ або ЕСХ. Параметр count може бути безпосереднім значенням, регістром або операндом пам’яті розміром 8 біт.

Оператор заміни (&) дозволяє замінювати рядок аргументів при виклику макровизначення. У наведеному прикладі директива IRP проведе виклик макровизначення вісім разів, використовуючи різні значення змінної styp при кожному виклику.

Директива IRPC Директива IRPC подібна директиві IRP, за винятком того, що

число символів в аргументі “рядок” визначає число повторень. Синтаксис цієї директиви такий:

IRPC параметр, рядок команди ENDM Рядок може бути поміщений в кутові дужки (< >), якщо вона

містить пропуски, коми або інші спеціальні символи. У наступному прикладі створюється п’ять змінних (value_A, value_B й т. д.), а як аргумент використовується рядок ABCDE:

IRPC parm,ABCDE value_&parm DB ‘&parm’ ENDM Команди, що були згенеровані асемблером: value_A DB ‘A’ value_B DB ‘В’ value_C DB ‘С’ value_D DB ‘D’ value_E DB ‘E’ Макровизначення надають величезні можливості для розширення

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

Page 296: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

295

достатньо велика колекція макровизначень, доводиться кожного разу копіювати їх в створювану програму. Натомість створіть окремий файл з макровизначеннями і використайте директиву INCLUDE для підключення його при асемблюванні. Тепер необхідні макровизначення стануть частиною остаточної програми. Якщо використовується двопрохідний асемблер, такий, як Microsoft Assembler (MASM), то можна обмежити INCLUDE директивами IF1 і ENDIF, які примусять асемблер включати макровизначення тільки при першому проході:

IF1 ; якщо це перший прохід include macros.inc ; підключити файл макровизначень

ENDIF Якщо не вказаний повний шлях файла, що підключається, асемблер

шукатиме його в поточному каталозі. Можна додатково вказати повний або відносний шлях.

11.9. Лабораторна робота “Макроси”

Мета заняття: – поглибити і закріпити знання з архітектури МП платформи х86 і

навички його програмування; – придбати практичні навички складання, налагодження і

виконання програм для програмування макросів, написаних мовою асемблеру для МП платформи х86 з організацією виведення результату на з використанням АРІ-функцій.

Постановка задачі Згідно з останньою цифрою номера в групі вибрати варіант та

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

1. (2a/b) + a/3b; 6. (ab – 3)/ab; 2. (x – a) + 232/(x – a); 7. 2a – b + (2a – b)/a; 3. x + a – 4/(x + a); 8. (ab + d)/(ab – d); 4. 3(a – b) – (a – b)/5; 9. (de + e)/(de – e); 5. 2x – 3 + 8(2x –3); 0. (a/2b) – (a/5b). Вимоги до програм: – для перших десяті за списком студентів змінні повинні мати

розмір байта, для другого десятку – розмір слова;

Page 297: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

296

– програма повинна містити виведення даних на екран монітора з використанням API-функцій.

Зміст звіту 1. Постановка задачі для конкретного варіанта. 2. Блок-схема алгоритму виконання прикладу з детальним

коментарем та описом роботи. 3. Листинг програми. 4. Рrint screen екрана 32-розрядного налагоджувача з виконанням

програми та результатами виконання. 5. Висновки за результатами роботи. Приклад 11.5. Написати програму з використанням макросів для

обчислення виразу a(a – b) – (a – b)

з використанням слів розміром у байт.

Програму без виведення результату на монітор наведено в листингу 11.6.

Листинг 11.6: title CopyRight by Rysovaniy A. N. [email protected] .686 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap:none ; відмінність малих та великих літер includelib \masm32v9_0\lib\kernel32.lib ExitProcess proto:dword ; прототип API-функції

mSubB macro a,b ; макрос з ім’ям mSubB mov al,a ;; занесення змінної а sub al,b ;; віднімання a – b mov res1,al ;; збереження результату у пам’яті

endm ;; закінчення макросу .data ; директива визначення даних a db 6 ; збереження в комірці пам’яті, розміром в байт операнда 6 b db 5 ; збереження в комірці пам’яті, розміром в байт операнда 5

res1 db 0 ; резервування пам’яті для результату res1 res2 dw 0 ; резервування пам’яті для результату res2

.code ; директива початку програми

Page 298: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

297

_start: ; мітка початку програми з ім’ям _start

mSubB [a],[b] ; виклик макросу mov al,a mov bl,res1 mul bl ; ax := al × bl mov bx,ax ; визволення ах для наступних операцій mSubB [a],[b] ; виклик макросу movzx ax,res1 ; занесення з розширенням розрядності sub bx,ax ; mov res2,bx ; збереження залишкового результату

invoke ExitProcess, 0 ; повернення керування ОС Windows ; та визволення ресурсів

end _start ; директива закінчення програми з ім’ям _start Стан програми листингу 11.6 після її виконання наведено на

рис. 11.7. У програмі макрос викликається два рази. У зв’язку з тим, що після перемноження регістрів al та bl результат

зберігається у регістрі ах розміром в слово, виникає необхідність в подальшому зберіганні результату розміром 16 розрядів. Через цю причину використовується команда movzx та інші.

Рис. 11.7. Стан програми з листингу 11.6 після її виконання

Page 299: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

298

Результат виконання програми розташовується в комірці 403003h та при вибраних початкових даних дорівнює 05.

Програму з виведенням результату на монітор наведено в листингу 11.7.

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

Листинг 11.7: title CopyRight by Rysovaniy A. N. .386 ; директива визначення типу мікропроцесора

.model flat, stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap:none ; відмінність малих та великих літер include \masm32v9_0\include\windows.inc include \masm32v9_0\include\user32.inc include \masm32v9_0\include\kernel32.inc includelib \masm32v9_0\lib\user32.lib includelib \masm32v9_0\lib\kernel32.lib BSIZE equ 15

mSubB macro a,b ; макрос з ім’ям mSubB mov al,a sub al,b mov res1,al

endm ; ; закінчення макросу .data ; директива визначення даних

ifmt db "digit = %d",0 ; завдання перетворення одного символу buf db BSIZE dup(?) ; резервування пам’яті для буфера crlf db 0dh,0ah

stdout DWORD ? ; резервування в пам’яті 32-розрядної комірки ; з ім’ям stdout для збереження дескриптора виведення

cWritten DWORD ? ; резервування 32-розрядної комірки пам’яті ; з ім’ям cWritten для адреси символів виведення

a db 6 ; збереження в байті пам’яті десяткового числа 6 з іменем а b db 5 ; збереження в байті пам’яті десяткового числа 5 з іменем b res1 db 0 ; збереження в байті пам’яті нуля з іменем res1 res2 dw 0 ; збереження в двох байтах пам’яті нуля з іменем res2

Page 300: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

299

.code ; директива початку коду програми start: ; мітка початку програми з ім’ям start

invoke GetStdHandle, STD_OUTPUT_HANDLE mov stdout, eax ; запам’ятання отриманого дескриптора mSubB [a],[b]

mov al,a ; запис в al числа з комірки пам’яті з ім’ям а mov bl,res1 ; запис в bl числа з комірки пам’яті з ім’ям res1 mul bl mov bx,ax

mSubB [a],[b] movzx ax,res1 sub bx,ax mov res2,bx movzx ebx,bx

invoke wsprintf, \ ; АРІ-функція перетворення числа ADDR buf, \ ; адреса буф., куди буде записана послід. символів

ADDR ifmt, \ ; адреса рядка перетворення формату ebx ; регістр, вміст якого перетворюється

invoke WriteConsoleA, \ ; АРІ-функція виведення на екран stdout, \ ; дескриптор стандартного пристрою виведення

ADDR buf, \ ; адреса початку повідомлення BSIZE, \ ; розмір повідомлення

ADDR cWritten, \ ; адреса, де зберігається число символів NULL

invoke WriteConsoleA, stdout, ADDR crlf,\ 2, ADDR cWritten, NULL invoke ExitProcess, 0 ; повернення керування ОС Windows

; та визволення ресурсів end start ; директива закінчення програми з ім’ям start В наведеній програмі на екран виводиться вміст регістра ebx.

Причому АРІ-функції потребують, щоб число, яке виводиться, мало розрядність – 32. Інакше буде генерована помилка при трансляції. Щоб помилок не виникало, використано команду збільшення розрядності регістра до 32 (movzx ebx,bx).

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

рис. 11.8.

Page 301: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

300

Результат виконання програми наведено на рис. 11.9, який

отримано у самому налагоджувачі OllyDbg. Такий самий результат можна отримати й через файловий менеджер FAR.

Для виведення чисел на екран за допомогою АРІ-функцій

необхідно, щоб результат був розташований у 32-розрядному регістрі. Тому в програмі з листингу 11.7 використано команду movzx ebx,bx, яка розширює результат до 32-розрядного формату.

Рис. 11.8. Результат виконання програми з листингу 11.7

Рис. 11.8. Стан програми з листингу 11.7 після її виконання

Page 302: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

301

12. ФАЙЛИ

12.1. Створення файлів

При роботі з програмами часто виникає необхідність зберігати отримані результати на жорсткому диску комп’ютера, щоб у подальшому їх використовувати у розрахунках. Середа Win32 здатна підтримуватися декілька файлових систем. Ці системи повинні дотримуватися правила привласнення імен файлам і каталогам.

Функції API Win32, що мають відношення до роботи з файловою системою наведено у табл. 12.1.

Таблиця 12.1

Функція Призначення AreFileApisANSI Визначення набору символів файла Cancello Відмінити всі процеси обробки операції

введення і виведення (I/О), які чекають CloseHandle Закрити відкритий дескриптор файла СоруFilе,

CopyFilеЕх Копіювання існуючого файла в новий файл

CopyProgressRoutine Визначення зворотного виклику. Використовується з функціями CopyFileEx та MoveFileWithProgress. Викликається, коли завершується частина операції копіювання або пересилання

CreateDirectory, CreatedrectoryEx

Створити каталог

CreateFile Створити файл або об’єкт спеціального типу DefineDosDevice Визначити, перевизначити або видалити ім’я

пристрою MS DOS

Page 303: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

302

Продовження табл. 12.1

DeleteFile Видалити файл FindClose Закрити вказаний пошуковий

дескриптор FindCloseChangeNotification Закрити об’єкт-повідомлення про

зміну файла FindFirstChangeNotification Створити об’єкт-повідомлення про

зміну файла FindFirstFile,

FindFirstFileEx, FindNextFile Пошук файлів

FindNextChangeNotification Скидання об’єкта-повідомлення в зайнятий стан

FlushFileBuffers Очищення буфера для вказаного файла і запис всіх буферізованих даних у файл

GetBinaryType Визначити, чи є файл виконуваним і для якої підсистеми – Win32, MS DOS, OS/2, POSIX та ін.

GetCurrentDirectory Отримати поточний каталог GetDiskFreeSpace, GetDiskFreeSpaceEx

Інформація щодо вказаного диска, включаючи кількість вільного простору на ньому

GetDriveType Визначити тип диска – знімний, фіксований, CD-ROM, електронний або мережевий

GetFileAttributes, GetFileAttributesEx

Отримати атрибути файла або каталогу

GetFileInformationByHandle Знайти інформацію щодо вказаного файла

GetFileSize,GetFi1eSizeEx Отримати розмір вказаного файла GetFileType Отримати тип вказаного файла GetFullPathName Отримати повний шлях і ім’я для

вказаного файла

Page 304: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

303

Продовження табл. 12.1 GetLogicalDrives, GetLogicalDriveStrings

Визначити доступні в даний час дисководи

GetLongPathName Перетворити вказаний шлях до його довгої форми

GetShortPathName Отримати псевдонім файла GetTempFileNam Створити ім’я для тимчасового файла GetTempPath Отримати шлях каталогу для тимчасових

файлів LockFile, LockFileEx Блокування файла MoveFile, MoveFileEx, MoveFileWithProgress

Перейменування файла

QueryDosDevice Отримати інформацію про імена пристрою MS DOS

ReadDirectoryChangesW Отримати інформацію про зміни в межах каталогу

ReadFile, ReadFileEx Читання файла з поточної позиції ReadFileScatter Читання даних з файла із збереженням їх

в наборі буферів RemoveDirectory Видалити існуючий порожній каталог SearchPath Пошук вказаного файла SetCurrentDirectory Встановити поточний каталог SetEndOfFile Помістити символ кінця файла (EOF) в

поточну позицію покажчика файла SetFileApisToANSI Використовувати кодову сторінку набору

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

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

SetFileAttributes Встановити атрибути файла SetFilePointer, SetFilePointerEx

Перемістити покажчик файла в певну позицію

Page 305: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

304

Закінчення табл. 12.1 SetVolumeLabel Задати мітку тому UnlockFile,

UnlockFileEx Зняти блокування файла

WriteFile,WriteFileEx Запис у файл WriteFileGather Запис даних у файл з набору буферів

Програма, наведена у листингу 12.1 створює новий файл з іменем

main та зберігає в ньому числа, які раніше були записані в програму. Листинг 12.1. Створення файла з іменем main: .386 ; директива визначення типу мікропроцесора

.model flat, stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap:none ; відмінність малих та великих літер include \masm32v9_0\include\windows.inc include \masm32v9_0\include\kernel32.inc includelib \masm32v9_0\lib\user32.lib includelib \masm32v9_0\lib\kernel32.lib BSIZE equ 20 ; кількість байтів, які записуються у файл

.data ; директива визначення даних fName BYTE "main",0 ; комірки для файла

fHandle DWORD ? ; резервування в пам’яті 32-розрядної ; комірки з ім’ям fHandle для дескриптора збереження файлів

cWritten DWORD ? ; резервування 32-розрядної комірки пам’яті ; з ім’ям cWritten для адреси символів виведення

digs DW 1,2,3,4,5,6,7,8,9,10 ; числа, які записуються у файл .code ; директива початку сегмента-даних start: ; мітка початку програми з ім’ям start invoke CreateFile, ADDR fName, ; адреса імені файла з символами

GENERIC_WRITE, ; запис у файл 0, NULL, ; параметри багатозадачності

CREATE_ALWAYS, ; знищити та створити новий файл FILE_ATTRIBUTE_ARCHIVE, 0

mov fHandle, eax ; запам’ятання дескриптора пристрою invoke WriteFile, fHandle, ; дескриптор пристрою

ADDR digs, ; адреса області пам’яті, що зберігає символи

Page 306: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

305

BSIZE, ; кількість символів ADDR cWritten, ; адреса пам’яті, де зберігається число

; записаних у файл символів NULL

invoke CloseHandle, fHandle ; дескриптор файла invoke ExitProcess, 0 ; повернення керування ОС Windows

; та визволення ресурсів end start ; директива закінчення програми з іменем start Створює файл процедура CreateFile з параметрами. Перший параметр містить адресу імені файла, що складається з

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

створюється файл. Параметр GENERIC_WRITE означає, що дозволений запис у файл, а параметр GENERIC_READ дозволяє тільки читання. Для читання і запису обидва параметри об’єднуються оператором АБО:

GENERIC_READ or GENERIC_WRITE Третій параметр показує, чи може файл використовуватися іншими

програмами в багатозадачному режимі. Четвертий параметр теж має відношення до багатозадачності і

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

П’ятий параметр показує, що робити, якщо файл вже існує. Значення CREATE_ALWAYS наказує знищити вже існуючий файл і створити на його місці порожній файл з тим же ім’ям. Інші значення цього параметра: CREATE_NEW (не чіпає вже існуючий файл), OPEN_EXISTING (відкриває тільки вже існуючий файл, зберігаючи його вміст), OPEN_ALWAYS (якщо файл існує, відкриває його, не чіпаючи вміст, якщо не існує, створюємо новий файл з вказаним ім’ям).

Шостий параметр задає атрибут файла: архівний, прихований, тільки для читання, системний і т.д. В нашому випадку параметр дорівнює FILE_ATTRIBUTE_ARCHIVE – звичайному для більшості файлів атрибуту.

Сьомий параметр дорівнює нулю. Процедура CreateFile повертає в регістр еах дескрипт ор файла,

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

Page 307: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

306

Процедура WriteFile, використовувана для запису у файл символів, має ті ж параметри, що і процедура WriteConsole: дескриптор файла fHandle, адреса області пам’яті, що зберігає символи ADDR digs; кількість символів BSIZE; адреса пам’яті, де зберігається число записаних у файл символів ADDR cWritten; і, нарешті, нікому не потрібний нульовий покажчик NULL. Процедура WriteFile пише у файл байти.

Завершує роботу з файлом процедура CloseHandle, у якої всього один параметр – дескриптор файла. Ця процедура від’єднує файл від дескриптора, і після її виконання файл знову повинен бути відкритий, щоб стали можливими читання або запис.

Після того як стандартними засобами отримано файл з ім’ям, наприклад 12_1L.exe, натискаємо на клавішу Enter та отримаємо файл з ім’ям main. Для того щоб відкрити цей файл, необхідно нажати в оборочці FAR на клавішу F3. Шістнадцяткові коди цього файла можуть мати вигляд, наведений на рис. 12.1.

Якщо у директиві визначення даних digs DW 1,2,3,4,5,6,7,8,9,10

використати слово DWORD, то числа будуть мати вже по чотири байти. І для того, щоб зберегти десять чисел необхідно замість BSIZE equ 20 вказати BSIZE equ 40. Інакше буде збережена у файлі тільки половина чисел від 1 до 5.

12.2. Лабораторна робота “Файли” Мета заняття: – поглибити і закріпити знання з архітектури МП платформи х86 і

навички його програмування; – придбати практичні навички складання, налагодження і

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

Рис. 12.1. Внутрішній вигляд створеного файла

Page 308: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

307

Вимоги до програм: – для перших десяті за списком студентів змінні повинні мати

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

використанням API-функцій. Зміст звіту 1. Постановка задачі для конкретного варіанта. 2. Блок-схема алгоритму виконання прикладу з детальним

коментарем та описом роботи. 3. Листинг програми та коментарі до всіх команд. 4. Рrint screen екрана 32-розрядного налагоджувача з виконанням

програми та результатами виконання. 5. Висновки за результатами роботи. Постановка задачі Згідно з останньою цифрою номера в групі вибрати варіант та

написати програму з виведенням даних у файл: 1. Проаналізувати масив даних з 15 елементів. Підрахувати і

зберегти в комірках пам’яті кількість елементів масиву, якщо їх значення менше або більше 132; кількість елементів масиву, значення яких дорівнюють 132. Вивести відповідні повідомлення.

2. Проаналізувати масив даних з 10 елементів. Додавати елементи масиву доти, поки значення суми не перевищить 512. Зберегти номер елемента, на якому відбулося переповнення. Якщо сума елементів не досягла значення 512, то видати відповідне повідомлення.

3. Проаналізувати масив даних з 16 елементів. Елементами масиву є числа 32, 64, 96 і 128. Підрахувати та вивести на екран кількість повторень кожного елемента.

4. Проаналізувати масив даних з 12 елементів. Створити масив, до якого входять елементи першого масиву, що дорівнюють 128. Перервати виконання програми, якщо буде знайдено 5 елементів зі значенням 128. Вивести відповідні повідомлення.

5. Проаналізувати 2 масиви, що складаються з 15 елементів кожен. Підрахувати кількість елементів першого масиву, що мають рівні значення в другому масиві. Вивести відповідні повідомлення.

6. Проаналізувати масив даних з 14 елементів. Підрахувати кількість елементів, значення яких дорівнює 55h. Рахунок перервати,

Page 309: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

308

якщо кількість елементів перевищить 3. Вивести відповідні повідомлення.

7. Проаналізувати масив даних з 15 елементів. Елементами масиву є числа 10, 20, 30 і 180. Підрахувати кількість повторень кожного елемента. Вивести відповідні повідомлення.

8. Для функції Y = 40Х + 65 видати в комірку пам’яті перше значення аргументу, при якому значення функції перевищить 1024. Початкове значення аргументу Х = 20.

9. Для функції Y = 40Х + 10 одержати перше значення, що перевищує 512, починаючи з Х = 1. Значення аргументу та функції записати в комірки пам’яті.

0. Для функції 7Х + 85 знайти перше значення аргументу, при якому молодші цифри результату виконання функції дорівнюють 155. Результат виконання функції та його аргумент розмістити в комірках пам’яті.

Page 310: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

309

13. СТРУКТУРИ

13.1. Організація структур Масиви є сукупністю однотипних елементів. У додатках виникає

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

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

Для використання структур в програмі необхідно виконати три дії: 1. Задати шаблон структури. Це означає визначити новий тип

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

2. Виконати ініціалізацію конкретної змінної структури (за допомогою шаблону).

3. Організувати звернення до елементів структури. Описати структуру в програмі означає лише вказати її схему або

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

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

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

Опис шаблону структури Опис шаблону структури має такий синтаксис: Ім’я_структури STRUC <опис полів> Ім’я_структури ENDS

Page 311: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

310

Тут <опис полів> є послідовністю директив опису даних db, dw, dd, dq і dt.

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

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

Спочатку розглянемо спрощену програму з використанням

структур. Приклад 13.1. Обчислити суму елементів головної діагоналі

матриці розміром 4 × 4, з використанням даних структурного типу. Як приклад в програмі спеціально використано спрощену

сегментацію з декількома директивами .CODE та .DATA. Транслятор потім збирає код і дані разом.

Листинг 13.1. Програма обчислення елементів головної діагоналі: title CopyRight by Rysovaniy A. N. .386 ; директива визначення типу мікропроцесора

.model flat, stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap:none ; відмінність малих та великих літер DATE1 STRUCT ; визначення даних СТРУКТУРА з іменем DATE1

CarName dw ? ; ім’я першого поля структури Number dw ? ; ім’я другого поля структури Name1 dw ? ; ім’я третього поля структури Viol dw ? ; ім’я четвертого поля структури

DATE1 ENDS ; закінчення даних СТРУКТУРА з іменем DATE1 .data ; директива визначення даних Car1 DATE1 <1,10,2,3> ; структура з іменем Car1 Car2 DATE1 <2,-11,6,7> ; структура з іменем Car2 Car3 DATE1 <3,12,10,11> ; структура з іменем Car3 Car4 DATE1 <4,13,14,15> ; структура з іменем Car4

.code ; директива початку сегмента-даних

Page 312: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

311

start: ; мітка початку програми з ім’ям start xor edx,edx ; заповнювання нулями mov bx,Car1.CarName ; movzx ebx,bx ; заповнювання нулями старшої частини mov dx,Car2.Number ; add edx,ebx ; mov bx,Car3.Name1 ; adc edx,ebx ; mov bx,Car4.Viol ; adc edx,ebx ;

.data ; директива визначення даних res dd ? ; резервування 32-розрядної комірки пам’яті з ім’ям res

.code ; директива початку сегмента-даних mov res,edx ; ret ; повернення керування ОС end start ; директива закінчення програми з іменем start На рис. 13.1 наведено вікна налагоджувача OllyDbg з програмою

листингу 13.1. У програмі листингу 13.1 кожній з чотирьох структур присвоєно

ім’я, а, в свою чергу, кожний елемент структури має теж своє ім’я, яке наведено в структурі DATE1 STRUCT.

Рис. 13.1. Вікна налагоджувача OllyDbg з програмою листингу 13.1.

Page 313: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

312

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

Приклад 13.2. Задано структуру, яка містить поля: день Day,

місяць Month, рік Year. Замість числа місяця вивести скорочену назву. Програму прикладу 13.2 наведено у листингу 13.2. Листинг 13.2. Програма виконання прикладу 13.2: .386 ; директива визначення типу мікропроцесора

.model flat, stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap:none ; відмінність малих та великих літер include \masm32v9_0\include\windows.inc include \masm32v9_0\include\user32.inc include \masm32v9_0\include\kernel32.inc includelib \masm32v9_0\lib\kernel32.lib includelib \masm32v9_0\lib\user32.lib DATE STRUCT ; тип даних СТРУКТУРА

Day DWORD ? Month DWORD ? Year DWORD ?

DATE ENDS DateDisp proto :DATE BSIZE equ 15 ; розмір буфера .data ; директива визначення даних ifmt BYTE "%d",0 ; завдання перетворення одного числа

; у послідовність символів buf BYTE BSIZE dup(0) Date DATE <12,11,2007> ; змінна типу DATE MName BYTE "янв фев мар апр май июн июл авг "

BYTE "сен окт ноя дек" .data? ; не визначені структури даних

stdout DWORD ? ; резервування в пам’яті 32-розрядної комірки ; з ім’ям stdout для збереження дескриптора виведення

cWritten DWORD ? ; резервування 32-розрядної комірки пам’яті

Page 314: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

313

; з ім’ям cWritten для адреси символів виведення .code ; директива початку програми

start: invoke GetStdHandle, STD_OUTPUT_HANDLE mov stdout, eax ; збереження дескриптора invoke DateDisp, Date ; показати дату invoke ExitProcess, 0 ; повернення керування ОС Windows

; та визволення ресурсів DateDisp proc d:DATE

invoke wsprintf, ADDR buf, \ ; адреса буфера, де процедура зберігає

; число у вигляді послідовності символів ADDR ifmt, ; адреса форматного рядка

d.Day ; перетворюване число invoke WriteConsole, stdout, ; дескрип. станд. пристрою виведення

ADDR buf, ; адреса початку повідомлення 3, ; розмір повідомлення (кількість байтів в ньому)

ADDR cWritten, ; адреса ділянки пам’яті, де процедура ; зберігає число виведених на екран символів

NULL mov eax, d.Month ; завантаження поля структури Month (eax = 0Bh) dec eax ; зменшення – тому що нумерація з нуля (0Ah = 10) shl eax, 2 ; умножити на 4 (обчислення кількості байтів: 10 × 4 = 40

mov esi, offset MName ; занесення адреси масиву назв add esi, eax ; обчислення лінійної адреси поля Month

invoke WriteConsole, stdout, esi, 4,\ ADDR cWritten, NULL xor eax, eax

invoke wsprintf, ADDR buf, ADDR ifmt, d[8] invoke WriteConsole, stdout, ADDR buf, 4,\

ADDR cWritten, NULL ret ; повернення з процедури

DateDisp endp ; закінчення процедури з ім’ям DateDisp end start ; закінчення програми Після отримання файла з розширенням .exe та його виконання в

середовищі програми FAR буде отримано надпис, який наведено на рис. 13.2.

Page 315: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

314

Програму після її виконання у вікнах відлагоджувача OllyDBG

наведено на рис. 13.3. В цих вікнах видно процес та порядок виклику API-функцій. Для того щоб прослідкувати виконання програми слід у покроковому режими натискувати кнопку F8, щоб обійти детальне виконання цих функції.

13.2. Лабораторна робота

“Структури”

Мета заняття: – поглибити і закріпити знання з архітектури МП платформи х86 і

навички його програмування; – придбати практичні навички складання, налагодження і

виконання програм з використанням структур, написаних мовою асемблеру МП платформи х86.

Постановка задачі Згідно з останньою цифрою номера в групі вибрати варіант та

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

1. Задано матрицю 3 × 5. Виконати транспонування цієї матриці. Результат виконання програми вивести у вікно консолі.

2. Задано матрицю 3 × 6. Визначити суму елементів під головною діагоналлю. Результат виконання програми вивести у вікно консолі.

Рис. 13.2. Результат виконання програми з листингу 13.2

Page 316: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

315

Рис. 13.3. Програма листингу 13.2 після її виконання у вікнах відлагоджувача OllyDBG

Page 317: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

316

3. Задано матрицю 3 × 4. Визначити рядок з максимальною сумою позитивних елементів. Результат виконання програми вивести у вікно консолі.

4. Задано матрицю 4 × 5. Визначити мінімальний елемент кожного стовпця. Результат виконання програми вивести у вікно консолі.

5. Задано матрицю 3 × 4. Визначити максимальний елемент кожного рядка. Результат виконання програми вивести у вікно консолі.

6. Задано матрицю 4 × 6. Визначити суму елементів кожного стовпця. Результат виконання програми вивести у вікно консолі.

7. Задано матрицю 3 × 6. Визначити рядок з максимальною сумою елементів. Результат виконання програми вивести у вікно консолі.

8. Задано матрицю 3 × 6. Визначити рядок з мінімальною сумою елементів. Результат виконання програми вивести у вікно консолі.

9. Задано матрицю 3 × 6. Визначити елементи кратні 3 в кожному рядку і помістити на їх місце елемент, номер якого збігається з номером рядка. Результат виконання програми вивести у вікно консолі.

0. Задано матрицю 4 × 6. Визначити суму негативних елементів кожного рядка і помістити її на місце першого елемента. Результат виконання програми вивести у вікно консолі.

Зміст звіту 1. Постановка задачі для конкретного варіанта. 2. Блок-схема алгоритму виконання прикладу з детальним

коментарем та описом роботи. 3. Листинг програми та коментарі до всіх команд. 4. Рrint screen екрана 32-розрядного налагоджувача з виконанням

програми та результатами виконання. 5. Висновки за результатами роботи. Приклад 13.3. Задано матрицю 2 × 4. Визначити суму всіх

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

Листинг 13.3. Програма виконання прикладу 13.3: title CopyRight by Rysovaniy A. N. (10_7L.asm) .386 ; директива визначення типу мікропроцесора .model flat, stdcall ; завдання лінійної моделі

пам’яті

Page 318: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

317

; та угоди ОС Windows option casemap:none ; відмінність малих та великих літер include \masm32v9_0\include\windows.inc include \masm32v9_0\include\user32.inc include \masm32v9_0\include\kernel32.inc includelib \masm32v9_0\lib\user32.lib includelib \masm32v9_0\lib\kernel32.lib ExitProcess proto: dword ; прототип API-функції

DATE1 STRUCT ; тип даних СТРУКТУРА з іменем DATE1 elem1 dd ? ; ім’я першого поля структури elem2 dd ? ; ім’я другого поля структури elem3 dd ? ; ім’я третього поля структури elem4 dd ? ; ім’я четвертого поля структури

DATE1 ENDS .data ; директива визначення даних

str1 DATE1 <1,-1,-2,3> ; структура з іменем str1 str2 DATE1 <0,-2,-1,-3> ; структура з іменем str2 st1 db " amount of negative elements ",0 st2 db 10 dup(?),0 ifmt db "%d",0

.code ; директива початку сегмента-даних start: ; мітка початку програми з ім’ям start

xor edx,edx ; заповнювання нулями mov ebx,2 ; завантаження кількості рядків lea esi,str1 ; завантаження адреси першого рядка структури

m5: mov ecx,4 ; кількість елементів у рядку m3: mov eax,[esi] ; завантаження елемента з рядка структури

add eax,0 ; визначення ознак елемента js m1 ; перейти на m1, якщо елемент негативний jmp m2 ; безумовний перехід, якщо навпаки

m1: add edx,eax ; додавання негативних елементів рядка структури m2: add esi,4 ; підготовка адреси нового елемента

loop m3 ; есх := ecx – 1 та перехід на m3, якщо не нуль dec ebx ; ebx := ebx – 1 jz m4 ; якщо ebx = 0 (z = 1), то перехід на закінчення lea esi,str2 ; завантаження адреси нового рядка jmp m5 ; перехід на новий цикл

Page 319: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

318

m4: invoke wsprintf, \ ; АРІ-функція перетворення числа ADDR st2, \ ; адреса буф., куди буде записана послід. символів ADDR ifmt, \ ; адреса рядка перетворення формату edx ; регістр, вміст якого перетворюється

invoke MessageBox, \ ; АРІ-функція виведення вікна консолі NULL, \ ; hwnd – ідентифікатор вікна addr st2, \ ; адреса рядка, яка містить текст повідомлення addr st1, \ ; адреса рядка, яка містить заголовок повідомлення MB_OK ; вид діалогового вікна

invoke ExitProcess, 0 ; повернення керування ОС Windows

; та визволення ресурсів end start ; директива закінчення програми з іменем start Результат виконання програми з листингу 8.6 наведено на рис. 13.4. У результаті виконання програми отримується число -9, яке

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

Рис. 13.4. Вікно з результатом виконання програми з листингу 13.3

Page 320: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

319

14. ДИНАМІЧНІ БІБЛІОТЕКИ

14.1. Створення динамічних бібліотек та їх використання

Операційна система Windows і всі її драйвери (окрім віртуальних), а також інші розширення в деякому розумінні є не чим іншим, як набором бібліотек динамічного компонування. Жоден крупний додаток Windows не обходиться без власних бібліотек динамічного компонування, і жодне застосування не може обійтися без виклику функцій, розташованих в таких бібліотеках. Зокрема, всі функції програмного інтерфейсу Windows знаходяться саме в бібліотеках динамічного компонування DLL (Dynamic-link Libraries ).

Для звернення до зовнішніх по відношенню до програм модулів операційної системи MS-DOS і модулів BIOS використовується механізм програмних переривань. У будь-який момент часу в оперативній і постійній пам’яті комп’ютера знаходиться весь код, необхідний для роботи як програми, так і самої операційної системи MS-DOS.

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

У середовищі мультизадачної операційної системи, такі як Windows, OS/2 або UNIX, статичне компонування неефективне, оскільки воно призводить до неекономного використання дуже дефіцитного ресурсу – оперативної пам’яті.

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

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

Page 321: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

320

Для того щоб були зрозумілі відмінності між додатком і DLL-бібліотекою, уточнимо такі поняття, як завдання (task), копія додатка (instance) і модуль (module).

Коли запускаються декілька копій одного застосування, Windows завантажує в оперативну пам’ять тільки одну копію коду і ресурсів. Для кожної копії додатка створюється окремий сегмент даних, стік і черга повідомлень.

Коли запускаються декілька копій одного застосування, Windows завантажує в оперативну пам’ять тільки одну копію коду та ресурсів. Для кожної копії додатка створюється окремий сегмент даних, стек і черга повідомлень.

Завдання (task) можна розглядати як сукупність віртуального процесора і ресурсів, таких як стек, регістри процесора, глобальна пам’ять, черга повідомлень і так далі. В операційній системі Windows є база даних запущених завдань, в якій зберігається вся інформація, що відноситься до завдання, наприклад, ідентифікатор додатка, ідентифікатор модуля додатка і так далі.

Копія додатка (instance) є контекстом, в якому виконується модуль додатка. Ідентифікатор копії додатка, який отримується через параметр hinstance функції Winmain, є ідентифікатором сегмента даних DGROUP, використовуваного при виконанні програмного модуля.

Модуль додатка (module) складається із виконавчого коду та ресурсів. Усередині Windows є база даних модулів, в якій зберігається така інформація, як посилання на функції, що експортуються, розташування сегментів коду та сегментів, що містять ресурси. Оскільки модуль додатка не змінюється (сегменти коду та ресурсів не змінюються), всі запущені копії одного застосування можуть ними користуватися.

DLL-бібліотека також є модулем. Вона знаходиться в пам’яті в єдиному екземплярі, містить сегменти коду та ресурси, а також один сегмент даних. Можна сказати, що для DLL-бібліотеки створюється одна копія (instance), що складається тільки з сегмента даних, і один модуль, що складається з коду та ресурсів.

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

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

Page 322: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

321

Використання DLL-бібліотек підвищує модульність додатків і самої операційної системи Windows. З погляду додатка DLL-бібліотека є не більше ніж набором функцій з тим або іншим інтерфейсом, а також, можливо, набором ресурсів. Внутрішня побудова і алгоритми роботи функцій, а також використовувані функціями структури даних повністю приховані від додатка. Тому при внесенні змін або удосконалень до DLL-бібліотеки немає необхідності виконувати повторне збирання додатків (якщо не змінився інтерфейс або набір функцій, що входять в бібліотеку).

Для створення своєї динамічної бібліотеки з файлом myio.dll

необхідно виконати кроки. Крок 1. З програми, яка має процедуру, видалити мітку та в кінці –

директиву end start, так, як наведено у листингу 14.1. Листинг 14.1:

; файл myio.asm .386 ; директива визначення типу мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті

; та угоди ОС Windows option casemap:none ; відмінність малих та великих літер includelib\masm32v9_0\lib\kernel32.lib ExitProcess proto :DWORD AddDD proto :DWORD, :DWORD ; прототип процедури

.code ; директива початку сегмента-даних AddDD proc arg1:DWORD,arg2:DWORD mov eax,[esp+8] ; add eax,[esp+12] ; ret ; повернення керування ОС AddDD endp ; закінчення процедури з ім’ям AddDD end ; закінчення програми з ім’ям start Крок 2. Створити файл з розширенням .def, на основі змісту якого

асемблер узнає точку входу в процедуру (функцію). Файл myio.def буде таким, як у листингу 14.2.

Листинг 14.2. Файл myio.def: LIBRARRY myio EXPORTS AddDD 3,4

Page 323: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

322

Крок 3. Необхідно створити командний файл для створення файла dll-бібліотеки, такий, як у листингу 14.3.

Листинг 14.3. Командний bat-файл з ім’ям, наприклад

atake_2.bat, для створення файла dll: ml /c /coff "myio.asm" link /DLL /DEF:myio.def /NOENTRY "myio.obj" Файли myio.asm, myio.def та командний файл необхідно

розмістити в одну папку. В результаті таких дій створюється файл myio.dll. Разом з цим файлом транслятор створює й файл з розширеннями .exp.

Програму, що використовує процедуру з myio.dll-файла, яка має ім’я, наприклад mydll.asm, наведено в листингу 14.4,.

Листинг 14.4. Програма з іменем mydll.asm: .386 ; директива визначення типу мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті

; та угоди ОС Windows option casemap:none ; відмінність малих та великих літер includelib\masm32v9_0\lib\kernel32.lib includelib myio.lib ExitProcess proto :DWORD AddDD proto :DWORD, :DWORD ; прототип процедури

.code ; директива початку сегмента-даних start: ; мітка початку програми з ім’ям start

invoke AddDD,5,4 ; виклик директиви AddDD з параметрами invoke ExitProcess,0

end start ; директива закінчення програми з ім’ям start Усі програми, які були створені та використовувались при викликах

dll-функції, відображено у вікні файлового менеджера (рис. 14.1). Процес виклику особистого dll-файла та обчислення результату

виконання програми наведено на рис. 14.2. Програма з листингу 14.4 викликає процедуру, яка наведена у

листингу 14.3. Результат додавання 4 + 5 = 9 зберігається у регістрі EAX.

Page 324: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

323

14.2. Угорська нотація

Деякі змінні в іменах мають малі букви. Це не що інше як

виконання угорської нотації, що була прийнята при програмуванні під Windows на честь легендарного програміста Microsoft Чарльза Симоні. Суть цієї нотації полягає в тому, що ім’я змінної починається з малої букви або букв, які відзначають тип даних змінної. Наприклад, префікс sz в szCmdLine означає, що рядок завершується нулем (s tring te rmina ted by zero). Преф ікс h в hInstance і hPrevInstance означає описувач (handle); преф ікс i в iCmdShow означає ціле (integer).

Рис. 14.1. Програми, які використовувались при створені та виклику dll-функції

Рис. 14.2. Процес виклику особистого dll-файла та обчислення результату виконання програми з листингу 14.4

Page 325: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

324

Угорська нотація допомагає уникати помилок в програмі ще до її компонування. Оскільки ім’я змінної описує і саму змінну і тип її даних, то набагато знижується вірогідність введення в програму помилок, пов’язаних з розбіжністю типу даних у змінних.

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

Таблиця 14.1

Префікс Тип даних c Символ by BYTE (беззнаковий символ) n Коротке ціле i Ціле x, y Ціле (координати x та y) cx, cy Ціле (довжина x та y), с позначає "рахунок" — (count) b або f BOOL (булеве ціле); f позначає "прапорець" — (flag) w WORD (беззнакове коротке ціле) l LONG (довге ціле) dw DWORD (беззнакове довге ціле) fn Функція s Рядок sz Рядок із завершенням нулем h Описувач (handle) p Вказівник (pointer)

14.3. Лабораторна робота “Dll-файли”

Мета заняття: – поглибити і закріпити знання з архітектури МП платформи х86 і

навички його програмування; – придбати практичні навички складання, налагодження і

виконання програм з використанням Dll-файлів, написаних мовою асемблеру для програмування МП платформи х86.

Постановка задачі Згідно з останньою цифрою номера в групі вибрати варіант та

написати програму на асемблері обчислення одного з виразів:

Page 326: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

325

1. Задано масив А з N = 5 елементів. Навести алгоритм та програму визначення кількості елементів масиву А, які задовольняють умову L < Ai ≤ M, де L = 2 та M = 10.

2. Задано масив А з N = 6 елементів. Навести алгоритм та програму визначення кількості елементів масиву А, які задовольняють умову L ≤ Ai < M, де L = 3 та M = 15.

3. Задано масив А з N = 7 елементів. Навести алгоритм та програму визначення кількості елементів масиву А, які задовольняють умову L < Ai < M, де L = 4 та M = 18.

4. Задано масив А з N = 8 елементів. Навести алгоритм та програму визначення кількості елементів масиву А, які задовольняють умову L ≤ Ai ≤ M, де L = 5 та M = 20.

5. Задано масив А з N = 9 елементів. Навести алгоритм та програму визначення кількості елементів масиву А, які задовольняють умову L ≥ Ai > M, де L = 6 та M = 22.

6. Задано масив А з N = 10 елементів. Навести алгоритм та програму визначення кількості елементів масиву А, які задовольняють умову L > Ai ≥ M, де L = 7 та M = 24.

7. Задано масив А з N = 5 елементів. Навести алгоритм та програму визначення кількості елементів масиву А, які задовольняють умову L > Ai > M, де L = 8 та M = 28.

8. Задано масив А з N = 7 елементів. Навести алгоритм та програму визначення кількості елементів масиву А, які задовольняють умову L ≥ Ai ≥ M, де L = 9 та M = 30.

9. Задано масиви А і В по N = 8 елементів. Навести алгоритм та програму сформування масиву С за правилом: якщо Аi ≤ Вi, то Сi = Аi + Вi; інакше – Сi = Аi – Вi.

0. Задано масиви А і В по N = 9 елементів. Навести алгоритм та програму формування масиву С за правилом: якщо Аi ≤ Вi, то Сi = Вi – Аi; інакше – Сi = Аi + Вi.

Зміст звіту 1. Постановка задачі для конкретного варіанта. 2. Блок-схема алгоритму виконання прикладу з детальним

коментарем та описом роботи. 3. Листинг програми та коментарі до всіх команд. 4. Рrint screen екрана 32-розрядного налагоджувача з виконанням

програми та результатами виконання. 5. Висновки за результатами роботи.

Page 327: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

326

15. СПІВПРОЦЕСОР ТА ЙОГО ВИКОРИСТАННЯ

Арифметичний співпроцесор призначений для виконання операцій над числами у форматі з плаваючою крапкою (дійсні числа) і довгими цілими числами. Він значно (у десятки разів) прискорює обчислення, пов’язані з дійсними числами. Співпроцесор може обчислювати такі функції, як синус, косинус, тангенс, логарифми і т. д. За допомогою співпроцесора можна виконувати і прості арифметичні операції складання, віднімання, множення і ділення.

Основна область застосування арифметичного співпроцесора – наукові розрахунки і машинна графіка.

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

Співпроцесор запускається центральним процесором. Після запуску він виконує всі обчислення самостійно і паралельно з роботою центрального процесора. Якщо центральний процесор видає чергову команду співпроцесору у момент часу, коли той ще не закінчив виконання попередньої команди, центральний процесор переводиться в стан очікування. Якщо ж співпроцесор нічим не зайнятий, центральний процесор, видавши команду співпроцесору, продовжує свою роботу, не чекаючи завершення обчислення. Існують спеціальні засоби синхронізації пристроїв (команда FWAIT).

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

Асемблерні мнемоніки всіх команд співпроцесора починаються з букви F, наприклад: FADD, FDIV, FSUB і тощо. Команди співпроцесора можуть адресуватися до операндів, аналогічно звичайним командам центрального процесора. Для команд арифметичного співпроцесора

Page 328: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

327

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

15.1. Типи даних співпроцесора

До форматів даних співпроцесора відносяться: – цілі двійкові числа розрядністю 16, 32 і 64 біт; – упаковані цілі десяткові (BCD) числа розміром до 9 байт; – дійсні числа в короткому (32 біти), довгому (64 біти) і

розширеному (80 біт) форматах. Межі змінення даних у цих форматах наведено у табл. 15.1.

Таблиця 15.1 Межі змінення даних FPU

Тип даних Біт Кількість значущих цифр

Межі

Ціле слово 16 4 – 32 768 – 32 767 Коротке ціле 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

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

яких відносяться: – денормалізовані дійсні числа; – нуль; – позитивні і негативні значення нескінченності; – не-числа; – різного роду невизначеності формати.

Співпроцесор має єдине внутрішнє подання даних і зберігає всі

числа в єдиному 80-розрядному розширеному форматі. Цей формат відповідає формату регістрів стека співпроцесора. Будь-які операнди, подані у вигляді 16-, 32- і 64-розрядних цілих чисел, 32-, 64- або 80-розрядних чисел з плаваючою крапкою, а також упакованих BCD-чисел, зображені 18 цифрами, при завантаженні в регістри співпроцесора

Page 329: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

328

автоматично переводяться в розширений формат. Результати обчислень переводяться назад в один з цих форматів даних і зберігаються в регістрах або пам’яті.

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

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

Дійсні числа можуть мати розмірність 32, 64 або 80 біт. При записі дійсних чисел завжди виконують нормалізацію –

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

При використанні цього алгоритму перша цифра мантиси завжди дорівнює 1, тому її можна не писати, збільшуючи тим самим точність подання числа додатково на 1 біт. Крім того, значення експоненти зберігають не у вигляді цілого із знаком, а у вигляді суми з деяким числом так, щоб завжди зберігати тільки позитивне число і щоб було легко порівнювати дійсні числа – в більшості випадків досить порівняти експоненту.

Для подання 32-розрядних дійсних чисел використовується директива DD, а для 64-розрядних – DQ.

До не-чисел (Non-A-Number, NAN) відносяться послідовності бітів, які не можна зіставити з жодним форматом. До спеціальних числових значень відносять нуль і нескінченність. Значення “нуль” може, наприклад, бути результатом роботи команд з нульовими операндами. У перелік спеціальних числових значень входять і так звані денормалізовані числа. Це числа, що виходять за межі діапазону даного формату і наближаються до нуля.

15.2. Архітектура співпроцесора

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

типів даних і команд. До групи регістрів співпроцесора входять: – вісім 80-розрядних регістрів, що окремо адресуються,

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

Page 330: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

329

– три службові 16-розрядні регістри: регістр стану swr (Status Word Register) співпроцесора; регістр cwr (Control Word Register); регістр тегів twr (Tags Word Register);

– регістри-вказівники даних dpr (Data Point Register) і команд ipr (Instruction Point Register), які використовуються при обробці виняткових ситуацій.

Кожний з восьми числових регістрів в стеку має розмір 80 біт і складається з окремих полів, відповідно до розширеного дійсного типу даних (рис. 15.1).

Команди співпроцесора адресують регістри даних щодо регістра,

стека, що є вершиною. У будь-який момент часу номер цього регістра міститься в полі top регістра стану (swr) співпроцесора.

Регістр стану (swr) містить інформацію про поточний стан

співпроцесора. Деякі найбільш важливі поля наведено на рис. 15.2. Поля с3-с0 регістра встановлюються певним чином після

виконання математичних операцій і є аналогом прапорців в регістрі прапорців EFLAGS основного процесора. Поля 13-11 містять поточний номер регістра стека (R0 – R7), що є в даний момент вершиною.

Слово стану регістра swr збігається в пам’яті за допомогою команд fstsw/fnstsw, fstenv/fnstenv і fsave/fnsave, після чого його можна передати в регістр АХ за допомогою команд fstsw AX/fnstsw AX, дозволяючи програмі перевірити слово стану співпроцесора.

Рис. 15.1. Регістровий стек співпроцесорів

79 78 64 63 0 1 0 R0 R1 R2 R3 R4 R5 R6 R7

Знак Порядок Мантиса Регістр тегів 1 розряд 15 розрядів 64 розряди

Page 331: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

330

Команда sahf може копіювати поля с3 – с0 безпосередньо в біти

прапорців процесора, що спрощує організацію галужень і умовних переходів в програмах.

Регістр тегів (twr) розподіляється на вісім двобітових полів. Кожне

поле відноситься до свого чисельного регістра (рис. 15.3).

TAG0 TAG1 TAG2 TAG3 TAG4 TAG5 TAG6 TAG7

Рис. 15.3. Формат регістра тегів

Поля регістра тегів (twr) класифікують вміст "свого" чисельного регістра, опис якого наведено в табл. 15.2.

Таблиця 15.2 Поле Опис

00 Регістр містить дійсне ненульове число 01 У регістрі знаходиться нуль 10 Регістр містить недійсне число – не-число, нескінченність,

невизначеність 11 Порожній неініціалізований регістр

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

в стек чисельних регістрів було занесене одне дійсне ненульове значення, вміст регістра тегів буде 3FFFh. Дані полів тегів відображають стан фізичних регістрів R0 – R7, а не логічних st(0) – st(7). Для отримання повної інформації про стан регістрів стека потрібно буде використовувати поле top регістра стану (swr).

с3 с2 с1 с0 15 14 13 12 11 10 9 8 7 0

Рис. 15.2. Регістр стану (swr) співпроцесора

top

Status Wurd Registr (swr)

Page 332: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

331

Для встановлення режимів обробки даних співпроцесора служить регістр керування (cwr) (рис. 15.4). Він включає шість масок виключень, поля керування точністю (precision control, рс) і поля керування округленням (rounding control, re).

За допомогою бітів поля рс вибирається довжина мантиси: 00 – довжина мантиси дорівнює 24 біт; 10 – довжина мантиси дорівнює 53 біт; 11 – довжина мантиси дорівнює 64 біт. Далі показано можливі комбінації поля гс: – 00 – число, що міститься в стеку st(0) співпроцесора,

округляється до найближчого цілого значення; 01– число в st(0) округляється в меншу сторону; 10 – число в st(0) округляється у більшу сторону; 11 – відкидається дробова частина числа. Маски призначено для маскування виняткових ситуацій,

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

При виникненні помилки процесор намагається порушити переривання за особливою ситуацією, встановлюючи відповідні біти в слові стану. Проте якщо ситуація замаскована за допомогою керуючого слова (співпроцесор сам реагує на неї).

p u o z d i 15 12 11 10 9 8 7 6 5 4 3 2 1 0

Рис. 15.4. Регістр стану керування (сwr)

Точність

pc rc

Переповнення негативне Переповнення Ділення на 0 Ненормалізований операнд Неприпустима операція

Page 333: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

332

Біти керування точністю (біти 8 – 9) можуть бути використані для того, щоб встановити меншу точність внутрішніх операцій пристрою, ніж точність, задана за умовчанням (розмір мантиси дорівнює 64 бітам).

15.3. Система команд математичного співпроцесора

Команди з плаваючою крапкою можна згрупувати в класи: – команди передачі даних; – команди порівняння; арифметичні команди; – трансцендентні команди; – команди маніпуляції константами; – команди керування.

Формати команд співпроцесора х87 аналогічні форматам команд

х86. Асемблерні мнемоніки команд співпроцесора починаються з букви F (Floating).

Друга буква I (Integer) позначає операцію з цілим двійковим числом з пам’яті, буква B (Binari-coded decimal) – операцію з десятковим операндом з пам’яті, а друга буква визначає операцію з дійсними числами.

Передостання або остання буква R указує зворотну операцію (для віднімання і ділення).

Остання буква P (Pop) ідентифікує команду, завершальною дією якої є витягання із стека.

У командах неявно указується чисельний регістр співпроцесора, що адресується вершиною стека st або st(0) (Stack Top).

Чисельні регістри адресуються щодо вершини стека. Наприклад, команда

fadd st(0),st(4) додає вміст четвертого регістра від вершини стека до вмісту верхнього регістра стека.

Верхній регістр стека можна позначити st або st(0). Наприклад, команда

fadd st(0),st(0) додає вміст верхнього регістра стека до нього ж, тобто подвоює вміст регістра st(0).

Для операндів в пам’яті допускаються всі режими адресації процесора х86, наприклад:

Page 334: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

333

fadd [bx] fadd name [bx] [si]

У командах FPU не використовується безпосередня адресація операндів.

15.3.1. Команди передачі даних

Команди передачі даних передають дані між регістрами стека і

пам’яттю. Ці команди можна розділити на три групи: – команди передачі чисел з плаваючою крапкою; – команди передачі цілих чисел; – команди передачі десяткових чисел. Команди передачі даних автоматично оновлюють регістр стану

співпроцесора. Розглянемо команди передачі даних у форматі дійсних чисел: fld операнд-дж ерело – завантажує дійсне число з елемента

пам’яті, поданої операндом-джерелом, у вершину стека співпроцесора; fst операнд-приймач, fstp операнд-приймач – команди

зберігають дійсне число з вершини стека в пам’яті. Крім того, команда fstp ще виштовхує операнд із стека, збільшуючи тим самим значення top на 1. В цьому випадку вершиною стека стає фізичний регістр з великим номером.

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

fild операнд-дж ерело – завантажує число з елемента пам’яті, поданої операндом-джерелом, у вершину стека;

fist операнд-приймач, fistp операнд-приймач – зберігають ціле число з вершини стека в пам’яті. Єдина відмінність двох команд полягає в тому, що команда flstp ще виштовхує операнд із стека, збільшуючи тим самим значення top на 1. В цьому випадку вершиною стека стає фізичний регістр з великим номером.

Команди передачі даних, поданох в десят ковому форматі: fbld операнд-дж ерело – завантажує число з елемента пам’яті,

поданої операндом-джерелом, у вершину стека; fbstp операнд-приймач – зберігає ціле число з вершини стека в

пам’яті і виштовхує операнд із стека, збільшуючи тим самим значення top на 1. В цьому випадку вершиною стека стає фізичний регістр з великим номером.

Page 335: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

334

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

1. У регістр керування (cwr) поміщається число 37h, яке означає, що округлення виконуватиметься до найближчого цілого (поле rc = 0).

2. Біти з нульового по п’ятий встановлюються в 1, що означає маскування всіх виключень.

3. Поле керування точністю встановлюється для роботи з максимальною точністю в 64 біт (рс =11).

4. Регістр стану (swr) обнуляється, а це означає, що виключення відсутні і фізичний регістр R0 регістрового стека стає вершиною стека st(0).

5. У регістр тегів (twr) заносяться одиниці, а це означає, що всі регістри співпроцесора вважаються порожніми.

6. Регістри вказівників даних (dpr) і команд (ipr) обнуляються. До команд пересилання відноситься також команда fxch st(i), яка

обмінює значення у вершині стека співпроцесора і регістра st(i). Приклад 15.1. Перемістити п’ять дійсних числа з одного масиву

пам’яті в інший. Програму розв’язання вирішення прикладу 15.1 наведено у

листингу 15.1. Листинг 15.1. Програма розв’язання прикладу 15.1: title CopyRight by Rysovaniy A. N. .686 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap: none ; відмінність малих та великих літер ExitProcess proto: dword ; прототип API-функції includelib \masm32v9_0\lib\kernel32.lib

.data ; директива визначення даних mas1 DD 129.235, -1024.01, -12.5, 5.06, 67895.025

len EQU $- mas1 ; обчислення кількості байтів елементів масиву mas1 mas2 DD len DUP(0) ; резервування len комірок пам’яті для mas2 .code ; директива початку коду програми

start: ; мітка початку програми finit ; ініціювання співпроцесора

Page 336: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

335

mov ECX, len ; занесення len = 20 – кількості байтів масиву mas1 shr ECX, 2 ; ділення на 4 – визначення кількості чисел lea ESI, mas1 ; занесення адреси початку масиву lea EDI, mas2 ; занесення адреси початку масиву

next: fld dword ptr [ESI] ; занесення в вершину стека з [ESI] fstp dword ptr [EDI] ; занесення з вершини стека в пам’ять

; за адресою, яка знаходиться в EDI add ESI, 4 ; вирівнювання на межу подвійного слова масиву mas1 add EDI, 4 ; вирівнювання на межу подвійного слова масиву mas2

dec ECX ; зменшення лічильника jnz next ; перейти, якщо не нуль

invoke ExitProcess, 0 ; повернення керування ОС windows ; та визволення ресурсів

end start ; директива закінчення програми з ім’ям start Вікна налагоджувача при першому проходженні циклу програми з

листингу 15.1 наведено на рис. 15.5.

Рис. 15.5. Вікна налагоджувача при виконанні програми з листингу 15.1

Page 337: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

336

У вікні регістрів (Registers) можна бачити, що перше число з масиву mas1 заноситься у вершину стека st(0). В комірках пам’яті, починаючи з адреси 00403000, наведено п’ять чисел масиву mas1 розміром подвійного слова, які після виконання програми перемістяться у масив mas2.

Приклад 15.2. Заповнити масив конкретним значенням. Програму розв’язання прикладу 11.2 наведено у листингу 15.2. Листинг 15.2. Програма вирішення прикладу 15.2: .686 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap: none ; відмінність малих та великих літер ExitProcess proto: dword ; прототип API-функції includelib \masm32v9_0\lib\kernel32.lib

.data ; директива визначення даних dig DD 2.25 ; число 2.25 з іменем dig подвійного формату mas1 DD 8 DUP (12345678h) ; першочергове заповнення масиву len EQU $-mas1 ; обчислення кількості байтів масиву mas1 .code ; директива початку коду програми

start: ; мітка початку програми finit ; ініціювання співпроцесора mov ECX, len ; занесення кількості байтів масиву mas1 shr ECX, 2 ; ділення на 4 – визначення кількості чисел lea ESI, mas1 ; занесення адреси початку масиву mas1 fld dword ptr dig ; занесення числа dig у вершину стека

next: fst dword ptr [ESI] ; занесення в вершину стека з [ESI]

add ESI, 4 ; вирівнювання на межу подвійного слова масиву mas1 dec ECX ; зменшення лічильника jnz next ; перейти, якщо не нуль fincstp ; очищення вершини стека

invoke ExitProcess, 0 ; повернення керування ОС windows ; та визволення ресурсів

end start ; директива закінчення програми з ім’ям start Програма з листингу 15.2 виконує заповнення комірок пам’яті, які

раніше (директивами визначення даних) були визначені. У даному

Page 338: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

337

випадку вони були визначені константою 12345678h. Комірки пам’яті з цією константою можна побачити у вікнах налагоджувача (рис. 15.6).

В цих вікнах показано момент занесення константи у вершину

стека (в регістр st(0)) командою fld dword ptr dig.

15.3.2. Команди порівняння У центральному процесорі команди умовних переходів

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

fcom – порівнює вміст вершини стека st(0) з вмістом регістра st(1);

fcomp mem –порівнює вміст вершини стека st(0) з операндом пам’яті mem, після чого виштовхує число з st(0) і збільшує вказівник вершини стека на 1 в полі top регістра swr. Операнд mem може бути 32- або 64-розрядним числом з плаваючою крапкою;

Рис. 15.6. Вікна налагоджувача при виконанні програми з листингу 15.2

Page 339: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

338

fcompp – порівнює вміст вершини стека st(0) з вмістом регістра st(1), після чого виштовхує із стека значення, що знаходяться в регістрах st(0) і st(1);

flcom – порівнює цілочисельні значення st(0) і st(1); ficomp mem –порівнює вміст вершини стека st(0) і операнда

пам’яті mem, після чого виштовхує число з st(0) і збільшує вказівник вершини стека на 1 в полі top регістра swr. Операнд mem може бути 16- або 32-розрядним цілим;

ftst –- порівнює вміст вершини стека st(0) з нулем; fxam –аналізує операнд, що знаходиться у вершині стека

співпроцесора і за результатом такого аналізу встановлює біти c0-с3 спеціальним чином.

Команди порівняння встановлюють біти коду умови в регістрі swr

(табл. 15.3). Таблиця 15.3

Коди умов команди fcom c3 c2 c1 c0 Значення 0 0 ? 0 st(0) більше операнда 0 0 ? 1 st(0) менше операнда 1 0 ? 0 st(0) дорівнює операнду 1 1 ? 1 st(0) та операнд непорівнянні

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

порівняння звичним способом, використовуючи бітові прапорці регістра прапорців процесора. Для цих цілей до складу системи команд співпроцесора включена команда fstsw, що дозволяє зберегти слово стану в регістрі АХ або в елементі пам’яті. Командою sahf вміст регістра АН записується в молодший байт регістра прапорців. При цьому біт с0 поміщається на місце прапорця CF, біт с2 – на місце прапорця PF, біт с3 – на місце ZF, а біт c1 не використовується.

Приклад 15.3. Знайти максимальне число з двох та зберегти його у

пам’яті. Програму розв’язання прикладу 15.3 наведено у листингу 15.3. Листинг 15.3. Програма вирішення прикладу 15.3: .686 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті

Page 340: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

339

; та угоди ОС Windows option casemap: none ; відмінність малих та великих літер

ExitProcess proto: dword ; прототип API-функції includelib \masm32v9_0\lib\kernel32.lib

.data ; директива визначення даних

dig1 DD 2.25 ; подвійне число 2,25 з іменем dig1 dig2 DD 2.26 ; подвійне число 2,26 з іменем dig2 res DD 0 ; резервування пам’яті з іменем res

.code ; директива початку коду програми start: ; мітка початку програми

finit ; ініціювання співпроцесора fld dword ptr dig1 ; занесення в вершину стека числа dig1 fld dword ptr dig2 ; занесення в вершину стека числа dig2

fcom ; порівняння вмісту вершини стека st(0) з вмістом регістра st(1) fstsw AX ; зберегти слово стану в регістрі АХ sahf ; завантажити прапорці стану з АН jnc m1 ; перейти, якщо CF = 0 [st(0) > st(1)] fxch st(1) ; обміняти місцями вершину стека st(0) з st(1)

fstp res ; зберегти вершину стека st(0) в комірці пам’яті з ім’ям res

jmp m2 ; безумовний перехід на m2 m1: fstp res ; зберегти вершину стека st(0) в комірці пам’яті з ім’ям res m2: invoke ExitProcess, 0 ; повернення керування ОС Windows

; та визволення ресурсів end start ; директива закінчення програми з ім’ям start

У вікнах налагоджувача видно (рис. 15.7), що перше початкове

число розміщується у комірці пам’яті за номером 0040300h, друге число – за номером 00403004h, а результат виконання програми – за номером 00403008h.

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

Page 341: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

340

Для порівняння операнда з вершини стека з нулем призначеноа команду ftst. Після її виконання коди умов встановлюються відповідно до табл. 15.4.

Таблиця 15.4 с3 → zf с0 → cf Умова

0 0 st(0) > 0 0 1 st(0) < 0 1 0 st(0) = 0 1 1 st(0) та 0 не порівнюються

Приклад 15.4. Найти в масиві подвійних чисел негативні елементи

та записати їх в новий масив. Алгоритм розв’язання прикладу 15.4 наведено на рис. 15.8. Програму розв’язання прикладу 15.4 наведено у листингу 15.4.

Рис. 15.7. Вікна налагоджувача при виконанні програми з листингу 15.3

Page 342: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

341

Листинг 15.4. Програма розв’язання прикладу 15.4: title CopyRight by Rysovaniy A. N. .686 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap: none ; відмінність малих та великих літер ExitProcess proto: dword ; прототип API-функції includelib \masm32v9_0\lib\kernel32.lib

.data ; директива визначення даних

mas1 DD -12.25, 25.05, -8.1, 12.01 len equ $-mas1 ; обчислення кількості байтів масиву mas1 mas2 DD 4 dup(0) ; резервування комірок пам’яті

.code ; директива початку коду програми start: ; мітка початку програми

mov ecx,len ; занесення кількості байтів масиву mas1 shr ecx,2 ; ділення на 4 – визначення кількості чисел lea esi,mas1 ; занесення адреси початку масиву mas1 lea edi,mas2 ; занесення адреси початку масиву mas2

ecx := len

ecx := ecx/4

esi := адр mas1

edi := адр mas2

Ініціал. FPU

st(0) ← [esi]

st(0) – 0

flags := ax

Z = 0 ?

CF = 1 ?

Початок

st(0) → [edi]

edi + 4

esi + 4

еcx – 1

ecx = 0 ?

Закінчення

Рис. 15.8. Алгоритм вирішення прикладу 15.4

Ні

Ні

Ні

Page 343: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

342

finit ; ініціювання співпроцесора m4:

fld dword ptr [esi] ; занесення в вершину стека числа з [esi] ftst ; порівняння операнда з st(0) з нулем fstsw ax ; зберегти слово стану в регістрі ах sahf ; завантажити прапорці стану з АН у flags[l] jnz m1 ; перехід на m1, якщо не нуль jmp m3 ; безумовний перехід на m3

m1: jc m2 ; перехід на m2, якщо є перенесення jmp m3 ; безумовний перехід на m3

m2: fst dword ptr [edi] ; занесення з вершини стека в пам’ять ; за адресою, яка знаходиться в EDI

add edi,4 ; вирівнювання на межу подвійного слова масиву mas2 m3: add esi,4 ; вирівнювання на межу подвійного слова масиву mas1

dec ecx ; зменшення лічильника jnz m4 invoke ExitProcess, 0 ; повернення керування ОС Windows

; та визволення ресурсів end start ; директива закінчення програми з ім’ям start

Вікна налагоджувача після виконання програми та вміст комірок

пам’яті наведено на рис. 15.9. В якості прикладу програма з листингу 15.4 складена так, щоб

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

Починаючи з процесора Intel Pentium Pro, група команд порівняння поповнилася двома новими командами: fcomi і fcomip. Ці команди виконують ті ж операції, що і fcom і fcomp, але на відміну від останніх не вимагають спеціальних команд для обробки бітів с0 – с3 регістра swr, а встановлюють прапорці ZF, CF і PF безпосередньо в регістрі прапорців EFLAGS центрального процесора.

В Pentium Pro включено команди, які можна позначити як fcmovCC, де СС – мнемонічне позначення коду умови (b, nb, e, ne, be, nbe). Ці команди виконують копіювання регістра st(і) в регістр st(0), якщо виконується вказана в команді умова.

Формати команд і аналізовані ними прапорці наведені в табл. 15.5.

Page 344: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

343

Таблиця 15.5

Формати команд fcmovCC Мнемоника Прапорці Умова встановлення прапорця fcmovb CF = 1 Якщо менше fcmovnb CF = 0 Якщо не менше fcmove ZF = 1 Якщо дорівнює fcmovne ZF = 0 Якщо не дорівнює fcmovbe (CF или ZF) = 1 Якщо менше або дорівнює fcmovnbe (CF или ZF) = 0 Якщо не менше або не дорівнює

Приклад 15.5. Виконати попарне порівняння двох масивів

розміром у 4 подвійних слова та записати більше число у новий масив. Програму розв’язання прикладу 15.5 наведено у листингу 15.5.

Рис. 15.9. Вікна налагоджувача після виконання програми з листингу 15.4

Page 345: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

344

Листинг 15.5. Програма розв’язання прикладу 15.5: title CopyRight by Rysovaniy A. N. .686 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap: none ; відмінність малих та великих літер ExitProcess proto: dword ; прототип API-функції includelib \masm32v9_0\lib\kernel32.lib

.data ; директива визначення даних mas1 DD -25.25, 10.05, -10., 1.01 len equ $-mas1 ; обчислення кількості байтів масиву mas1 mas2 DD -2., 10.06, -21., 2. mas3 DD 4 dup(0) ; резервування комірок пам’яті

.code ; директива початку коду програми start: ; мітка початку програми

mov ecx,len ; занесення кількості байтів масиву mas1 shr ecx,2 ; ділення на 4 – визначення кількості чисел lea esi,mas1 ; занесення адреси початку масиву mas1 lea edi,mas2 ; занесення адреси початку масиву mas2 lea edx,mas3 ; занесення адреси початку масиву mas3 finit ; ініціювання співпроцесора

m4: fld dword ptr [esi] ; занесення в вершину стека числа з [esi] fld dword ptr [edi] ; занесення в вершину стека числа з [edi] fcomi st(0),st(1) ; порівняння та встановлення eflags fcmovb st(0),st(1) ; копіювання, якщо CF = 1. Інакше – ні fst dword ptr [edx] ; занесення у пам’ять більшого числа у масив mas3

add esi,4 ; вирівнювання на межу подвійного слова масиву mas1 add edi,4 ; вирівнювання на межу подвійного слова масиву mas2 add edx,4 ; вирівнювання на межу подвійного слова масиву mas3 loop m4 ; перейти на m4, якщо есх ≠ 0

invoke ExitProcess, 0 ; повернення керування ОС Windows ; та визволення ресурсів

end start ; директива закінчення програми з ім’ям start

Вікна налагоджувача після виконання програми та вміст комірок пам’яті наведено на рис. 15.10.

У програмі команду len equ $-mas1 треба завжди використати після тої директиви визначення даних, яка обчислюється. Якщо цю

Page 346: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

345

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

Доступ до елементів трьох масивів виконується за допомогою регістрів esi, edi та edx з використанням непрямої адресації.

Для того щоб виконати операції над некоректними цілими або

дійсними числами, в системі команд передбачено три команди: fucom st(i) – порівняння безпорядкових чисел в регістрах st(0)

і st(i); fucomp st(i) – порівняння безпорядкових чисел в регістрах

st(0) і st(i) з виштовхуванням чисел з вершини стека; fucompp st(i) – порівняння безпорядкових чисел в регістрах

st(0) і st(i) з виштовхуванням чисел з регістрів st(0) і st(1).

15.3.3. Арифмет ичні команди До групи арифметичних команд належать команди, які реалізують

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

Рис. 15.10. Вікна налагоджувача після виконання програми з листингу 15.5

Page 347: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

346

Мнемоніки базових арифметичних команд приведено в табл. 15.6.

Таблиця 15.6 Мнемоніка базових арифметичних команд

Команди Основні Ціле у пам’яті З вилученням Додавання Віднімання Зворотне віднімання Множення Ділення Зворотне ділення

fadd fsub fsubr fmul fdiv fdivr

fiadd fisub fisubr fimul fidiv fidivr

faddp fsubp fsubrp fmulp fdivp fdivrp

Команди для роботи з цілочисельними операндами маніпулюють

даними розміром в 16 і 32 біта і включають: fiadd операнд – складання вмісту вершини стека st(0) з

цілочисельним операндом розміром 16 або 32 біта; результат складання зберігається в регістрі st(0);

fisub операнд – віднімання цілочисельного операнда розміром 16 або 32 біта з вмісту вершини стека st(0), результат віднімання зберігається в регістрі st(0);

fimul операнд – множення вмісту вершини стека st(0) на цілочисельний операнд розміром 16 або 32 біта; результат множення зберігається в регістрі st(0);

fdiv операнд – ділення вмісту вершини стека st(0) на цілочисельний операнд розміром 16 або 32 біта; результат ділення зберігається в регістрі st(0);

flsubr операнд – віднімання вмісту регістра st(0) з цілочисельного операнда розміром 16 або 32 біта; результат віднімання зберігається в регістрі st(0);

fidivr операнд – ділення цілочисельного операнда розміром 16 або 32 біта на вміст вершини стека st(0); результат ділення зберігається в регістрі st(0).

Арифметичні команди для роботи з дійсними числами складання

мають такий синтаксис: fadd приймач, джерело faddp приймач, st fadd джерело

Page 348: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

347

Тут приймач – операнд-приймач, а джерело – операнд-джерело. Якщо обидва операнди є регістрами стека, то одним з них обов’язково повинен бути st(0). Якщо єдиним операндом є елемент пам’яті (32 або 64 розряди), то другим операндом буде регістр st(0), в якому і зберігається результат.

Далі наводиться докладніший опис команд складання: fadd – складання вмісту вершини стека st(0) і регістра st(і);

результат складання зберігається в регістрі st(0); fadd джерело – складання вмісту вершини стека st(0) і

елемента пам’яті джерело; результат складання зберігається в регістрі st(0);

fadd st, st(i) – складання вмісту регістра стека st(i) і вершини стека st(0); результат зберігається в регістрі st(0);

fadd st(i), st – складання вмісту регістра стека st(i) і вершини стека st(0); результат зберігається в регістрі st(i);

faddp st(i), st –складання вмісту регістра стека st(i) і вершини стека st(0), з наступним виштовхуванням значення з вершини стека; результат операції зберігається в регістрі st(i – 1).

Команди віднімання мають такий синтаксис: fsub приймач, джерело fsubp приймач, st fsub джерело Тут приймач – операнд-приймач, а джерело – операнд-джерело.

Команди виконують віднімання вмісту операнда-джерела з вмісту операнда-приймача, зберігаючи результат в операнді-приймачі. Якщо обидва операнди є регістрами стека, то одним з них обов’язково повинен бути st(0). Якщо єдиним операндом є елемент пам’яті (32 або 64 розряди), то другим операндом буде регістр st(0), в якому і зберігається результат.

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

fsub – віднімання вмісту регістра st(0) з вмісту st(1); результат віднімання зберігається в регістрі st(0): [st(0) := st(1) – st(0)];

fsub джерело – віднімання вмісту операнда джерело, розташованого в пам’яті, з вмісту вершини стека st(0), результат віднімання зберігається в регістрі st(0);

fsub st, st(i) – віднімання вмісту регістра st(i) з вмісту регістра стека st(0); результат зберігається в регістрі st(0);

Page 349: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

348

fsub st(i), st – віднімання вмісту регістра стека st(0) з вмісту будь-якого з регістрів st(i); результат – в регістрі st(i): [st(i) := st(i) – st(0)];

fsubp st(i), st – віднімання вмісту регістра стека st(0) з вмісту будь-якого з регістрів st(i) з наступним виштовхуванням значення з вершини стека; результат операції зберігається в регістрі st(і – 1);

fsubr st(i), st – віднімання вмісту регістра стека st(і) з вмісту регістра st(0); результат зберігається в регістрі st(і): [st(i) := st(0) – st(i)];

fsubrp st(i), st –віднімання вмісту регістра стека st(0) з вмісту будь-якого з регістрів st(i), з наступним виштовхуванням значення з вершини стека; результат операції зберігається в регістрі st(i).

Команди множення мають такий синтаксис: fmul приймач, джерело fmulp приймач, st fmul джерело Тут приймач – операнд-приймач, а джерело – операнд-джерело.

Команди цієї групи виконують множення операнда-приймача на операнд-джерело, зберігаючи результат в операнді-приймачі. Якщо як операнди вказано регістри стека співпроцесора, то один з них повинен бути st(0). Якщо як єдиний операнд виступає елемент пам’яті, то другим операндом за умовчанням є регістр st(0), що зберігає результат операції. Операнди, подані змінними в пам’яті, можуть бути 32- або 64-розрядними.

У цю групу включено такі команди: fmul – множення вмісту регістра вершини стека st(0) на вміст

регістра st(1); результат зберігається в регістрі st(0), st(1) обнуляється; fmul st, st(i) – множення регістра st(0) на вміст регістра st(i);

результат зберігається в регістрі st(0); fmul st(i), st – множення вмісту регістра st(0) на вміст одного з

регістрів st(і); результат зберігається в регістрі st(і); fmulp st(i), st – множення вмісту регістра st(0) на вміст одного

з регістрів st(i) з наступним виштовхуванням вмісту вершини стека st(0); результат множення залишається в регістрі st(і – l).

Команди ділення мають такий синтаксис: fdiv приймач, джерело fdivp приймач, st fdiv джерело

Page 350: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

349

Тут приймач – операнд-приймач, а джерело –- операнд-джерело. Команди цієї групи виконують ділення операнда-приймача на операнд-джерело, зберігаючи частку в операнді-приймачі. Якщо як операнди вказано регістри стека співпроцесора, то один з них повинен бути st(0). Якщо як єдиний операнд виступає елемент пам’яті, то другим операндом за умовчанням є регістр st(0), в якому зберігається результат операції. Операнди, подані змінними в пам’яті, можуть бути 32- або 64-розрядними.

У цю групу включено такі команди: fdiv – ділення вмісту регістра st(1) на значення, що знаходиться

у вершині стека st(0); результат операції зберігається в регістрі st(0); fdiv st, st(i) – ділення вмісту регістра st(0) на значення, що

знаходиться в регістрі st(i); результат операції зберігається в регістрі st(0);

fdiv st(i), st – ділення вмісту регістра st(і) на значення, що знаходиться в регістрі st(0); результат операції зберігається в регістрі st(і);

fdivp st(i), st –ділення вмісту регістра st(і) на значення, що знаходиться в регістрі st(0) з наступним виштовхуванням вмісту вершини стека; результат операції поміщається в регістр st(і – 1);

fdivr st(i), st – ділення вмісту регістра st(i) на значення, що знаходиться у вершині стека st(0); результат операції поміщається в регістр st(0);

fdivrp st(i), st – ділення вмісту регістра st(i) на значення, що знаходиться у вершині стека st(0); результат операції поміщається в регістр st(i), після чого вміст st(0) виштовхується із стека, а результат ділення залишається в регістрі st(і – 1).

Приклад 15.6. Обчислити вираз ab – cd, де a = 0,1; b = 10,05;

c = 100; d = 0,5. Програма обчислення прикладу 15.6 наведено у листингу 15.6. Листинг 15.6. Програма обчислення прикладу 15.6: title CopyRight by Rysovaniy A. N. .386 ; директива визначення типу мікропроцесора

.model flat, stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap:none ; відмінність малих та великих літер include \masm32v9_0\include\windows.inc

Page 351: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

350

include \masm32v9_0\include\kernel32.inc include \masm32v9_0\include\fpu.inc includelib \masm32v9_0\lib\user32.lib includelib \masm32v9_0\lib\kernel32.lib includelib \masm32v9_0\lib\fpu.lib BSIZE equ 30 ; розмір буфера

.data ; директива визначення даних a1 DWORD 0.1 b1 DWORD 10.05 a2 DWORD 100.0 b2 DWORD 0.5

stdout DWORD ? ; резервування в пам’яті 32-розрядної комірки ; з ім’ям stdout для збереження дескриптора виведення

cWritten DWORD ? ; резервування 32-розрядної комірки пам’яті ; з ім’ям cWritten для адреси символів виведення

buf BYTE BSIZE dup (?) ; кількість байтів для запису послід. символів .code ; директива початку програми start: ; мітка початку програми з ім’ям start

main proc ; процедура з іменем main finit ; ініціювання співпроцесора fld a1 ; занесення в вершину стека a1: st(0) := a1 fld b1 ; занесення в вершину стека b1: st(0) := b1, st(1) := a1 fmul ; st(0) := b1 × a1 fld a2 ; занесення a2; st(0) := a2, st(1) := b1 × a1 fld b2 ; занесення b2: st(0) := b2, st(1) := a2, st(2) := b1 × a1 fmul ; st(0) := b2 × a2, st(1) := b1 × a1 fsub ; st(0) := st(1) – st(0)

invoke GetStdHandle, STD_OUTPUT_HANDLE mov stdout, eax ; збереження одержаного дескриптора у пам’яті

invoke FpuFLtoA, \ ; АРІ-функція перетворення 80-розр. числа 0, \ ; адреса числа, що відображається

10, \ ; кількість десяткових знаків після коми (10) ADDR buf, \ ; адреса буфера для символів, які перетворяться

SRC1_FPU or SRC2_DIMM ; адреса 80-розр. числа та саме число

invoke WriteConsoleA, \ ; АРІ-функція виведення на екран stdout, \ ; дескриптор стандартного пристрою виведення

ADDR buf, \ ; адреса початку повідомлення BSIZE, \ ; розмір повідомлення

Page 352: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

351

ADDR cWritten, \ ; адреса, де зберігається число символів NULL

invoke ExitProcess, 0 ; повернення керування ОС Windows

; та визволення ресурсів main endp ; закінчення процедури з іменем main end start ; директива закінчення програми з іменем start Процедура FpuFLtoA підготовляє 80-розрядне число до виведення

на екран: розшифровує і записує в буфер послідовність символів з десятьма знаками після коми. Ця процедура входить у склад бібліотеки fpu.lib.

У процедури FpuFLtoA чотири параметри: – адреса числа, що відображається; – кількість десяткових знаків після коми (10); – адреса буфера, де опиняться символи, на які перетвориться число; – константи, процедури, що керують роботою. Константа

SRC1_REAL передає функції, що її перший параметр – це адреса 80-бітового числа, що зберігається в звичайній пам’яті. Константа SRC2_DIMM указує функції, що другий її параметр – просто число (10).

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

-48.9949999660, наведено на рис. 15.11. Приклад 15.7. Обчислити вираз: a – b/4 – ab, де a = 0,1;

b = 10,05. Програму обчислення прикладу 15.7 наведено у листингу 15.7.

Рис. 15.11. Результат виконання програми з листингу 15.6

Page 353: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

352

Листинг 15.7. Програма обчислення прикладу 15.7: title CopyRight by Rysovaniy A. N. .386 ; директива визначення типу мікропроцесора

.model flat, stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap:none ; відмінність малих та великих літер include \masm32v9_0\include\windows.inc include \masm32v9_0\include\kernel32.inc include \masm32v9_0\include\fpu.inc includelib \masm32v9_0\lib\user32.lib includelib \masm32v9_0\lib\kernel32.lib includelib \masm32v9_0\lib\fpu.lib BSIZE equ 30 ; розмір буфера

.data ; директива визначення даних a1 DWORD 0.1 b1 DWORD 10.05 c1 DWORD 4.

stdout DWORD ? ; резервування в пам’яті 32-розрядної комірки ; з ім’ям stdout для збереження дескриптора виведення

cWritten DWORD ? ; резервування 32-розрядної комірки пам’яті ; з ім’ям cWritten для адреси символів виведення

buf BYTE BSIZE dup (?) ; кількість байтів для запису послід. символів .code ; директива початку програми start: ; мітка початку програми з ім’ям start

main proc ; процедура з іменем main finit ; ініціювання співпроцесора fld b1 ; занесення в вершину стека b1 fld c1 ; занесення в вершину стека числа 4 fdiv ; st(0) := st(1)/st(0) fld a1 ; занесення в вершину стека a1 fsub st(0),st(1) ; st(0) := st(0) – st(1) fld a1 ; занесення в вершину стека а1 fld b1 ; занесення в вершину стека b1 fmul ; st(0) := st(0) × st(1) fsubp st(1),st(0) ; st(0) ← st(1) := st(1) – st(0)

invoke GetStdHandle, STD_OUTPUT_HANDLE mov stdout, eax ; збереження одержаного дескриптора у пам’яті

invoke FpuFLtoA, \ ; АРІ-функція перетворення 80-розр. числа 0, \ ; адреса числа, що відображається

Page 354: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

353

10, \ ; кількість десяткових знаків після коми (10) ADDR buf, \ ; адреса буфера для символів, які перетворяться

invoke WriteConsoleA, \ ; АРІ-функція виведення на екран stdout, \ ; дескриптор стандартного пристрою виведення

ADDR buf, \ ; адреса початку повідомлення BSIZE, \ ; розмір повідомлення

ADDR cWritten, \ ; адреса, де зберігається число символів NULL

invoke ExitProcess, 0 ; повернення керування ОС Windows ; та визволення ресурсів

main endp ; закінчення процедури з іменем main end start ; директива закінчення програми з ім’ям start

Вікна налагоджувача після виконання програми з листингу 15.7

наведено на рис. 15.12. Рис. 15.12. Вікна налагоджувача після виконання програми листингу 15.7

Page 355: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

354

Результат виконання програми з листингу 15.7 наведено на рис. 15.13. Він дорівнює -3,4175.

Окрім основних арифметичних команд є додат кові арифмет ичні

команди: fsqrt – обчислення квадратного кореня; fscale – масштабування на ступінь числа 2; fprem – обчислення часткового залишку; frndint – округлення до цілого; fxtract – виділення порядку числа та мантиси; fabs – обчислення абсолютної величини числа; fchs – зміна знака числа.

За командою fsqrt обчислене значення квадратного кореня

записується у вершину стека st(0). Розглянемо використання цієї команди.

Приклад 15. 8. Обчислити функцію Листинг 15.8. Програма виконання прикладу 15.8: .686 ; директива визначення типу мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті

; та угоди ОС Windows option casemap: none ; відмінність малих та великих літер ExitProcess proto: dword ; прототип API-функції includelib \masm32v9_0\lib\kernel32.lib

Рис. 15.13. Результат виконання програми з листингу 15.7

S = √p × ( p – A) (p – B) (p – C).

Page 356: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

355

.data ; директива визначення даних

opA dd 5.6 ; opB dd 6.1 ; opC dd 7.5 ; Per dd 2 ; комірка для збереження периметра res dd ? ; комірка для збереження результату

.code ; директива початку коду програми _st: ; мітка початку програми

finit ; ініціювання співпроцесора fld opA ; st(0) := opA fld opB ; st(0) := opB, st(1) := opA fld opC ; st(0) := opC, st(1) := opB, st(2) := opA fld st(0) ; повторення (місце для виконання операцій)

; st(0) := opC, st(1) := opC, st(2) := opB, st(3) := opA ; обчислення периметра

fadd st(0),st(2) ; st(0) := opC + opB fadd st(0),st(3) ; st(0) := (opC + opB) + opA fidiv Per ; обчислення півпериметра: st(0) := st(0)/2 fsubr st(1),st ; st(1) := st(0) – st(1), (p – C) fsubr st(2),st ; st(2) := st(0) – st(2), (p – B) fsubr st(3),st ; st(3) := st(0) – st(3), (p – A) fmulp st(1),st ; st(0) := st × st(1), p(p – C) fmulp st(1),st ; p(p – C)(p – B) fmulp st(1),st ; p(p – C)(p – B)(p – A) fsqrt ; обчислення кореня fstp res ; збереження у пам’яті результату

invoke ExitProcess, 0 ; повернення керування ОС Windows

; та визволення ресурсів end _st ; директива закінчення програми

Вікна налагоджувача перед виконання обчислення кореня прикладу

15.8 наведено на рис. 15.14.

Page 357: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

356

У наведеній програмі команда fld st(0) необхідна для того, щоб у

вершині стека регістрів виконувати тимчасові операції без порушення початкових значень операндів. А для коректного виконання ділення при обчисленні півпериметра слід використати команду цілочисельного ділення fidiv Per2. При іншій мнемоніці коду операції результат буде невірним. Крім того, при використанні API-функцій обов’язково необхідно використати умову stdcall.

Приклад 15.9. Обчислити корні квадратного рівняння Листинг 15.9. Програма виконання прикладу 15.9: .686 ; директива визначення типу мікропроцесора .model flat, stdcall ; завдання лінійної моделі пам’яті

; та угоди ОС Windows option casemap:none ; відмінність малих та великих літер include \masm32v9_0\include\windows.inc include \masm32v9_0\include\kernel32.inc include \masm32v9_0\include\fpu.inc

Рис. 15.14. Вікна налагоджувача після виконання програми з листингу 15.8

x1,2 = – p/2 ± √p2/4 – q.

Page 358: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

357

includelib \masm32v9_0\lib\user32.lib includelib \masm32v9_0\lib\kernel32.lib includelib \masm32v9_0\lib\fpu.lib BSIZE equ 30 ; розмір буфера

.data ; директива визначення даних p DWORD 8.0 q DWORD 5.0 two DWORD -2.0 x1 TBYTE ? x2 TBYTE ? stdout DWORD ? ; резервування в пам’яті 32-розрядної комірки

; з ім’ям stdout для збереження дескриптора виведення cWritten DWORD ? ; резервування 32-розрядної комірки пам’яті

; з ім’ям cWritten для адреси символів виведення buf BYTE BSIZE dup (?); кількість байтів для запису послід. символів

.code ; директива початку програми start: ; мітка початку програми з ім’ям start

finit ; ініціювання співпроцесора fld p ; st = p fld two ; st = -2, st(1) = p fdiv ; st(1) = p/2 fld ST ; st(0) = st(1) = p/2 fmul ; st(1) = st(1) × st(0) = p2/4 fld q ; st(0) = q fsub ; st(0) = (p2/4) – q fsqrt ; √(p2/4) – q) fld p ; st(0) = p fld two ; -2.0 fdiv ; st(0) = – p/2 fld st ; st(1) = st(0) fsub st, st(2) ; st = – p/2 – √(p2/4) – q) fstp x1 ; зберегти корінь fadd st, st(1) ; st = – p/2 + √(p2/4) – q) fstp x2 ; зберегти корінь invoke GetStdHandle, STD_OUTPUT_HANDLE

mov stdout, eax ; збереження одержаного дескриптора у пам’яті invoke FpuFLtoA, ADDR x1, 10, \ ADDR buf, SRC1_REAL or SRC2_DIMM invoke WriteConsoleA, \ ; АРІ-функція виведення на екран

Page 359: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

358

stdout, \ ; дескриптор стандартного пристрою виведення ADDR buf, \ ; адреса початку повідомлення

BSIZE, \ ; розмір повідомлення ADDR cWritten, \ ; адреса, де зберігається число символів

NULL invoke FpuFLtoA, ADDR x2, 10, \ ADDR buf, SRC1_REAL or SRC2_DIMM invoke WriteConsoleA, stdout, ADDR buf, \ BSIZE, ADDR cWritten, NULL invoke ExitProcess, 0 ; повернення керування ОС Windows

; та визволення ресурсів end start ; директива закінчення програми з іменем start У наведеній програмі під коренем повинні бути позитивні числа.

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

Результат отримання коренів наведено на рис. 15.15. Команда fscale змінює порядок числа, що знаходиться в st(0). За

цією командою значення порядку числа st(0) складається з масштабним коефіцієнтом, який повинен бути заздалегідь записаний в st(1).

Рис. 15.15. Результат виконання програми з листингу 15.9

Page 360: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

359

Команда fprem обчислює залишок від ділення діленого st(0) на дільник st(1). Знак результату дорівнює знаку st(0), а сам результат знаходиться у вершині стека st(0). Дія команди полягає в зрушеннях і відніманнях, аналогічно ручному діленню “в стовпчик”. Після виконання команди прапорець c2 регістра стану може набувати такі значення:

0 – залишок від ділення, одержаний в st(0), менше дільника st(1); команда завершується повністю;

1 – st(0) містить частковий залишок; програма повинна ще раз виконати команду для отримання точного значення залишку.

Команда frndint округляє st(0) відповідно до вмісту поля rc регістра керування.

Команда fabs обчислює абсолютне значення st(0). Команда fchs змінює знак st(0) на протилежний.

Команда frndint виконує округлення числа, що знаходиться у вершині стека st(0), до цілого числа. Команда не має операндів, а тому використовує операнд з регістра st(0) і після перетворення його там і залишає (повертає результат в регістр st(0)). Допускається чотири режими округлення, причому визначаються вони значенням поля гс керуючого регістра cwr співпроцесора. Режим округлення можна встановлювати в процесі виконання програми до того як виникне потреба в цій операції. Для цього можна встановити потрібну комбінацію бітів в полі гс регістра cwr, використовуючи команди fstсw (збереження регістра cwr) і fldcw (завантаження регістра cwr).

Параметр, який вказує режим округлення, може набувати значення 0 – 3, при цьому 0 відповідає режиму з гс = 00 (округлення до найближчого цілого числа), 1 – режиму з гс = 01 (округлення в меншу сторону), 2 – режиму з гс = 10 (округлення у велику сторону) і, нарешті, 3 – режиму з гс = 11 (відкидання дробової частини).

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

округлити результат до найближчого цілого числа Програму обчислення прикладу 15.10 наведено у листингу 15.10. Листинг 15.10. Програма обчислення прикладу 15.10: title CopyRight by Rysovaniy A. N. .686 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

Page 361: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

360

option casemap: none ; відмінність малих та великих літер ExitProcess proto: dword ; прототип API-функції includelib \masm32v9_0\lib\kernel32.lib

.data ; директива визначення даних

op1 dd 10.1 ; збереження в 32-розрядній комірці пам’яті ; з ім’ям op1 числа 10.1

op2 dd 10.2 tmp1 DW 0F3FFh ; rc = mode 00 res DD 0

.code ; директива початку коду програми _st: ; мітка початку програми

finit ; ініціювання співпроцесора fldcw tmp1 ; завантажити cwr константою з іменем tmp1 fld op1 ; занести ор1 в st(0) fadd op2 ; st(0) := st(0) + op2 frndint ; округлити st(0) fstp dword ptr res ; занести st(0) у комірку пам’яті з іменем res

invoke ExitProcess, 0 ; повернення керування ОС Windows ; та визволення ресурсів

end _st ; директива закінчення програми з іменем _st

Вікна налагоджувача після виконання програми листингу 15.10 наведено на рис. 15.16.

Рис. 15.16. Вікна налагоджувача після виконання програми листингу 15.10

Page 362: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

361

З рис. 15.16 видно, що після округлення у вершині стека st(0) буде число 20.0. Таким чином, щоб змінювати режими округлення, необхідно заносити у регістр cwr такі константи:

F3FFh ; rc = mode 00 F7FFh ; rc = mode 01 FBFFh ; rc = mode 10 FFFFh ; rc = mode 11. У програмі з листингу 15.9 режим роботи задається константою з

іменем tmp1. Результат виконання операції зберігається в комірках пам’яті з іменем res.

15.3.4. Трансцендент ні команди

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

звичайних тригонометричних (sin, cos, tg,...), зворотних тригонометричних (arcsin, arccos,...), гіперболічних (sh, ch, th,...), зворотних гіперболічних (arsh, arch, arcth,...), логарифмічних і показних функцій (xy, 2x, 10x, ex). Звичайно такі обчислення займають багато часу і є дуже інтенсивними щодо використання ресурсів процесора.

Трансцендентними командами співпроцесора є: – fsin – обчислення sin(x); – fcos – обчислення cos(x); – fsincos – обчислення sin(x) і cos(x) одночасно; – fptan – обчислення часткового тангенса; – fpatan – обчислення часткового арктангенса; – fyl2x – обчислення y × log2(x); – fyl2xp1 – обчислення y × log2(x+1); – f2xm1 – обчислення 2x – 1.

Команда fptan обчислює частковий тангенс st(0), розміщуючи в

стеку такі два числа x і у, так що y/x = tg(st(0)). Після виконання команди число у розташовується в st(0), а число x

включається в стек зверху (тобто записується в st(1)). Аргумент команди fptan повинен знаходиться в таких межах:

0 <= st(0)<= π/4. Користуючись набутим значенням часткового тангенса, можна

обчислити інші тригонометричні функції.

Page 363: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

362

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

Кут (рад) = Кут (град) х π/180, де π/180 = 0,0174.

Команда fsіn заміщає аргумент (у радіанах), розташований у вершині стека st(0), значенням синуса. Команда fcos обчислює косинус кута і поміщає його в st(0). Команда fsincos комбінує попередні дві команди і обчислює обидві функції таким чином:

– значення синуса кута поміщається в st(0); – косинус кута поміщається в стек регістрів. Отже, після виконання операції косинус кута опиниться у вершині

стека st(0), синус – в регістрі st(і). Приклад 15.11. Обчислити sin34о та cos34о та перевірити

правильність їх обчислення. Програму виконання прикладу 15.11 наведено у листингу 15.11. Листинг 15.11. Програма виконання прикладу 15.11: .686 ; директива визначення типу мікропроцесора .model flat ; завдання лінійної моделі пам’яті option casemap:none ; відмінність малих та великих

літер .data ; директива визначення даних

x1 DD 34. ; величина градусів const DD 0.01745 ; π/180 sin_1 DD 0 ; перша комірка для обчислення sin34о cos_1 DD 0 ; перша комірка для обчислення cos34о sin_2 DD 0 ; друга комірка для обчислення sin34о cos_2 DD 0 ; друга комірка для обчислення cos34о

.code ; директива початку коду програми _st: ; мітка початку програми

finit ; ініціювання співпроцесора fld dword ptr x1 ; занесення аргументу у вершину стека fmul dword ptr const ; fsin ;

Page 364: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

363

fstp dword ptr sin_1 ; занесення аргументу у вершину стека fld dword ptr x1 fmul dword ptr const fcos ; fstp dword ptr cos_1 ; занесення аргументу у вершину стека fld dword ptr x1 fmul dword ptr const fsincos ; fstp dword ptr cos_2 ; збереження у пам’яті cos_2 fstp dword ptr sin_2

ret ; повернення керування OC

end _st ; директива закінчення програми Змінна з ім’ям const = 0.01745 = π/180 дозволяє переводити

градуси в радіани. Значення градусів вводиться змінною x1. Правильність отримання результатів підтвержується на рис. 15.17.

Значення sin34о наведено у комірках, починаючи з 402008 та

402010, а значення cos34о – у комірках, починаючи з 40200С та 402014.

Рис. 15.17. Вікна налагоджувача з отриманими результатами

Page 365: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

364

Приклад 15.12. Обчислити значення функції f = ½ × A × B ×sinα. Листинг 15.12. Програма розв’язання прикладу 15.12: .686 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap: none відмінність малих та великих літер ExitProcess proto: dword ; прототип API-

функції includelib \masm32v9_0\lib\kernel32.lib

.data ; директива визначення даних opA dd 5.6 ; збереження у 32-розрядній комірці пам’яті змінної А opB dd 6.2 ; збереження у 32-розрядній комірці пам’яті змінної В opALFA dd 0.7 ; збереження у 32-розрядній комірці пам’яті кута

res dd ? ; 32-розрядна комірка для збереження результату m2 dd 2 ; збереження у 32-розрядній комірці пам’яті константи m2 = 2 .code ; директива початку коду програми _st: ; мітка початку програми

finit ; ініціювання співпроцесора fld opALFA ; завантаження у вершину стека значення кута fsin fmul opA fmul opB fidiv m2 fstp res ; збереження результату у пам’яті invoke ExitProcess, 0 ; повернення керування ОС Windows

; та визволення ресурсів end _st ; директива закінчення програми У наведеній програмі константа m2 є цілочисельною. Тому й

необхідно використовувати команду ділення цілочисельних даних fidiv m2.

15.3.5. Команди маніпуляції константами

До команд передачі можна віднести і групу команд для

завантаження в стек регістрів зумовлених констант: fldz – st(0) ← 0 (завантаження 0 у вершину співпроцесора); fld1 – st(0) ← 1 (завантаження одиниці у вершину стека

Page 366: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

365

співпроцесора); fldpi – st(0) ← π (завантаження числа π у вершину стека

співпроцесора); fldl2t – st(0) ← loge10 (завантаження двійкового логарифма

десяти у вершину стека співпроцесора); fldl2е – st(0) ← log2e (завантаження двійкового логарифма

числа е у вершину стека співпроцесора); fldlg2 – st(0) ← log102 (завантаження десяткового логарифма

двох у вершину стека співпроцесора); fldln2 – st(0) ← loge2 (завантаження натурального логарифма

двох у вершину стека співпроцесора).

15.3.6. Команди керування Команди керування не використовуються в обчисленнях, а керують

діями співпроцесора на системному рівні. Синтаксис основних керівних команд такий:

fwait – синхронізує роботу процесора і математичного співпроцесора (якщо процесор зустрічає цю команду, він припиняє свою роботу до закінчення виконання чергової команди співпроцесора);

finit – ініціалізує співпроцесор з поміщенням зумовлених значень в керуючі регістри співпроцесора;

fstsw dest – зберігає регістр стану в 16-розрядному операнді dest; слово стану може зберігатися і в 16-розрядному регістрі АХ;

fstcw dest – зберігає вміст регістра керування в 16-розрядній змінній dest в пам’яті (команда використовується для аналізу полів регістра cwr);

fldсw src – завантажує вміст 16-розрядної змінної src в регістр cwr (команда використовується для завдання режимів роботи співпроцесора);

fclex – скидає прапорці виключень в регістрі swr співпроцесора;

fincstp – збільшує вказівник стека на одиницю в полі top регістра стану співпроцесора (swr). Команда не має операндів і за своєю дією нагадує команду fst. Вміст вершини стека при виконанні команди віддаляється;

fdecstp – зменшує вказівник стека на одиницю в полі top регістра стану співпроцесора (swr). Команда не має операндів і за своєю дією нагадує команду fld, але операнд в стек не поміщається;

Page 367: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

366

ffгее st(і) – звільняє регістр стека st(і), позначаючи його як порожній в регістрі тегів (twr). Вміст поля top в регістрі стану (swr) і сам зміст регістра не змінюються;

fnop – нічого не робить і може використовуватися для тимчасових затримок;

fsave dest – запам’ятовує стан співпроцесора в 94-байтовій області пам’яті dest (16-розрядний режим роботи) або в 108-байтовій області пам’яті (32-розрядний режим роботи);

frstor src – відновлює стан співпроцесора з 94-байтової області пам’яті src (16-розрядний режим роботи) або з 108-байтової області пам’яті (32-розрядний режим роботи);

fstenv dest – зберігає стан середовища співпроцесора (14 байт для 16-розрядного режиму роботи і 28 байт для 32-розрядного режиму) в області пам’яті dest. Команда не зберігає вміст стека регістрів (80 байт);

fldenv src – виконує часткове відновлення стану середовища співпроцесора (14 байт для 16-розрядного режиму роботи і 28 байт для 32-розрядного режиму) з області пам’яті src.

15.4. Лабораторна робота

“Арифметичні операції у співпроцесорі”

Мета заняття: – поглибити і закріпити знання з архітектури МП платформи х86 і

навички його програмування; – придбати практичні навички складання, налагодження і

виконання програм з використанням команд співпроцесора, написаних мовою асемблеру для програмування МП платформи х86.

Постановка задачі Згідно з останньою цифрою номера в групі вибрати варіант та

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

Завдання 1. Дослідити виконання арифметичних операцій

співпроцесора. 1. Обчислити 3 значення функції: Yn = 25х3 – 2,1 (x змінюється від 2

з кроком 3). Результат розмістити в пам’яті та вивести на екран. 2. Обчислити 4 значення функції: Yn = 7x/(4x2 – 1,5) (x змінюється

від 1 з кроком 4). Результат розмістити в пам’яті та вивести на екран.

Page 368: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

367

3. Обчислити 5 значень функції: Yn = 327/(2x2 + 7,3) (x змінюється від 1 з кроком 1). Результат розмістити в пам’яті та вивести на екран.

4. Обчислити 5 значень функції: Yn = 5,1x2 + 5,3 (х змінюється від 4,7 з кроком 3). Результат округлити до найближчого цілого числа та вивести на екран.

5. Обчислити 6 значень функції: Yn = 4x/(x + 5) (х змінюється від 3 з кроком 1,25). Результат округлити до цілого, розмістити в пам’яті та вивести на екран.

6. Обчислити 4 значень функції: Yn = 125/(3х2 – 1,1) (х змінюється від 3 з кроком 1,5). Результат округлити в меншу сторону та вивести на екран.

7. Обчислити 4 значень функції: Yn = 2,5x2 – 3,2 (x змінюється від 4 з кроком 1). Результат розмістити в пам’яті та вивести на екран.

8. Обчислити 3 значення функції: Yn = 25х2 + 2,1 (x змінюється від 3 з кроком 2,5). Результат розмістити в пам’яті та вивести на екран.

9. Обчислити 4 значення функції: Yn = 150/(x2 – 7) (x змінюється від 2 з кроком 3,1). Результат розмістити в пам’яті та вивести на екран.

10. Обчислити 6 значень функції: Yn = 256/(3x2 + 31) (x змінюється від 2 з кроком 3). Результат розмістити в пам’яті та вивести на екран.

Завдання 2. Дослідити виконання операцій порівняння

співпроцесора. 1. Знайти перше значення аргументу функції Y = 7(x + 0,3), при

якому молодші цілі цифри результату виконання функції дорівнюватимуть 15 (x змінюється від 2 з кроком 3,5). Результат розмістити в пам’яті та вивести відповідні повідомлення.

2. Знайти ціле значення аргументу, при якому функція Y = 10/(x2 + 1,4) стане менше 0,2. (x змінюється від 3 з кроком 2,5). Результат розмістити в пам’яті та вивести відповідні повідомлення.

3. Знайти значення х, при якому функція Y = 2х + 12 × 2–х дорівнюватиме 9,5. Результат розмістити в пам’яті та вивести відповідні повідомлення.

4. Знайти значення х, при якому функція 8arctg0,1 + arctgx = π/4. Результат розмістити в пам’яті та вивести відповідні повідомлення.

5. Визначити номер (х) елемента функції: xn = 3х + 5, при якому сума елементів перевищить 12 000. Результат розмістити в пам’яті та вивести відповідні повідомлення.

6. Знайти значення х, при якому функція lg(2x + 3) буде більше 2,5. Результат розмістити в пам’яті та вивести відповідні повідомлення.

Page 369: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

368

7. Знайти ціле значення аргументу, при якому функція Y = 5,6x/3x2 перевищить 125. Результат розмістити в пам’яті та вивести відповідні повідомлення.

8. Знайти ціле значення аргументу, при якому функція Y = 2х + 3х перевищить 100. Результат розмістити в пам’яті та вивести відповідні повідомлення.

9. Знайти перше значення аргументу функції Y = 9(x2 + 0,6), при якому молодші цілі цифри результату виконання функції дорівнюватимуть 12 (x змінюється від 3 з кроком 5,5). Результат розмістити в пам’яті та вивести відповідні повідомлення.

10. Знайти ціле значення аргументу, при якому функція Y = 2х/5 + 4 перевищить 400. Результат розмістити в пам’яті та вивести відповідні повідомлення.

Завдання 3. Дослідити виконання команд співпроцесора з

логарифмічними і показовими функціями. 1. Обчислити 3 значення функції: Y = 5 * ln (sin x), x змінюється в

градусах від 10 з кроком 15. 2. Обчислити 4 значення функції : Y = 7x, x змінюється від 0,5 з

кроком 0,2. 3. Обчислити 5 значень функції: Y = 4 lg (tg x), x змінюється в

градусах від 15 з кроком 10. 4. Обчислити 3 значення функції: Y = 12x, x змінюється від 0,3 з

кроком 0,5. 5. Обчислити 4 значення функції: Y = 3 * log2(x2 +1), x змінюється

від 0,2 з кроком 0,3. 6. Обчислити 4 значення функції: Y = 5(sin x), x змінюється в

градусах від 10 з кроком 8,5. 7. Обчислити 4 значення функції: Y = lg(x2 + √x) , x змінюється від

2 з кроком 3. 8. Обчислити 3 значення функції: Y = 4(x2 + 1), x змінюється від 2 з

кроком 1,7. 9. Обчислити 5 значень функції: Y = 6 lg (cos x), x змінюється в

градусах від 20 з кроком 15. 10. Обчислити 5 значень функції: Y = 3(cos x), x змінюється в

градусах від 10 з кроком 8.

Page 370: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

369

Зміст звіту 1. Постановка задачі для конкретного варіанта. 2. Блок-схема алгоритму виконання прикладу. 3. Листинг програми з детальним коментарем та описом роботи. 4. Рrint screen екрана 32-розрядного налагоджувача з виконанням

програми та результатами виконання. 5. Висновки за результатами роботи. Приклад 15.13. Обчислити 5 значень функції: Y = 3(cosx), де x

змінюється в градусах від 10 з кроком 8. Листинг 15.13. Програма виконання прикладу 15.13: title CopyRight by Rysovaniy A. N. and Bessonov D.S. KIT-26a .386 ; директива визначення типу мікропроцесора

.model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap:none ; відмінність малих та великих літер include \masm32v9_0\include\windows.inc include \masm32v9_0\include\kernel32.inc include \masm32v9_0\include\fpu.inc include \masm32v9_0\include\user32.inc includelib \masm32v9_0\lib\user32.lib includelib \masm32v9_0\lib\kernel32.lib includelib \masm32v9_0\lib\fpu.lib

.data ; директива визначення даних x dd 10 ; збереження у 32-розрядній комірці пам’яті змінної х y dd ? ; резервування 32-х розрядів пам’яті для змінної y tmp dd ? ; резервування 32-х розрядів пам’яті для змінної tmp st1 db "y=3(cosx)",0 st2 db 10 dup(?),0

.code ; директива початку коду програми start: ; директива початку коду програми xor ecx,ecx ; обнулення регістру есх mov tmp, 8 ; занесення в комірку пам’яті з іменем tmp константи

finit ; ініціювання співпроцесора mov cx,5 ; занесення до сх константи 5 fild x

Page 371: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

370

@@: fiadd tmp loop @b fldpi mov tmp, 180 fidiv tmp fmul fcos mov tmp,3 fimul tmp

invoke FpuFLtoA, 0, 10, ADDR st2, SRC1_FPU or SRC2_DIMM invoke MessageBox, NULL, addr st2, addr st1, MB_OK invoke ExitProcess, NULL ; повернення керування ОС Windows

; та визволення ресурсів end start ; директива закінчення програми з ім’ям start У цій програмі команда з унікальною міткою @@: fiadd tmp

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

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

Виведенням цього вікна відповідає АРІ-функція MessageBox, в

якій використовуються такі параметри: NULL (hwnd) – ідентифікатор вікна, з якого викликається

Messagebox; addr st2 (lptext) – вказівник на рядок, який містить текст

повідомлення;

Рис. 15.18. Вікно результату виконання

програми з листингу 15.13

Page 372: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

371

addr st1 (lpcaption) – вказівник рядка, який містить заголовок повідомлення;

MB_OK (utype) – вигляд діалогового вікна. Константи NULL та MB_OK, використані у функції Messagebox,

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

Оператор addr використовується для передачі адреси мітки функції. Він дійсний тільки в контексті директиви invoke.

Вікна налагоджувача OllyDbg з програмою з листингу 15.13 наведено на рис. 15.19.

Рис. 15.19. Вікна налагоджувача OllyDbg з програмою з листингу 15.13

Page 373: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

372

16. ММХ-РОЗШИРЕННЯ

Команди ММХ – це команди паралельної обробки цілочисельних даних для використання у мультимедійних додатках (розширеннях) (MultiMedia extensions – мультимедійні розширення). Вони призначені для одночасної обробці декількох елементів даних за одну інструкцію. Розширення ММХ з’явилося в процесорах модифікації Pentium P54C і присутнє у всіх останніх модифікаціях цього процесора (http://www.intel.com/design/pentium4/manuals/index_new.htm#aorm).

Команди ММХ включено до групи команд технології під назвою SIMD (Single Instruction, Multiple Data – одна команда, багато даних). Технологія SIMD реалізована як дві взаємозв’язані технології обробки даних: ММX і SSE. Застосування асемблеру в SIMD-розширеннях дозволяє писати компактний і швидкий код для критичних фрагментів додатка з використанням спеціальних інструкцій процесора для SIMD-розширень.

Команди технології ММХ працюють з новими типами даних: 64-розрядними цілочисельними даними, а також з даними, упакованими в групи загальною довжиною 64 біта. Такі дані можуть знаходитися в пам’яті або у восьми ММХ-регістрах, які позначаються як ММ0 – ММ7.

Команди MMX-розширення виконуються в тому ж режимі процесора, що і команди з плаваючою крапкою.

При роботі з ММХ-командами використовуються регістри стека математичного співпроцесора R0 – R7. При цьому використовуються лише 64 розряди, а стекова організація, що потрібна для операцій співпроцесора, не використовується. При сумісному використанні математичного співпроцесора і MMX-розширення останньою виконуваною командою MMX-розширення повинна бути команда emms. Ця команда забезпечує коректний перехід процесора від виконання фрагмента програмного коду з ММХ-командами до обробки звичайних команд з плаваючою крапкою співпроцесора.

Page 374: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

373

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

упаковані байти (packed byte) – один 64-розрядний регістр містить 8 байт;

упаковані слова (packed word) – один 64-розрядний регістр містить чотири 16-розрядні слова;

упаковані подвійні слова (packed doubleword) – один 64-розрядний регістр містить два 32-розрядні слова;

64-розрядні слова (quadword). Обробка даних MMX-розширення може виконуватися одним з двох

способів: з використанням циклічної арифметики (wraparound arithmetic) або арифметики з насиченням (saturation arithmetic).

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

Якщо команда використовує арифметику з насиченням і результат операції перевищує максимальне уявне значення, то у вихідний операнд записується це максимальне значення (відбувається “насичення”).

Більшість команд мають суфікс, який визначає тип даних і використовувану арифметику:

us (unsigned saturation) – беззнакове насичення, при якому, якщо результат операції перевищує максимальне значення, у вихідний операнд записується це максимальне значення (відбувається “насичення”). Якщо результат операції виявився меншим за нижню межу допустимого діапазону, то у вихідний операнд записується мінімально можливе значення;

s або ss (signed saturation) – знакове насичення, при якому використовується арифметика з насиченням, дані із знаком;

якщо в суфіксі немає ні символу s, ні символів ss, то застосовується циклічна арифметика (wraparound). Якщо в цьому випадку результат операції виходить за двійкову розрядну сітку використовуваного типу даних, то “зайві” старші біти результату відкидаються;

b, w, d, q – ці букви указують тип даних. Якщо в суфіксі є дві з цих букв, то перша з них відповідає вхідному операнду, а друга – вихідному.

Page 375: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

374

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

Таблиця 16.1

Тип даних Мінімальне значення Максимальне значення Байт зі знаком 80h (-128) 7Fh (127) Байт без знака 00h FFh (256) Слово зі знаком 8000h (-32768) 7FFFh (32767) Слово без знака 0000h FFFFh (65535) Подвійне слово зі знаком 80000000h (-2147483648) 7FFFFFFFh (2147483647) Подвійне слово без знака 00000000h FFFFFFFFh (4294967295) Слово, збільшене учетверо зі знаком 1000 0000 0000 0000h 7FFFF FFFF FFFF FFFFh

Слово, збільшене учетверо без знака 0000 0000 0000 0000h 0FFFF FFFF FFFF FFFFh

При складанні слова зі знаком 7F38h (32568) та слова 1707h (5895)

результат дорівнює 7FFFh (32767). Математична сума виявилася більшою за межу 7FFFh, і відбулося "насичення". Якщо ті ж самі два значення скласти як слова без знака, то вийде 963Fh (38463). В даному випадку "насичення" не відбувається, оскільки результат менший за максимально можливий FFFFh.

ММХ-команди умовно можна розділити на такі групи: команди передачі даних; – арифметичні команди (складання, віднімання, множення); – команди зсуву; логічні команди; команди порівняння; команди упакування і розпаковування.

16.1. ММХ-команди передачі даних

MOVD приймач, джерело MOVQ приймач, джерело

Копіювання 32-розрядного числа Копіювання 64-розрядного числа

Команда movd копіює 32-розрядне число:

Page 376: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

375

– з молодших розрядів одного ММХ-регістра в молодші розряди іншого (старші розряди заповнюються нулями);

– із змінної в пам’яті або з цілочисельного регістра в молодші 32 розряди ММХ-регістра (старші розряди заповнюються нулями);

– з молодших розрядів ММХ-регістра в елемент пам’яті або в цілочисельний регістр.

Команда movq виконує копіювання 64 біт: – з одного ММХ-регістра в іншій: movq mmxi, mmxj; – з пам’яті в ММХ-регістр: movq mmxi, mem; – з ММХ-регістра в пам’ять: movq mem, mmxj. Серед всіх ММХ-команд тільки movd і movq можуть мати

вихідний операнд в пам’яті, а movd – єдина команда, операнд якої може знаходитися в 32-розрядному регістрі процесора.

Для визначення підтримки ММХ-команд можна скористатися програмою з листингу 16.1.

Листинг 16.1. Тестова програма для визначення підтримки ММХ-

команд: .686 ; директива визначення типу мікропроцесора .model flat ; лінійна модель пам’яті option casemap: none ; відмінність малих та великих літер

.data ; директива визначення даних testMMX DB 1 ; збереження у 8-розрядній комірці пам’яті

; змінної testMMX .code ; директива початку коду програми

st: ; мітка початку програми з ім’ям st mov EAX, 1 cpuid ; ідентифікація мікропроцесора

test EDX, 800000h ; edx:= edx ∧ 80 0000h – визначення 23 розряду jnz exit ; перейти на exit, якщо не нуль mov testMMX, 0

exit: xor EAX, EAX ; заповнення нулями еах mov AL, testMMX ret ; повернення керування ОС end st ; директива закінчення програми з ім’ям st Програма з листингу 16.1 повертає 1 у регістр AL, якщо технологія

ММХ підтримується процесором.

Page 377: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

376

16.2. Арифметичні ММХ-команди

16.2.1. Команди додавання ММХ-команди паралельного додавання працюють з упакованими

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

PADDB, PADDW, PADDD приймач, джерело

Циклічне додавання байтів (В), слів(W), подвійних слів(D)

Команди paddb, paddw, paddd виконують циклічне додавання.

Якщо сума виходить за межу допустимого діапазону, то, за правилами циклічної арифметики, надлишок відлічується від іншої межі діапазону (результат отримується шляхом віднімання максимально допустимого числа від цього результату). Перенесення одиниці з одного елемента даних в іншій не відбувається. Вхідний операнд може знаходитися в ММХ-регістрі або в пам’яті; вихідний операнд повинен знаходитися в ММХ-регістрі.

PADDSB, PADDSW, приймач, джерело

Додавання зі знаковим насиченням

Команди paddsb, paddsw виконують додавання із знаковим

насиченням. Якщо сума виходить за граничне значення допустимого діапазону, то результатом вважається це граничне значення. Вхідний операнд може знаходитися в ММХ-регістрі або в пам’яті; вихідний операнд повинен знаходитися в ММХ-регістрі.

PADDUSB, PADDUSW, приймач, джерело

Додавання з беззнаковим насиченням

Команди paddusb, paddusw виконують додавання з беззнаковим

насиченням. Якщо сума виходить за межі граничного значення з допустимого діапазону, то результатом вважається це граничне значення. Вхідний операнд може знаходитися в ММХ-регістрі або в пам’яті; вихідний операнд повинен знаходитися в ММХ-регістрі.

Page 378: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

377

Максимальне значення для насичення байтів розміром у слово дорівнює 65 535.

Розглянемо програму переведення великих літер в малі. Різниця між числовими значеннями цих літер складає 20h.

Листинг 16.2. Програма переведення великих літер в малі за

допомогою команди циклічного паралельного додавання байтів paddb: .686 ; директива визначення типу мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті

; та угоди ОС Windows .MMX ; директива визначення команд MMX option casemap:none ; відмінність малих та великих літер includelib \masm32v9_0\lib\kernel32.lib ExitProcess proto :dword

.data ; директива визначення даних mas1 DB " STUDENTS OF THE UNIVERSITY" len EQU $-mas1 ; len := 26 – обчисл. кількості байтів повідомлення mas2 DB len DUP (20h) ; резервування 26 байтів зі значенням 20h masOut DB len DUP(‘ ‘),0 ; масив збереження модифікованих даних .code ; директива початку коду програми _st: ; для налагоджування як самостійної програми

_paddb_ex proc ; початок процедури з ім’ям _paddb_ex mov EAX, len ; завантаження кількості байтів у еах mov EBX, 8 ; максимальна кількість слів xor EDX, EDX ; ініціалізація EDX перед діленням div EBX ; визначення кількості циклів по 8 байт mov ECX, EAX lea ESI, mas1 ; завантаження адреси масиву mas1 lea EDI, masOut ; завантаження адреси масиву masOut lea EBX, mas2 ; завантаження адреси масиву mas2

m1: movq MM0, qword ptr [ESI] ; занесення 8 байтів масиву mas1 в ММ0

paddb MM0, qword ptr [EBX] ; mas1 + mas2 movq qword ptr [EDI], MM0 ; збереження результату в masOut add ESI, 8 ; підготування нової адреси даних масиву mas1 add EDI, 8 ; підготування нової адреси даних масиву masOut add EBX, 8 ; підготування нової адреси даних масиву mas2

loop m1 ; перейти на m1, якщо ecx ≠ 0 cmp EDX, 0 ; порівняння залишку

Page 379: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

378

jz exit ; перейти на exit, якщо EDX = 0 (z = 1) mov ECX, EDX

m2: mov AL, byte ptr [ESI] add AL, 20h mov byte ptr [EDI], AL inc ESI ; esi := esi + 1 inc EDI ; edi := edi + 1 dec ECX ; ecx := ecx – 1 jnz m2 ; перейти на m2, якщо не нуль (есх ≠ 0)

exit: lea eax,masOut ; збереження адреси масиву masOut invoke ExitProcess, 0 ; повернення керування ОС Windows

; та визволення ресурсів _paddb_ex endp ; закінчення процедури end _st ; для налагоджування як самостійної програми

Програма з листингу 16.2 виконує паралельну обробку даних

обсягом по 8 байтів. Вікно початкових даних налагоджувача перед виконанням програми наведено на рис. 16.1.

Обробку даних по 8 байтів виконують команди від мітки next: до

команди loop m1. Команда cmp EDX, 0 обчислює байти, що залишились, та вже послідовно оброблює їх командами від mov ECX, EDX до мітки exit: (рис. 16.2).

Модифіковані символи зберігаються в області пам’яті masOut. Масив masOut на 1 більше, ніж масиви mas2 та mas1, за рахунок нуля на кінці. Цей нуль необхідний для того, щоб головна програма на мові С++ визначила кінець рядка. Головну зовнішню програму наведено у листингу 16.3.

Рис. 16.1. Вікно початкових даних налагоджувача перед виконанням програми з листингу 16.2

Page 380: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

379

Листинг 16.3. Головна зовнішня програма для процедури з листингу 16.1:

#include <stdio.h> extern “C” chаr* paddb_ex(void); int main(void) { print(“PADDB res:\n”) printf(“%s\n”, paddb_ex()); return 0; } У цій програмі процедура paddb_ex об’явлена як зовнішня, яка

повертає результат у вигляді рядка (специфікатор chаr). Програма виводить на екран рядок

Рис. 16.2. Вікна налагоджувача при виконанні програми з листингу 16.2

Page 381: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

380

PADDB res: students@of@the@university

Розглянемо програму використання команди paddw та додавання

за допомогою двох масивів даних (дані – розміром у слово).

Листинг 16.4. Додавання двох масивів даних за допомогою команди paddw:

.686 ; директива визначення типу мікропроцесора

.model flat ; завдання лінійної моделі пам’яті

.MMX ; директива визначення команд MMX option casemap:none ; відмінність малих та великих літер

.data ; директива визначення даних mas1 DW 1, 20000, 30000, 40000, 100, 40000, 3, 50000, 6000 mas2 DW 2, 40000, 50000, 25538, 200, 40000, 1, 0, 60000 len EQU $-mas2 ; обчислення кількості байтів масиву mas2 sum DW len DUP(0) ; резервування байтів під змінну sum

.code ; директива початку коду програми _st: ; мітка початку програми з ім’ям st _paddw1 proc ; початок підпрограми (процедури) з іменем _paddw1

mov EAX, len ; eax := 18 = 12h shr EAX, 1 ; кількість слів в eax := 9 (ділення на 2) mov EBX, 4 xor EDX, EDX ; додавання за модулем 2 (онулення EDX) div EBX ; eax := 2 , edx := 1 mov ECX, EAX lea ESI, mas1 ; esi := addr mas1 lea EDI, mas2 ; edi := addr mas2 lea EBX, sum ; ebx := addr sum

m1: movq MM0, qword ptr [ESI] ; paddw MM0, qword ptr [EDI] ; паралельне циклічне додавання movq qword ptr [EBX], MM0 add ESI, 8 ; підготовка адреси mas1 до нового зчитування add EDI, 8 ; підготовка адреси mas2 до нового зчитування add EBX, 8 ; підготовка адреси sum до нового зчитування loop m1 ; ecx := ecx – 1 та перехід, якщо ecx ≠ 0 cmp EDX, 0 ; порівняння з нулем jz exit ; перейти, якщо edx = 0

Page 382: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

381

mov ECX, EDX m2:

mov AX, word ptr [ESI] add AX, word ptr [EDI] mov word ptr [EBX], AX add ESI, 2 add EDI, 2 add EBX, 2 dec ECX jnz m2

exit: lea EAX, sum ; збереження адреси масиву sum ret ; повернення з процедури _paddw1 endp ; закінчення процедури end _st ; закінчення програми з ім’ям _st Головну зовнішню програму для виклику програми з листингу 16.4

наведено на листингу 16.5. Листинг 16.5. Головна зовнішня програма для виклику програми з

листингу 16.4: #include <stdio.h> extern "C" unsigned short int* paddw_ex(void); int main(void) { unsigned short int* paddw = paddw_ex(); printf(‘PADDW result:\n"); for (int i1 = 0; i1 < 9; i1++) { printf(“%d ", *paddw++); } return 0; } Головна програма повертає вказівник типу unsigned short int. Цей

тип вказівника використовується для адресації беззнакового цілого 16-розрядного числа (діапазон зміни 0 – 65 535), що відповідає типу повертаного процедурою paddw_ex значення.

Page 383: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

382

Процес отримання результату у вікнах налагоджувача наведено на рис. 16.3.

Розглянемо результат додавання двох масивів: Команда додавання слів paddw формує результат за принципом

циклічного перенесення, що означає таке: якщо сума для формату слова перевищує максимально допустиме число 65 536, то результат отримується як різниця між отриманим числом та цією межею. Наприклад,

30 000 + 50 000 = 80 000, 80 000 – 65 536 = 14 464.

Рис. 16.3. Вікна налагоджувача при виконанні програми з листингу 16.4

1, 20000, 30000, 40000, 100, 50000, 3, 50000, 6000 2, 40000, 50000, 25538, 200, 40000, 1, 0, 60000 3, 60000, 14464, 2, 300, 24464, 4, 50000, 464

+

Page 384: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

383

16.2.2. Команди віднімання ММХ-команди паралельного віднімання, як і команди додавання,

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

PSUBB, PSUBW, PSUBD,PSUBQ приймач, джерело

Віднімання байтів (B), слів(W), подвійних слів(D), збільшених учетверо слів(Q) за правилами циклічної арифметики

Команди віднімання psubb, psubw, psubd,psubq

застосовуються для виконання операції між операндами (байтами, словами, подвійними словами). Якщо при віднімання виникає позика, то вона ігнорується. Вхідний операнд може знаходитися в ММХ-регістрі або в пам’яті; вихідний операнд повинен знаходитися в ММХ-регістрі:

psubb/w/d/q mmxi, mmxj/mem64. При циклічній арифметиці при виході результату за межі діапазону

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

PSUBSB, PSUBSW, приймач, джерело

Віднімання байтів (В), слів(W) зі знаковим насиченням

При виконанні команд psubsb, psubsw зі знаковим насиченням,

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

Максимальна межа для знакових чисел розміром у слово:

FFFF/2 = 7FFF = 32 767. Проте, з урахуванням нульового значення, остаточна межа складає

32 768.

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

для слів -30000 5000 -32768

-

Page 385: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

384

Листинг 16.6. Програма віднімання двох масивів даних розміром у байт:

.686 ; директива визначення типу мікропроцесора

.model flat ; завдання лінійної моделі пам’яті

.MMX ; директива визначення команд MMX option casemap:none ; відмінність малих та великих літер

.data ; директива визначення даних mas1 DB 5,-5, -200, 100,-150, 21, 55, 25, 5 mas2 DB 2,-2, 200,-200, 150,-11, -79, 20, 3 len EQU $-mas2 ; визначення кількості байтів в масиві mas2 res DB len dup (0)

.code ; директива початку коду програми _st: ; мітка початку програми з ім’ям _st _psub_ex proc

mov EAX, len ; eax := 9 mov EBX, 8

xor EDX, EDX ; заповнення нулями EDX (додавання за модулем 2) div EBX ; визначення кількості груп по 8 байтів та залишку mov ECX, EAX ; збереження у лічильнику цілої частини lea ESI, mas1 ; збереження в ESI адреси масиву mas1 lea EDI, mas2 ; збереження в EDI адреси масиву mas2 lea EBX, res ; збереження в EBX адреси масиву res

m1: movq MM0, qword ptr [ESI] ; занесення 8 байтів mas1 в ММ0 movq MM1, qword ptr [EDI] ; занесення 8 байтів mas2 в ММ1 psubb MM0, MM1 ; паралел. віднімання байтів та збереж. в ММ0 movq qword ptr [EBX], MM0 ; збереження результату в масиві res add ESI, 8 ; підготування нової адреси даних масиву mas1 add EDI, 8 ; підготування нової адреси даних масиву mas2 add EBX, 8 ; підготування нової адреси даних масиву res

loop m1 ; ecx := ecx – 1 та перехід, якщо ecx ≠ 0

cmp EDX, 0 ; порівняння залишку jz exit ; перейти, якщо edx = 0 mov ECX, EDX ; занесення залишку в лічильник

Page 386: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

385

m2: mov AL, byte ptr [ESI] sub AL, byte ptr [EDI] mov byte ptr [EBX], AL add ESI, 1 add EDI, 1 add EBX, 1 loop m2 ; ecx := ecx – 1 та перехід, якщо ecx ≠ 0

exit: lea EAX, word ptr res ; збереження адреси масиву res ret ; повернення з процедури

_psub_ex endp ; закінчення процедури з ім’ям _psub_ex end _st ; закінчення програми з ім’ям _st Процес отримання результату у вікнах налагоджувача наведено на

рис. 16.4.

Рис. 16.4. Вікна налагоджувача при виконанні програми з листингу 16.5

Page 387: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

386

Розглянемо результат додавання двох масивів: Слід ураховувати, що результати наведено у додаткових кодах.

Наприклад, –200 – 200 = – 400, │400│ – 256 = 144, 70h = 0111 0000 дод = 1001 0000пр = 144,

2Сh = 0010 1100 = 44, D4h = 1101 0100дод = 0010 1100 = 44 і т.д.

PSUBUSB, PSUBUSW, приймач, джерело

Беззнакове віднімання байтів (В), слів (W) з насиченням

Команди psubusb, psubusw виконують віднімання беззнакових

байтів або слів з насиченням.

16.2.3. Команди множення ММХ-команди попарно (паралельно) перемножують 16-розрядні

слова операндів. Всі команди формують результат за принципом циклічної арифметики.

PMULHW, приймач, джерело Старше множення

Команда pmulhw виконує попарне множення 16-розрядних слів зі

знаками. Результатом операції є чотири 32-розрядних добутки, при цьому старші розряди зберігаються в 16-розрядних словах вихідного операнда, а молодші розряди не зберігаються.

PMULLW, приймач, джерело Молодше множення

Команда pmullw виконує попарне множення 16-розрядних слів зі

знаком вхідного і вихідного операндів, що дає чотири 32-розрядних добутків. Молодші розряди добутку зберігаються в 16-розрядних словах вихідного операнда, а старші розряди добутку втрачаються. Вхідним операндом може виступати ММХ-регістр або елемент пам’яті, а вихідним операндом повинен бути ММХ-регістр.

5, -5, -200, 100, -150, 21, 55, 25, 5 2, -2, 200, -200, 150, -11, -79, 20, 3 3, FDh, 70h, 2Ch, D4h 20h, 86h, 5h, 2h

-

Page 388: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

387

PMADDWD, приймач, джерело Множення та додавання Команда pmaddwd виконує попарне множення 16-розрядних слів

зі знаком, які знаходяться в двох операндах. Після отримання в результаті чотирьох 32-розрядних добутків перший добуток складається з другим, а третій – з четвертим. Суми записуються в 32-розрядні слова вихідного операнда. Якщо всі слова на вході дорівнюють 8000h, то результат дорівнює 8000 0000h (єдиний випадок, коли перемножування негативних чисел дає негативний результат). Вхідним операндом може виступати ММХ-регістр або елемент пам’яті, а вихідним операндом повинен бути ММХ-регістр. Алгоритм роботи команди pmaddwd наведено на рис. 16.4.

Команди pmulhw і pmullw дозволяють виконати множення чотирьох 16-розрядних операндів одночасно, при цьому розрядність результатів множення виявляється в два рази більшою за розрядність операндів. Для отримання повного результату множення за допомогою цих команд необхідно виконати таку послідовність кроків:

1. Одержати старші 16 біт добутку, використовуючи команду pmulhw.

2. Одержати молодші 16 біт добутку, використовуючи команду pmullw.

3. Об’єднати добутки в одне подвійне слово за допомогою команд punpckhwd і punpcklwd.

16.3. ММХ-команди пакування та розпакування даних

ММХ-команди пакування перетворюють довгі елементи даних (16-

і 32-розрядні слова) в короткі. Якщо початкове значення не розміщується в короткому форматі даних, то відбувається насичення. В такому випадку результатом вважається граничне значення допустимого діапазону вихідного типу даних. Цими командами можна користуватися для збільшення числа значущих розрядів при обчисленнях.

PACKSSWB, PACKSSDW приймач, джерело

Пакування зі знаковим насичуванням

Команди packsswb, packssdw перетворюють довгі дані (16- і

32-розрядних слів із знаком) в короткі (байти або 16-розрядні слова зі знаком). Якщо початкове значення було за межами допустимого

Page 389: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

388

діапазону для вихідного типу даних, то результатом пакування вважається найближче граничне значення діапазону. Вхідним операндом може виступати ММХ-регістр або елемент пам’яті; вихідний операнд повинен знаходитися в ММХ-регістрі. Наприклад, дію команди packsswb ММ0, MM1 наведено на рис. 16.5.

Розглянемо практичний приклад використання команди packsswb. Листинг 16.7. Програма пакування знакових слів у байти за

допомогою команди packsswb: .686 ; директива визначення типу мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті

; та угоди ОС Windows .MMX ; директива визначення команд MMX option casemap:none ; відмінність малих та великих літер includelib \masm32v9_0\lib\kernel32.lib ExitProcess proto :dword

.data ; директива визначення даних mas1 DW 01, -21, 02, -128, -01, 10, 128, 5, 1, 2 len EQU $-mas1 ; обчислення кільк. байтів змінної mas1 res DB len DUP(0) ; резервування байтів для змінної res

.code ; директива початку коду програми _st: ; мітка початку програми з ім’ям st

mov EAX, len ; eax := 14h = 20 shr EAX, 1 ; eax := 0Ah = 5

xor EDX, EDX ; заповнювання нулями EDX (додав. за модулем 2) mov EBX, 8

0005 0080 000A FFFF FF80 0002 FFEB 0001

05 7F 0A FF

63 48 47 32 31 16 15 0

Рис. 16.5. Дія команди packsswb ММ0, MM1

ММ1 ММ0

packsswb ММ0, MM1 ММ0

80 02 EB 01 63 56 55 48 47 40 39 32 31 24 23 16 15 8 7 0

5 128 10 -01 63 48 47 32 31 16 15 0 -128 02 -2 1

Page 390: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

389

div EBX ; edx := 0, eax := 8 mov ECX, EAX lea ESI, mas1 ; збереження в ESI адреси масиву mas1 lea EDI, res ; збереження в EDI адреси масиву res

m1: movq MM0, qword ptr [ESI] ; 8 байтів в масив mas1 в ММ0 movq MM1,[esi+8] ; занесення 8 байтів масиву mas1 в ММ1 packsswb MM0, MM1 ; movq qword ptr [EDI], MM0 ; збереження результату в пам’яті

add ESI, 16 ; esi := 10 add EDI, 4 ; edi := 14 loop m1 ; ecx := ecx – 1 та перехід, якщо ecx ≠ 0 cmp EDX, 0 ; порівняння залишку je exit ; перейти, якщо дорівнює

exit: lea EAX, res ; збереження адреси масиву res invoke ExitProcess, 0 ; повернення керування ОС Windows

; та визволення ресурсів end _st ; директива закінчення програми з ім’ям _st Програма з листингу 16.7 упаковує слова, які розташовані по

4 слова в масиві mas1. Команди add ESI, 16 ; esi := 10 add EDI, 4 ; edi := 14

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

Дві команди movq MM1,[esi+8] packsswb MM0, MM1

наведено для того, щоб наочніше простежити за процесом перетворення операндів. Ці команди можна замінити однією командою packsswb MM0, [esi+8].

Процес отримання результату у вікнах налагоджувача наведено на рис. 16.6.

PACKUSWB приймач, джерело

Пакування з беззнаковим насичуванням

Page 391: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

390

Команда packuswb виконує перетворення 16-розрядних слів зі знаком з обох операндів в байти без знака і записує їх у вихідний операнд. Якщо початкове слово зі знаком було більше FFh, результатом перетворення вважається FFh. Якщо початкове слово зі знаком негативне, результатом перетворення вважається 00h. Вхідним операндом може виступати ММХ-регістр або елемент пам’яті; вихідний операнд повинен знаходитися в ММХ-регістрі. Наприклад, дію команди packssdw ММ0, MM1 наведено на рис. 16.7.

63 32 31 0

Рис. 16.7. Дія команди packssdw ММ0, MM1

ММ1 ММ0 packssdw ММ0, MM1

ММ0

63 32 31 0

63 48 47 32 31 16 15 0

Рис. 16.6. Вікна налагоджувача при виконанні програми з листингу 16.7

Page 392: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

391

PUNPCKHBW, PUNPCKHWD, PUNPCKHDQ приймач, джерело

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

Команди punpckhbw, punpckhwd, punpckhdq виконують

попарне об’єднання початкових елементів даних (байтів, 16- або 32-розрядних слів), що знаходилися в ст арших 32 розрядах обох операндів. Результат об’єднання записується у вихідний операнд (приймач). Початкові значення молодших розрядів операндів на результат не впливають. Вхідним операндом може виступати ММХ-регістр або елемент пам’яті, вихідний операнд повинен знаходитися в ММХ-регістрі:

punpckhbw/d/q mmxi, mmxj/mem64. Якщо відомо, що при формуванні нового збільшеного учетверо

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

Розглянемо практичний приклад використання команди punpckhbw. Наприклад, дію команди punpckhbw ММ0, mem наведено на рис. 16.8.

Листинг 16.8. Програма використання команди punpckhbw для

об’єднання двох масивів даних розміром у байт: .686 ; директива визначення типу мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті

; та угоди ОС Windows .MMX ; директива визначення команд MMX option casemap: none ; відмінність малих та великих літер includelib \masm32v9_0\lib\kernel32.lib

Рис. 16.8. Дія команди punpckhbw ММ0, mem

mem ММ0 punpckhbw ММ0, mem

ММ0 0D F8 0C F9 0B FA 0A FB 63 56 55 48 47 40 39 32 31 24 23 16 15 8 7 0

13 12 11 10 -8 -7 -6 -5 0D 0C 0B 0A F8 F9 FA FB

Page 393: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

392

ExitProcess proto :dword .data ; директива визначення даних

str1 DB -1, -2, -3, -4, -5, -6, -7, -8 str2 DB 6, 7, 8, 9, 10, 11, 12, 13 res DB 8 DUP(0)

.code ; директива початку коду програми _st: ; мітка початку програми з ім’ям st

movq MM0, qword ptr str1 punpckhbw MM0, qword ptr str2 movq qword ptr res, MM0 lea EAX, res ; збереження адреси масиву res invoke ExitProcess, 0 ; повернення керування ОС Windows

; та визволення ресурсів end _st ; закінчення програми з ім’ям _st Програма повертає в регістр EAX адресу масиву res. Дія команди

punpckhbw ММ0, mem полягає в створенні 64-розрядного слова з двох старших половинок операндів, які розміщуються у регістрах ММ0 та mem (див. рис. 16.8).

Вікна налагоджувача при виконанні програми з листингу 16.8 наведено на рис. 16.9.

У цих вікнах в регістрі ММ0 залишився зміст створеного

64-розрядного слова, яке потім було збережене в комірках пам’яті, починаючи з адреси 00403010.

Рис. 16.9. Вікна налагоджувача при виконанні програми з листингу 16.8

Page 394: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

393

Схема на рис. 16.10 показує дію команди punpckhwd з використанням регістрів MM0 та MM1.

Команда punpckhdg розпаковує старші подвійні слова операндів в операнд-приймач.

Схема на рис. 16.11 показує дію команди punpckhdg з

використанням регістрів MM0 та MM1.

PUNPCKLBW, PUNPCKLWD, PUNPCKLDQ приймач, джерело

Розпакування та об’єднання молодших елементів

Команди punpcklbw, punpcklwd, punpckldq виконують

попарне об’єднання початкових елементів даних (байтів, 16- або 32-розрядних слів), що знаходилися в молодших 32 розрядах обох операндів. Результат об’єднання записується у вихідний операнд (приймач). Початкові значення старших розрядів операндів на результат

Рис. 16.10. Дія команди punpckhwd ММ0, ММ1

ММ1

ММ0 punpckhwd ММ0, ММ1

63 48 47 32 31 16 15 0

63 48 47 32 31 16 15 0

63 48 47 32 31 16 15 0 ММ0

Рис. 16.11. Дія команди punpckhdg ММ0, ММ1

ММ1

ММ0 punpckhdg ММ0, ММ1 63 32 31 0

ММ0

63 32 31 0

63 32 31 0

Page 395: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

394

не впливають. Вхідним операндом може виступати ММХ-регістр або елемент пам’яті; вихідний операнд повинен знаходитися в ММХ-регістрі.

Механізм роботи команд розпаковування стане зрозумілішим, якщо подивитися на рисунки, що ілюструють їх роботу (рис. 16.12 – 16.14).

Рис. 16.12. Дія команди punpcklbw MM0. MM1

MM1 ММ0 punpcklbw ММ0, MEM1

ММ0 63 56 55 48 47 40 39 32 31 24 23 16 15 8 7 0

Рис. 16.14. Дія команди punpckldg ММ0, ММ1

ММ1

ММ0 punpckldg ММ0, ММ1

63 32 31 0

ММ0

63 32 31 0

63 32 31 0

Рис. 16.13. Дія команди punpcklwd ММ0, ММ1

ММ1

ММ0 punpcklwd ММ0, ММ1

63 48 47 32 31 16 15 0 ММ0

63 48 47 32 31 16 15 0 63 48 47 32 31 16 15 0

Page 396: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

395

16.4. ММХ-команди порівняння ММХ-команди порівняння попарно порівнюють елементи даних

(байти, 16- або 32-розрядні слова) вхідного і вихідного операндів. Залежно від результату порівняння відповідний елемент даних вихідного операнда заповнюється нулями або одиницями. Ці команди, як і вся решта ММХ-команд, не встановлюють ознак виконання операції.

ММХ-команди порівняння діляться на дві групи: команди звичайного порівняння (дорівнює або не дорівнює); команди порівняння за величиною (більше або менше). Операції порівняння проводяться над байтами, словами і

подвійними словами.

PCMPEQB, PCMPEQW, PCMPEQD приймач, джерело

Перевірка на рівняння

Команди pcmpeqb, pcmpeqw, pcmpeqd виконують попарне

порівняння елементів даних (байтів, 16- або 32-розрядних слів) вхідного і вихідного операндів. Якщо елемент даних вихідного операнда дорівнює відповідному елементу вхідного, то такий елемент вихідного операнда заповнюється одиницями. Якщо елементи не рівні, то він заповнюється нулями. Вхідним операндом можуть виступати ММХ-регістр або елемент пам’яті, а вихідний операнд повинен знаходитися в ММХ-регістрі.

PCMPGTB, PCMPGTW, PCMPGTD приймач, джерело

Порівняння на більше

Команди pcmpgtb, pcmpgtw, pcmpgtd виконують попарне

порівняння елементів даних (байтів, 16- або 32-розрядних слів із знаком) вхідного і вихідного операндів. Якщо елемент даних вихідного операнда більше відповідного елементу вхідного, то такий елемент вихідного операнда заповнюється одиницями. Якщо ж він не більше вхідного, то він заповнюється нулями. Вхідний операнд може знаходитися в ММХ-регістрі або в пам’яті, а вихідний операнд – в ММХ-регістрі.

Page 397: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

396

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

Розглянемо програму паралельного порівняння двох масивів

знакових чисел розміром у байт за допомогою команд pcmpeqb та pcmpgtb (листинг 16.9).

Листинг 16.9. Програма паралельного порівняння двох масивів

цілих чисел розміром у байт кожен: .686 ; директива визначення типу мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті

; та угоди ОС Windows .MMX ; директива визначення команд MMX option casemap: none ; відмінність малих та великих літер includelib \masm32v9_0\lib\kernel32.lib ExitProcess proto :dword

.data ; директива визначення даних mas1 DB -1, -2, 3, 4, 0, 1, 12, -8 mas2 DB -1, -2, 3, 4, 0, 1, 12, -8 res DB 16 DUP (5)

.code ; директива початку коду програми _st: ; мітка початку програми з ім’ям st

movq MM0, qword ptr mas1 ; занесення 8 байтів масиву mas1 pcmpeqb MM0, qword ptr mas2 ; попарне порівняння на рівняння

movq qword ptr res, MM0 ; збереження результату в пам’яті movq MM1, qword ptr mas1 pcmpgtb MM1, qword ptr mas2 ; попарне порівняння на більше movq qword ptr res+8, MM1 ; збереження результату в пам’яті lea EAX, res ; збереження в EAX адреси масиву res invoke ExitProcess, 0 ; повернення керування ОС Windows

; та визволення ресурсів end _st ; закінчення програми з ім’ям _st Початкові значення комірок пам’яті наведено на рис. 16.15.

Page 398: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

397

Для того щоб відрізнити початкові значення масиву res, в кожну

комірку пам’яті, починаючи з 00403010, занесено 05h. У зв’язку з тим, що масиві однакові, то за командою pcmpeqb MM0, qword ptr mas2 в регістр ММ0 заносяться всі одиниці. А за командою pcmpgtb MM1, qword ptr mas2 в регістр ММ1 заносяться всі нулі (рис. 16.16).

Рис. 16.15. Початкові значення комірок пам’яті налагоджувача при виконанні програми з листингу 16.9

Рис. 16.16. Вікна налагоджувача при виконанні програми з листингу 16.8

Page 399: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

398

Програма повертає командою lea EAX, res адресу масиву res в регістр EAX.

16.5. Логічні ММХ-команди

Логічні ММХ-команди виконують порозрядні логічні операції над

всіма 64 бітами своїх операндів. Ці команди реалізують логічні операції І, АБО, І-НІ, виключене АБО.

PAND приймач, джерело Логічне І (порозрядне множення)

Команда pand (логічне І) обчислює порозрядне логічне І своїх

операндів: pand mmxi, mmxj/mem64.

PANDN приймач, джерело

Логічне І – НІ (порозрядні інверсія та множення)

Команда pandn (логічне І – НІ) обчислює звернення (порозрядне

НІ) вихідного операнда, а потім порозрядне логічне І між вхідним операндом і оберненим значенням вихідного:

pandn mmxi, mmxj/mem64.

РОR приймач, джерело Логічне АБО (порозрядне додавання) Команда роr (логічне АБО) обчислює порозрядне логічне АБО

своїх операндів: pand mmx, mmx/mem64.

РХОR приймач, джерело Виключне АБО

Команда рхоr (виключне АБО) обчислює порозрядне логічне

виключне АБО своїх операндів (додаток за модулем два): pxor mmxi, mmxj/mem64.

16.6. Команди зсуву

Команди ММХ-зсуву виконують зсув кожного елемента даних (16-,

Page 400: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

399

32- або 64-розрядного слова) у вихідному операнді на величину, що задається вхідним операндом. Серед команд зсуву виділяють команди арифметичного і логічного зсуву. При виконанні команд арифметичного зсуву розряди елементів, що звільняються, заповнюються знаком числа (старший біт) і можуть набувати значення, такі, як 0 і 1, тоді як при виконанні команд логічного зсуву, розряди, що звільнилися, заповнюються нулями.

PSLLW, PSLLD, PSLLQ приймач, джерело Логічний зсув ліворуч

Команди psllw, pslld, psllq виконують логічний зсув ліворуч

елементів даних (16-, 32- або 64-розрядних слів) у вихідному операнді на число бітів, що задається вхідним операндом. Молодші розряди, що звільнилися, заповнюються нулями. Вхідний операнд може бути безпосереднім операндом або може знаходитися в ММХ-регистрі чи в пам’яті:

psllw/d/q mmxi, imm8/mmxj/mem64.

PSRLW, PSRLD, PSRLQ приймач, джерело Логічний зсув праворуч Команди psrlw, psrld, psrlq виконують логічний зсув елементів

даних праворуч (16-, 32- або 64-розрядних слів) у вихідному операнді на число бітів, що задається вхідним операндом. Старші розряди, що звільнилися, заповнюються нулями. Вхідний операнд може бути безпосереднім операндом або може знаходитися в ММХ-регістрі чи в пам’яті. Вихідний операнд повинен знаходитися в ММХ-регістрі:

psrlw/d/q mmxi, imm8/mmxj/mem64.

PSRAW, PSRAD приймач, джерело Арифметичний зсув праворуч Команди psraw, psrad виконують арифметичний зсув елементів

даних праворуч (16- або 32-розрядних слів) у вихідному операнді на число бітів, що задається вхідним операндом. Якщо зсовується позитивне число, то старші розряди, що звільнилися, заповнюються нулями; якщо негативне – то одиницями. Вхідний операнд може бути безпосереднім операндом або може знаходитися в ММХ-регістрі чи в пам’яті. Вихідний операнд повинен знаходитися в ММХ-регістрі:

psraw/d mmxi, imm8/mmxj/mem64.

Page 401: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

400

Приклад використання ММХ-команд зсуву розглянуто в програмі з листингу 16.10.

Листинг 16.10. Приклад використання ММХ-команд зсуву: .686 ; директива визначення типу мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті

; та угоди ОС Windows .MMX ; директива визначення команд MMX option casemap:none ; відмінність малих та великих літер includelib \masm32v9_0\lib\kernel32.lib ExitProcess proto :dword

.data ; директива визначення даних mas1 dw 2, 4369, 273, 15 ; масив слів розміром в слово a1 dq 2 ; визначення кількості бітів зсуву res dq 3 dup (0) ; масив результату розміром 64 × 3 бітів

.code ; директива початку коду програми _st: ; мітка початку програми з ім’ям st

movq MM0, qword ptr mas1 ; занесення масиву mas1 в ММ0 psllw MM0, qword ptr a1 ; логічний зсув слів ліворуч movq qword ptr res, MM0 ; збереження результату в пам’яті movq MM1, qword ptr mas1 psrlw MM1, qword ptr a1 ; логічний зсув слів праворуч movq qword ptr res+8, MM1 ; movq MM2, qword ptr mas1 psraw MM2, qword ptr a1 ; арифметичний зсув слів праворуч movq qword ptr res+16, MM2 ; invoke ExitProcess, 0 ; повернення керування ОС Windows

; та визволення ресурсів end _st ; закінчення програми з ім’ям _st У наведеній програмі паралельно завантажується весь масив даних

у відповідний регістр ММХ. Потім виконується зсув та запис результату в визначені раніше комірки пам’яті. При цьому треба приділити увагу правильності використання директиви визначення даних для кількості бітів зсуву a1 dq 2, від якої результат може бути істотно змінений.

Вікна налагоджувача при виконанні програми з листингу 16.11 наведено на рис. 16.17.

Page 402: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

401

16.7. ММХ-команди в Pentium ІІІ

Ці команди включено у всі покоління процесорів Intel Pentium,

починаючи з Pentium ІІІ. Деякі з них наводяться нижче. Команди pavgb, pavgw обчислюють середнє значення двох чисел,

наведених байтами або словами. Значення операндів інтерпретуються як беззнакові цілі числа. Як вхідний операнд можуть виступати ММХ-регістр або 64-розрядний елемент пам’яті; вихідним операндом служить

Рис. 16.17. Вікна налагоджувача при виконанні програми з листингу 16.11

Page 403: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

402

один з ММХ-регістрів: pavgb/w mmxi, mmxj/mem64.

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

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

рextrw r32/r64, mmx, imm8. Команда pinsrw вставляє слово в одне з чотирьох упакованих слів

вихідного операнда. Вихідним операндом є один з ММХ-регістрів, а вхідним операндом може виступати один з 32-розрядних регістрів загального призначення, молодше слово якого буде вставлене у вихідний операнд. Номер позиції, куди поміщається операнд, визначається молодшими двома бітами маски і може набувати значення від 0 до 3:

pinsrw mmx, r32/mem16, imm8.

Команди pmaxub, pmaxsw обчислюють максимальне значення з кожної пари упакованих елементів у вихідному і вхідному операндах. Операції можуть виконуватися як над беззнаковими байтами (pmaxub), так і над знаковими словами (pmaxsw). Як вихідним операндом може виступати ММХ-регістр, а вхідним – ММХ-регістр або 64-розрядний елемент пам’яті, то:

pmaxub/w mmxi, mmxj/mem64. Команди pminub, pminsw обчислюють мінімальне значення з

кожної пари упакованих елементів у вихідному і вхідному операндах. Операції можуть виконуватися як над беззнаковими байтами (pminub), так і над знаковими словами (pminsw). Як вихідним операндом може виступати ММХ-регістр, а вхідним – ММХ-регістр або 64-розрядний елемент пам’яті, то:

pminub/w mmxi, mmxj/mem64. Команда pmovmskb формує байт, що містить знакові біти восьми

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

Page 404: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

403

виступати один з ММХ-регістрів. Вихідним операндом є 32-розрядний регістр загального призначення, молодший байт якого міститиме результат. Ця команда дуже зручна для формування умовних галужень в програмах:

pmovmskb r32/r64, mmx/mem64. Команда psadbw обчислює сумарну різницю значень беззнакових

байтів вхідного і вихідного операндів. Вхідним операндом може виступати ММХ-регістр або 64-разрядний елемент пам’яті, а вихідним – один з ММХ-регістрів:

psadbw mmxi, mmxj/mem64. Команда psignb/w/d виконує заперечення упакованих цілих чисел

в mmxi, якщо знак в mmxj менше нуля: psignb/w/d mmxi, mmxj /mem64.

16.8. ММХ-команди в Pentium IV З появою Pentium 4 ММХ-команди дістали доступ до 128-бітових

регістрів (хmm). В цих командах першим операндом записується приймач інформації (dest), а другим – джерело (src).

Наведемо приклади ММХ-команд та їх опис: paddq хmm,хmm/mem128 – складання двох 128-бітових операндів; psubq хmm,хmm/mem128 – віднімання 128-бітових операндів; pmuludq хmm,хmm/mem128 – множення 64-бітових операндів.

Результат не повинен перевищувати 128-бітовий розмір;

pslldq xmm, imm8 – логічний зсув вмісту вліво на imm8 бітів; psrldq xmm, imm – логічний зсув вмісту вправо на imm8 бітів; pshufhw xmm xmm/mem128, imm – пересилання з перегрупуванням

чотирьох 16-бітових слів з молодшої половині dest в молодшу половину src. Перегрупування задається вмістом константи imm;

Page 405: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

404

pshuflw xmm xmm/mem128, imm – пересилання з перегрупуванням чотирьох 16-бітових слів із старшої половини dest в старшу половину src. Перегрупування задається вмістом константи imm;

pshufd xmm, xmm /mem128, imm – пересилання з перегрупуванням чотирьох 32-бітових слів з dest в src. Перегрупування задається вмістом константи imm;

punpckhqdq xmm, xmm /mem128 – у dest записується вміст старших половин src(xmm/m128) та dest;

punpcklqdq xmm, xmm/mem128 – у dest (xmm) записується вміст молодших половин src (xmm/m128) та dest;

movdq2q mmx, xmm – молодша половина хmm копіюється в mmx; mov2qdq xmm, mmx – вміст регістра mmx копіюється в молодшу

половину xmm; movntdq mem128,хmm – пересилання вмісту 128-бітового регістра в

пам’ять без кешування. Адреса повинна бути кратна 16;

movdqa хmm, хmm/m128 – пересилання 128-бітового коду; movdqa хmm/m128,хmm – пересилання даних з адресою, яка

кратна 16; movdqu xmm/mem128 – пересилання 128-бітового коду з пам’яті; movdqu xmm/mem128,хmm – пересилання даних, які можуть не мати

16-бітового вирівнювання movmskpd r32, хmm – копіювання вмісту знакових розрядів (63 і 127)

в біти 0 і 1 регістра г32. Решта біт регістра очищається;

maskmovdqu хmm, хmm – пересилання за маскою. Перший операнд хmm (src) містить код, що пересилається, другий операнд хmm (dest) – маску пересилання. Адреса третього (куди проводитиметься пересилка) операнда повинна знаходитися в DS:DI або в DS:EDI. Для

Page 406: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

405

кожного з 16-ти байтів виконується наступне: якщо знаковий розряд 1-го байта маски встановлений, то dest[i] = src[i]; якщо знаковий розряд байта маски очищений, то вміст dest не змінюється.

16.9. Лабораторна робота

“ММХ-команди” Мета заняття: – поглибити і закріпити знання з архітектури МП платформи х86 і

навички його програмуванню; – придбати практичні навички складання, налагодження і

виконання програм з використанням команд ММХ, написаних мовою асемблеру для програмування МП платформи х86.

Постановка задачі Згідно з останньою цифрою номера в групі вибрати варіант та

написати на асемблері програму обчислення одного з виразів з використанням дійсних чисел та виведенням їх на екран з використанням АРІ-функцій.

Завдання 1. 1. Виконати паралельне додавання 2-х масивів по 18 знакових

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

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

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

даних розміром у слово. 5. Виконати паралельне упакування 2-х масивів по 4 знакових

даних розміром у двійне слово. 6. Виконати паралельне множення 2-х масивів по 11 знакових даних

розміром у слово. 7. Скласти приклад та навести програму виконання команди ММХ

– pavgw. 8. Скласти приклад та навести програму виконання команди ММХ

– pinsrw.

Page 407: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

406

9. Скласти приклад та навести програму виконання команди ММХ – pmaxsw.

10. Скласти приклад та навести програму виконання команди ММХ – pminsw.

11. Скласти приклад та навести програму виконання команди ММХ – pmovmskb

12. Скласти приклад та навести програму виконання команди ММХ – psadbw.

13. Скласти приклад та навести програму виконання команди ММХ – pextrw.

Завдання 2 1. Виконати паралельне порівняння за допомогою ММХ-команд 2-х

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

a – e/c – ab, де a = 0,2; b = 10,05; c = 2,3; e = 21,07, інакше – виконати операцію ac.

2. Виконати паралельне порівняння за допомогою ММХ-команд 2-х масивів по 8 знакових цілих чисел розміром у байт. Якщо один масив більший від другого, то виконати операцію

(a – c)b + c/a, де a = 0,2; b = 10,05; c = 2,3; інакше – виконати операцію a – c.

3. Виконати паралельне порівняння за допомогою ММХ-команд 2-х масивів по 8 знакових цілих чисел розміром у байт. Якщо один масив більший від другого, то виконати операцію

(a – e)b – d/b, де a = 0,1; b = 1,05; c = 2,1; d = 3,2; інакше – виконати операцію d/b.

4. Виконати операцію паралельного логічного додавання за допомогою ММХ-команд над масивами цілих чисел. Якщо друге слово більше 55, то виконати операцію

a – e/b – de, де a = 0,2; b = 8,05; c = 2,2; d = 3,3; інакше – виконати операцію a – e/b.

5. Виконати операцію паралельного логічного множення за допомогою ММХ-команд над масивами цілих чисел. Якщо друге слово більше 55, то виконати операцію

(b + d)/ba – с, де a = 0,2; b = 7,05; c = 2,3; d = 3,4; інакше – виконати операцію ba – с.

6. Виконати операцію паралельного додавання за модулем рхоr за допомогою ММХ-команд над масивами цілих чисел. Якщо друге слово

Page 408: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

407

менше 15, то виконати операцію (b – dс)/a – с, де a = 0,2; b = 6,05; c = 1,3; d = 3,5;

інакше – виконати операцію b – dс. 7. Виконати команду логічного зсуву ліворуч pslld та залежно від

значення другого байта виконати операцію ae – d/c – b, де a = 1,2; b = 5,05; c = 0,3; d = 3,5;

інакше – виконати операцію d/c. 8. Виконати команду арифметичного зсуву елементів даних

праворуч psraw та залежно від значення другого байта виконати операцію

(ab – d)/b – d, де a = 3,6; b = 9,17; c = 2,8; d = 3,9; інакше – виконати операцію ab – d.

9. Виконати команду логічного зсуву елементів даних праворуч psrlw та залежно від значення другого байта виконати операцію:(de – e)/(c – a), де a = 3,1; b = 9,11; c = 2,3; d = 5,5; інакше – виконати операцію de – e.

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

a/b – cd, де a = 4,5; b = 12,3; c = 2,5; d = 6,5; інакше – виконати операцію a/b – d.

Зміст звіту 1. Постановка задачі для конкретного варіанта. 2. Блок-схема алгоритму виконання прикладу з детальним

коментарем та описом роботи. 3. Листинг програми з виведенням даних на екран монітора з

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

4. Рrint screen екрана 32-розрядного налагоджувача з виконаною програмою.

5. Висновки за результатами роботи. Приклад 16.1. Виконати паралельне порівняння 2-х масивів по 8

знакових даних розміром у байт. Якщо старші половини масивів однакові, то виконати операцію

a – b/4, де a = 0,2; b = 10,05, інакше – ні.

Програму обчислення прикладу наведено у листингу 16.12.

Page 409: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

408

Листинг 16.12. Програма обчислення прикладу 16.1: title CopyRight by Rysovaniy A. N. [email protected] .686 ; директива визначення типу мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті

; та угоди ОС Windows .MMX ; директива визначення команд MMX

option casemap: none ; відмінність малих та великих літер include \masm32v9_0\include\windows.inc include \masm32v9_0\include\kernel32.inc include \masm32v9_0\include\fpu.inc includelib \masm32v9_0\lib\user32.lib includelib \masm32v9_0\lib\kernel32.lib includelib \masm32v9_0\lib\fpu.lib BSIZE equ 30

.data ; директива визначення даних str1 DB -1, -2, 3, 4, 0, 1, 12, -8 str2 DB -1, -2, 3, 4, 0, 1, 12, -8 res DB 8 DUP (5) a1 DWORD 0.2 b1 DWORD 10.05 c1 DWORD 4.

stdout DWORD ? ; резервування в пам’яті 32-розрядної комірки ; з ім’ям stdout для збереження дескриптора виведення

cWritten DWORD ? ; резервування 32-розрядної комірки пам’яті ; з ім’ям cWritten для адреси символів виведення

buf BYTE BSIZE dup (?) ; кількість байтів для запису послід. символів res2 DWORD ?

.code ; директива початку коду програми _st: ; мітка початку програми з ім’ям _st

movq MM0, qword ptr str1 pcmpeqb MM0, qword ptr str2 movq qword ptr res, MM0 emms ; визволити регістри ММХ add dword ptr res,0 jz m1 finit ; ініціалізація співпроцесора fld b1 ; занесення в вершину стека b1 fld c1 ; занесення в вершину стека c1

Page 410: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

409

fdiv fld a1 ; занесення в вершину стека a1 fsub st(0),st(1) ; fst res2

m1: invoke GetStdHandle, STD_OUTPUT_HANDLE

mov stdout, eax ; збереження одержаного дескриптора у пам’яті invoke FpuFLtoA, \ ; АРІ-функція перетворення 80-розр. числа 0, \ ; адреса числа, що відображається 10, \ ; кількість десяткових знаків після коми (10) ADDR buf, \ ; адреса буфера для символів, які перетворяться SRC1_FPU or SRC2_DIMM ; адреса 80-розр. числа та саме число invoke WriteConsoleA, \ ; АРІ-функція виведення на екран

stdout, \ ; дескриптор стандартного пристрою виведення ADDR buf, \ ; адреса початку повідомлення

BSIZE, \ ; розмір повідомлення ADDR cWritten, \ ; адреса, де зберігається число символів

NULL invoke ExitProcess, 0 ; повернення керування ОС Windows

; та визволення ресурсів end _st ; директива закінчення програми Результат виконання програми з листингу 16.12 наведено на

рис. 16.18. Він дорівнює -2,3125… . Результат також можна отримати у вікні налагоджувача OllyDbg,

наприклад так, як наведено на рис. 16.19.

Рис. 16.18. Результат виконання програми з листингу 16.12

Page 411: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

410

Вікна налагоджувача після виконання програми з листингу 16.12

наведено на рис. 16.20. Рис. 16.20. Вікна налагоджувача після виконання програми листингу 16.12

Рис. 16.19. Результат виконання програми з листингу 11.8 в вікні налагоджувача OllyDbg

Page 412: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

411

Крім наведених методів виведення результатів слід

використовувати виведення у вікно консолі як найбільш прогресивний метод (листинг 16.13).

Листинг 16.13. Програма з виведенням результату у вікно консолі: title CopyRight by Rysovaniy A. N. and Bessonov D.S. KIT-26a .686 ; директива визначення типу мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті

; та угоди ОС Windows .MMX ; директива визначення команд MMX

option casemap: none ; відмінність малих та великих літер include \masm32v9_0\include\windows.inc include \masm32v9_0\include\kernel32.inc include \masm32v9_0\include\fpu.inc include \masm32v9_0\include\user32.inc includelib \masm32v9_0\lib\user32.lib includelib \masm32v9_0\lib\kernel32.lib includelib \masm32v9_0\lib\fpu.lib

.data ; директива визначення даних

str1 DB -1, -2, 3, 4, 0, 1, 12, -8 str2 DB -1, -2, 3, 4, 0, 1, 12, -8 res DB 8 DUP (5) a1 DWORD 0.2 b1 DWORD 10.05 c1 DWORD 4. res2 DD ?

st1 db "result",0 st2 db 10 dup(?),0

.code ; директива початку коду програми

_st: ; мітка початку програми з ім’ям _st movq MM0, qword ptr str1 ; копіювання 64-розрядного числа pcmpeqb MM0, qword ptr str2 movq qword ptr res, MM0 ; збереження результату

emms ; остання ММХ-команда (для співпроцесора) add dword ptr res,0 ; порівняння старшої частини res jz m1 ; перехід на m1, якщо ст. частина дорівнює нулю

Page 413: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

412

finit ; ініціювання співпроцесора fld b1 ; завантаження у вершину стеку ST(0) змінної b1 fld c1 ; завантаження у вершину стеку ST(0) змінної с1 fdiv ; st(0) := st(1)/st(0) fld a1 ; завантаження у вершину стеку ST(0) змінної а1 fsub st(0),st(1) ; st(0) := st(0) – st(1) ;fst res2 ; можливе збереження у пам’яті

m1: invoke FpuFLtoA, \ ; АРІ-функція перетворення 80-розр. числа

0, \ ; адреса числа, що відображається 10, \ ; кількість десяткових знаків після коми (10)

ADDR st2, \ ; адреса буфера для символів, які перетворяться SRC1_FPU or SRC2_DIMM ; адреса 80-розр. числа та саме число

invoke MessageBox, \ ; АРІ-функція виведення вікна консолі

NULL, \ ; hwnd – ідентифікатор вікна addr st2, \ ; адреса рядка, яка містить текст повідомлення

addr st1, \ ; адреса рядка, яка містить заголовок повідомлення MB_OK ; вид діалогового вікна

invoke ExitProcess, 0 ; повернення керування ОС Windows

; та визволення ресурсів end _st ; директива закінчення програми Результат виконання програми з листингу 16.13, отриманий за

допомогою АРІ-функції MessageBox, наведено у вигляді вікна на рис. 16.21.

Рис. 16.21. Результат виконання програми

з листингу 16.13

Page 414: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

413

За назву вікна відповідає параметр addr st1. Вікна налагоджувача після виконання програми з листингу 16.13

наведено на рис. 16.22. У випадку необхідності порівняння всього масиву 8-ми байтових

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

Рис. 16.22. Вікна налагоджувача після виконання програми з листингу 16.13

Page 415: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

414

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

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

(a – c)/b + c, де a = 0,2; b = 10,05; c = 2,3; інакше – виконати операцію a – c.

Листинг 16.14. Програма обчислення прикладу 16.2: title CopyRight by Rysovaniy A. N. [email protected] .686 ; директива визначення типу мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті

; та угоди ОС Windows .MMX ; директива визначення команд MMX

option casemap: none ; відмінність малих та великих літер include \masm32\include\windows.inc include \masm32\include\kernel32.inc include \masm32\include\fpu.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\fpu.lib BSIZE equ 30

.data ; директива визначення даних str1 db -1, -2, 3, 2, 5, 1, 12, -8 ; резервування в пам’яті комірок

; для чисел масиву str1 str2 db -1, -2, 3, 2, 0, 1, 12, -8 ; res DD 8 DUP (0) ; резервування в пам’яті комірок для res a1 DWORD 0.2 ; константа а b1 DWORD 10.05 ; константа b c1 DWORD 2.3 ; константа с

stdout DWORD ? ; резервування в пам’яті 32-розрядної комірки ; з ім’ям stdout для збереження дескриптора виведення

cWritten DWORD ? ; резервування 32-розрядної комірки пам’яті ; з ім’ям cWritten для адреси символів виведення

buf BYTE BSIZE dup (?) ; кільк. байтів для запису послід. символів res2 DWORD ? .code ; директива початку коду програми

_st: ; мітка початку програми з ім’ям _st lea esi,str1 ; занесення в esi адреси масиву str1 lea edi,str2 ; занесення в edi адреси масиву str2

Page 416: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

415

movq MM0, qword ptr [esi] ; занесення 8-ми байтів до Рг ММ0 pcmpeqb MM0, qword ptr [edi] ; перевірка на рівняння movq qword ptr res, MM0 ; збереження результату порівняння emms ; визволити регістри ММХ

cmp dword ptr res,0 ; порівняння старшої частини результату jnz m1 ; перейти на m1 якщо результат не нульовий

cmp dword ptr res+4,0 ; порівняння молодшої частини рез. jnz m1 ; перейти на m1 якщо результат не нульовий

finit ; ініціалізація співпроцесора fld c1 ; занесення у вершину стеку st(0) змінної с1 fld b1 ; занесення у вершину стеку st(0) змінної b1 fld a1 ; занесення у вершину стеку st(0) змінної а1

fsub st(0),st(2) ; a – c та збереження в st(0) fdiv st(0),st(1) ; (a – c)/b та збереження в st(0) fadd st(0),st(2) ; (a – c)/b + а та збереження в st(0) fst res2 ; збереження вершини стеку в пам’яті з ім’ям res2 jmp m2 ; безумовний перехід на мітку m2

m1: finit ; ініціалізація співпроцесора

fld c1 ; занесення у вершину стеку st(0) змінної с1 fld a1 ; занесення у вершину стеку st(0) змінної а1

fsub st(0),st(1) ; а1 – с1 та збереження рез. у вершині стеку fst res2 ; збереження вершини стеку в пам’яті з ім’ям res2

m2: invoke GetStdHandle, STD_OUTPUT_HANDLE mov stdout, eax ; збереження одержаного дескриптора у пам’яті invoke FpuFLtoA, \ ; АРІ-функція перетворення 80-розр. числа

0, \ ; адреса числа, що відображається 10, \ ; кількість десяткових знаків після коми (10)

ADDR buf, \ ; адреса буфера для символів, які перетворяться SRC1_FPU or SRC2_DIMM ; адреса 80-розр. числа та саме число

invoke WriteConsoleA, \ ; АРІ-функція виведення на екран stdout, \ ; дескриптор стандартного пристрою виведення

ADDR buf, \ ; адреса початку повідомлення BSIZE, \ ; розмір повідомлення

ADDR cWritten, \ ; адреса, де зберігається число символів NULL

invoke ExitProcess, 0 ; повернення керування ОС Windows

Page 417: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

416

; та визволення ресурсів end _st ; директива закінчення програми

Процес виконання програми наведено у вікні налагоджувача

OllyDbg на рис. 16.23.

Рис. 16.23. Вікна налагоджувача OllyDbg при виконанні програми з листингу 16.14

Page 418: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

417

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

рис. 16.24.

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

Рис. 16.24. Результат виконання програми з листингу 16.14

Page 419: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

418

17. SSE-РОЗШИРЕННЯ У 3D-графіці часто зустрічаються групи операцій, які можна

виконати за один такт за допомогою SIMD-команд (single instruction, multiple data, тобто одна команда – багато даних). Такими операціями є інтерполяція векторів, скалярне множення векторів, нормування векторів, інтерполяція компонент кольору (наприклад, RGB) і так далі. До SIMD-команд відносяться й команди SSE-розширення.

SSE-розширення з’явилося в процесорах Intel Pentium III і доповнює MMX-розширення засобами обробки даних з плаваючою крапкою (http://www.intel.com/design/pentium4/manuals/ index_new.htm #aorm). SSE-команди можна паралельно обробляти з командами математичного співпроцесора. Набір інструкцій SSE-розширення складається з 70 команд.

SSE-розширення реалізоване як апаратно-програмний модуль, який включає додаткові вісім регістрів розрядністю в 128 біт, що мають позначення ХММ0 – ХММ7 і 32-розрядний регістр керування/стану MXCSR.

SSE-команди призначені для роботи з даними у форматі з плаваючою крапкою. Вмістом ХММ-регістра є чотири 32-розрядні операнди з плаваючою крапкою в короткому форматі (Single Precision Floating Point, SPFP) [9 – 10]. Формат подання даних SSE-розширення наведено на рис. 17.1.

127 96 95 64 63 32 31 0

Рис. 17.1. Формат даних SSE-розширень

Порядок Мантиса

31 30 23 23 0 знак

Page 420: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

419

Кожне 32-розрядне число з плаваючою комою має 1 знаковий біт, 8

бітів порядку і 23 біта мантиси, що відповідає стандарту IEEE-754 на формат подання чисел одинарної точності з плаваючою комою.

Діапазон зміни чисел в SSE-форматі дорівнює 2-126 – 2127. У зв’язку з тим, що формати команд співпроцесора та SSE-команд

не однакові, то в деяких випадках при різних межах вирівнювання результати обчислень з використанням форматів FPU і SSE можуть розрізнятися.

Структура полів регістра керування/стану (MXCSR) багато в чому нагадує ту, що реалізована в регістрах стану (swr) і керування (cwr) математичного співпроцесора. Станом обчислень можна керувати шляхом установлення певних значень в поля цього регістра.

Значна частина команд може виконуватися в двох варіантах:

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

Команди паралельних арифметичних операцій обробляють одночасно 4 подвійних слова і мають в своїй мнемоніці суфікс ps.

Команди скалярних операцій обробляють тільки молодші 32-розрядні подвійні слова упакованих операндів, не зачіпаючи при цьому три старші подвійні слова. Виняток становлять деякі команди скалярного пересилання даних. Мнемонічне позначення цих команд включає суфікс ss.

У процесі обробки даних команди SSE-розширення можуть

порушувати виняткові ситуації, які виникають, якщо відбувається одна з наступних подій:

некоректна операція (invalid operation); денормалізований операнд (denormalized operand); ділення на 0 (divide-by-zero); арифметичне переповнювання (numeric overflow); втрата значущих розрядів (numeric underflow); втрата точності (inexact result). При виникненні виняткових ситуацій встановлюються біти 0 – 5 в

регістрі керування/стану (MXCSR). Кожна виняткова ситуація може бути замаскована шляхом установлення в 1 бітів 7 – 12 регістра MXCSR. Якщо яке-небудь виключення замасковане, то воно обробляється

Page 421: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

420

процесором за стандартним алгоритмом, після чого продовжується виконання програмного коду. Формат полів регістра MXCSR і їх призначення наведено на рис. 17.2.

Найбільше значення в регістрі керування/стану команд SSE-

розширень займають біти 13 – 14 поля rc. За умовчанням встановлюється режим округлення до найближчого значення числа з плаваючою крапкою в короткому форматі.

Ці біти можна встановити програмно, причому можливі такі комбінації:

00 – округлення до найближчого числа; 01 – округлення до меншого числа; 10 – округлення до більшого числа; 11 – округлення з відкиданням дробової частини. Біт 15 використовується, якщо результат операції близький до нуля.

При цьому процесор виконує такі дії: – повертає значення 0 і знак результату; – встановлює прапорці Р (біт 5) і U (біт 4); – маскує біти виключень. Команди SSE-розширення можна розділити на декілька груп: команди передавання даних; арифметичні команди; команди порівняння; команди перетворення; логічні команди;

31 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Рис. 17.2. Регістр керування/стану команд SSE-розширень

D Z O U P R I D Z O U P С R FZ Резерв

Прапорці виключних подій Зарезервовано

Маска виключних подій Режим округлення

Біт переходу до нуля

I

Page 422: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

421

додаткові команди. Для визначення підтримки SSE-команд можна скористатися

програмою з листингу 17.1. Листинг 17.1. Тестова програма для визначення підтримки SSE-

команд: .686 ; директива визначення типу мікропроцесора .model flat ; лінійна модель пам’яті option casemap: none ; відмінність малих та великих літер .data ; директива визначення даних

testSSE DB 1 .code ; директива початку коду програми st: ; мітка початку програми з ім’ям st

mov EAX, 1 cpuid ; ідентифікація мікропроцесора test EDX, 2000000h ; edx:= edx ∧ 200 0000h (25 розряд) jnz exit ; перейти на exit, якщо не нуль mov testSSE, 0

exit: xor EAX, EAX mov AL, testSSE ret ; повернення керування ОС end st ; закінчення програми з ім’ям st Програма з листингу 17.1 повертає 1 у регістр AL, якщо технологія

SSE підтримується процесором.

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

MOVAPS приймач, джерело Пересилання вирівняних по 16-байтовій межі 128-розрядних операндів

Команда movaps пересилає вирівняні по 16-байтовій межі 128-

розрядних операндів. Як вхідний операнд може бути ХММ-регістр або 128-розрядний елемент пам’яті; вихідним операндом може бути один з ХММ-регістрів. Якщо адреса елемента пам’яті не буде вирівняна по 16-байтовій межі, то відбудеться виключення загального захисту:

movaps xmm, xmm/mem128; movaps xmm/mem128, xmm.

Page 423: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

422

MOVUPS приймач, джерело Пересилання невирівняних по 16-

байтовій межі 128-розрядних операндів Команда movups пересилає невирівняні дані; як вхідний операнд

може бути ХММ-регістр або 128-розрядний елемент пам’яті; вихідним операндом може служити один з ХММ-регістрів. Команда не вимагає вирівнювання по 16-байтовій межі:

movups xmm, xmm/mem128; movups xmm/mem128, xmm.

MOVHPS приймач, джерело

Пересилання невирівняних старших 64 бітів з вхідного операнда у вихідний

Команда movhps пересилає невирівняні 64 бітів з вхідного

операнда у вихідний. Один з операндів обов’язково повинен бути ХММ-регістром; як другий може бути 64-розрядний елемент пам’яті. Пересилаються тільки старші 64 біт вхідних операндів. Молодші 64 біт обох операндів не змінюються. Якщо дані передаються з ХММ-регістра, то пересиланню підлягають тільки старші 64 біта. Команда не вимагає вирівнювання по 16-байтовій межі адреси елемента пам’яті:

movhps xmm,mem64; movhps mem64,xmm.

MOVHLPS приймач, джерело

Пересилання невирівняних старших 64 бітів з вхідного операнда у вихідний

Команда movhlps пересилає невирівняні 64 бітів з вхідного

операнда у вихідний. Обидва операнди повинні знаходитися в XММ-регістрах. Пересилаються тільки старші 64 біт вхідних операндів. У результаті виконання цієї команди змінюют ься молодші 64 біт регістра-приймача:

movhlps xmmi, xmmj. Схему виконання команди movhps наведено на рис. 17.3.

MOVLHPS приймач, джерело

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

Page 424: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

423

Команда movlhps пересилає невирівняні 64 бітів з вхідного

операнда у вихідний. Обидва операнди повинні знаходитися в ХММ-регістрах. Пересилаються тільки молодші 64 біт вхідних операндів.

У результаті виконання цієї команди змінюют ься ст арші 64 біт

регістра-приймача: movlhps xmmi, xmmj.

Схему виконання команди movlhps наведена на рис. 17.4.

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

Команда movlps пересилає невирівняні 64 бітів з вхідного

операнда у вихідний. Один з операндів обов’язково повинен бути ХММ-регістром, як другий може бути 64-розрядний елемент пам’яті. Пересилаються тільки молодші 64 біт вхідних операндів. Старші 64 біт обох операндів не змінюються. Якщо дані передаються з ХММ-регістра,

Рис. 17.3. Дія команди movhps XММ1, XMM0

XММ1 XММ0 movhps XММ1, XMM0

ММ0

127 64 63 0

127 64 63 0

127 64 63 0

Рис. 17.4. Дія команди movhps XММ1, XMM0

XММ1 XММ0 movhps XММ1, XMM0

ММ0

127 64 63 0

127 64 63 0

127 64 63 0

Page 425: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

424

то пересилвнню підлягають тільки молодші 64 біти. Команда не вимагає вирівнювання по 16-байтовій межі адреси елементу пам’яті:

movlps xmmi, mem64; movlps mem64,xmm.

MOVMSKPS приймач, джерело Пересилання знакових бітів 32-

розрядних слів Команда movmskps пересилає знакові біти кожного з чотирьох

упакованих чисел вхідного операнда в молодших чотири біта вихідного операнда. Як вхідний операнд може бути тільки ХММ-регістр, а як вихідний операнд – 32-розрядний регістр загального призначення. Ця команда використовується для організації умовних переходів:

movmskps r32, xmm; movmskps r64,xmm.

MOVSS приймач, джерело Пересилання 32 молодших бітів

Команда movss пересилає 32 молодших бітів з джерела в приймач,

при цьому як мінімум один з операндів повинен бути ХММ-регістром. Другий операнд повинен бути 32-розрядним елементом пам’яті. При виконанні операції пересилки з операнда в пам’яті молодші 32 біт поміщаються в молодших 32 біт ХММ-регістра.

Якщо виконується пересилання з ХММ-регістра, то вибираються молодші 32 розряди регістра, решта розрядів не змінюється:

movss xmm, xmm/mem32; movss xmm/mem32, xmm.

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

(приклад 17.1).

Рис. 17.4. Дія команди movhps XММ1, mem0

mem1 movlps XММ0, mem1

ММ0

63 0

127 64 63 0

Page 426: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

425

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

масиву на молодше слово другого масиву. Хай надано два масиви даних: 1357 та 0246. Сформувати масив

даних 5746. Процес отримання результату можна виконати за допомогою

команди movhlps (рис. 17.5).

Листинг 17.2. Приклад використання команд передавання даних: .686 ; директива визначення типу мікропроцесора .model flat ; завдання лінійної моделі пам’яті .XMM ; директива визначення команд XMM-розширення

option casemap:none ; відмінність малих та великих літер .data ; директива визначення даних

mas1 DD 0,2,4,6 ; резервування комірок пам’яті для масиву mas1 mas2 DD 1,3,5,7 ; резервування комірок пам’яті для масиву mas2 res DD 4 DUP(0) ; резервування комірок пам’яті для масиву res .code ; директива початку коду програми

_movhlps_ex proc movups XMM0, mas1 ; пересилання невирівняними даними movups XMM1, mas2

movhlps XMM0, XMM1 ; пересилання з обміном невирівн. 64 бітами movups res, XMM0 ; запам’ятання результату lea EAX, res ; запам’ятання адреси масиву результату ret ; повернення з процедури

_movhlps_ex endp ; закінчення процедури еnd ; закінчення програми Приклад використання команд зсуву реалізовано у вигляді

процедур.

Рис. 17.5. Процес отримання результату командою movhlps

XMM1 := 13 57

XMM0 := 02 46 XMM0 := 57 46

мол. ст.

мол. ст.

Page 427: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

426

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

17.2.1. Команди додавання

ADDPS приймач, джерело Паралельне додавання 128-розрядних

операндів Команда addps виконує паралельне додавання 128-розрядних

операндів, при цьому як вхідний операнд (операнд-джерело) може бути один з ХMM-регістрів або 128-розрядного елемента пам’яті. Вихідним операндом команди (операндом-приймачем) є один з ХММ-регістрів:

addps xmm, xmm/mem128.

ADDSS приймач, джерело Cкалярне складання операндів Команда addss виконує скалярне складання операндів. Молодші

подвійні слова операндів повинні бути числами з плаваючою крапкою в короткому форматі (single precision). Результат поміщається в операнд-приймач, яким може бути ХММ-регістр. Вхідним операндом можуть бути ХММ-регістр або 32-розрядний елемент пам’яті:

addss xmm, xmm/mem32. Листинг 17.3. Паралельне додавання 128-розрядних операндів: .686 ; директива визначення типу мікропроцесора .model flat ; завдання лінійної моделі пам’яті .XMM ; директива визначення конкретних команд option casemap:none ; відмінність малих та великих літер .data ; директива визначення даних

mas1 DD 12.13, -15.01, -325.12, 77.1 mas2 DD -25.25, 35.21, -34.56, 23.77 len EQU $- mas2 ; визначення кількості байтів масиву mas2 res DD len DUP(0) ; резервування пам’яті для res розміром DD

.code ; директива початку коду програми _addps_ex proc lea ESI, mas1 ; занесення адреси масиву mas1 в esi lea EDI, mas2 ; занесення адреси масиву mas2 в edi movups XMM0, [ESI] ; пересилання невирівняних 128-розр. даних addps XMM0, [EDI] ; паралельне додавання 128-розр. даних

Page 428: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

427

movups res, XMM0 ; пересилання невирівняних 128-розр. даних lea EAX, res ; збереження адреси масиву res в еах ret ; повернення з процедури _addps_ex endp ; закінчення процедури end ; закінчення програми

Листинг 17.4. Скалярне додавання масивів дійсних чисел: .686 ; директива визначення типу мікропроцесора .model flat ; завдання лінійної моделі пам’яті .XMM ; директива визначення команд XMM-розширення option casemap:none ; відмінність малих та великих літер

.data ; директива визначення даних mas1 DD 12.13, -15.01, -325.12, 77.1 mas2 DD -25.25, 35.21, -34.56, 23.77 len EQU $- mas2 res DD len DUP(0)

.code ; директива початку коду програми _addss_ex proc lea ESI, mas1 ; занесення адреси масиву mas1 в esi lea EDI, mas2 ; занесення адреси масиву mas2 в edi lea EBX, res ; занесення адреси масиву res в ebx mov ECX, len ; занесення кількості байтів у лічильник shr ECX, 2 ; ECX/4 – кількість 32-розрядних чисел

next: movd XMM0, dword ptr [ESI] ; занесення 32-розр. даних в XMM0 addss XMM0, dword ptr [EDI] ; скалярне додавання мол. 32 розр. movd dword ptr [EBX], XMM0 ; занесення 32-розр. даних в пам’ять

add ESI, 4 add EDI, 4 add EBX, 4

loop next lea EAX, res ; збереження адреси масиву res в еах

ret ; повернення з процедури _addss_ex endp ; закінчення процедури еnd ; закінчення програми

17.2.2. Команди віднімання

SUBPS приймач, джерело Паралельне віднімання 128-розрядних

Page 429: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

428

операндів Команда subps виконує паралельне віднімання 128-розрядних

операндів; як операнд-джерело буде один з ХММ-регістрів або 128-розрядний елемент пам’яті. Вихідним операндом команди є один з ХММ-регістрів:

subps xmm, xmm/mem128.

SUBSS приймач, джерело Cкалярне віднімання операндів Команда subss виконує скалярне віднімання операндів. Молодші

подвійні слова операндів повинні бути числами з плаваючою крапкою в короткому форматі. Результат поміщається в операнд-приймач, яким може бути ХММ-регістр. Вхідним операндом можуть бути ХММ-регістр або 32-розрядний елемент пам’яті:

subss xmm, xmm/mem32. Листинг 17.5. Паралельне віднімання 128-розрядних дійсних

чисел: .686 ; директива визначення типу мікропроцесора .model flat ; завдання лінійної моделі пам’яті .XMM ; директива визначення команд XMM-розширення option casemap:none ; відмінність малих та великих літер

.data ; директива визначення даних mas1 DD 12.13, -15.01, -325.12, 77.1 mas2 DD -25.25, 35.21, -34.56, 23.77 len EQU $- mas2 res DD len DUP(0)

.code ; директива початку коду програми _subps_ex proc lea ESI, mas1 ; занесення адреси масиву mas1 в esi lea EDI, mas2 ; занесення адреси масиву mas2 в edi movups XMM0, [ESI] subps XMM0, [EDI] movups res, XMM0 lea EAX, res ; збереження адреси масиву res в еах ret ; повернення з процедури _subps_ex endp ; закінчення процедури end ; закінчення програми

Page 430: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

429

17.2.3. Команди паралельного і скалярного множ ення

MULPS приймач, джерело Паралельне множення 128-розрядних

операндів Команда mulps виконує паралельне множення 128-розрядних

операндів; як операнд-джерело буде один з ХММ-регістрів або 128-розрядний елемент пам’яті. Вихідним операндом команди повинен бути один з ХММ-регістрiв:

mulps xmm, xmm/mem128.

MULSS приймач, джерело Cкалярне множення операндів Команда mulss виконує скалярне множення операндів. Молодші

подвійні слова операндів повинні бути числами з плаваючою крапкою в короткому форматі. Результат поміщається в операнд-приймач, яким повинен бути ХMM-регістр. Вхідним операндом можуть бути ХММ-регістр або 32-розрядний елемент пам’яті:

mulss xmm, xmm/mem128. Листинг 17.6. Паралельне множення 128-розрядних чисел: .686 ; директива визначення типу мікропроцесора .model flat ; завдання лінійної моделі пам’яті .XMM ; директива визначення команд XMM-розширення option casemap:none ; відмінність малих та великих літер

.data ; директива визначення даних mas1 DD 12.13, -15.01, -325.12, 77.1 mas2 DD -25.25, 35.21, -34.56, 23.77 len EQU $ - mas2 ; обчислення кількості байтів масиву mas2 res DD len DUP(0)

.code ; директива початку коду програми _mulps_ex proc lea ESI, mas1 ; занесення адреси масиву mas1 в esi lea EDI, mas2 ; занесення адреси масиву mas2 в edi movups XMM0, [ESI] mulps XMM0, [EDI] movups res, XMM0 lea EAX, res ; збереження адреси масиву res в еах

Page 431: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

430

ret ; повернення з процедури _mulps_ex endp ; закінчення процедури end ; закінчення програми

17.2.4. Команди паралельного і скалярного ділення

DIVPS приймач, джерело

Паралельне ділення 128-розрядних операндів

Команда divps виконує паралельне ділення 128-розрядних

операндів; як операнд-джерело буде один з ХММ-регістрів або 128-розрядний елемент пам’яті. Вихідним операндом команди повинен бути один з ХММ-регістрів, при цьому як ділене виступає операнд-приймач, а як дільник – операнд-джерело. Результат поміщається в операнд-приймач:

divps xmm, xmm/mem128.

DIVSS приймач, джерело Скалярне ділення операндів Команда divss виконує скалярне ділення операндів; молодші

подвійні слова операндів повинні бути числами з плаваючою крапкою в короткому форматі. Результат поміщається в операнд-приймач, яким повинен бути ХММ-регістр. Вхідним операндом можуть бути ХММ-регістр або 32-розрядний елемент пам’яті:

divss xmm, xmm/mem32. Листинг 17.7. Паралельне ділення 128-розрядних чисел: .686 ; директива визначення типу мікропроцесора .model flat ; завдання лінійної моделі пам’яті .XMM ; директива визначення команд XMM-розширення option casemap:none ; відмінність малих та великих літер

.data ; директива визначення даних mas1 DD 12.13, -15.01, -325.12, 77.1 mas2 DD -25.25, 35.21, -34.56, 23.77 len EQU $- mas2 res DD len DUP(0)

.code ; директива початку коду програми _divps_ex proc

Page 432: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

431

lea ESI, mas1 ; занесення адреси масиву mas1 в esi lea EDI, mas2 ; занесення адреси масиву mas2 в edi movups XMM0, [ESI] divps XMM0, [EDI] movups res, XMM0 lea EAX, res ; збереження адреси масиву res в еах ret ; повернення з процедури _divps_ex endp ; закінчення процедури end ; закінчення програми

17.2.5. Додат кові арифмет ичні команди

SQRTPS приймач, джерело

Паралельне обчислення квадратного кореня

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

кореня з упакованих чисел з плаваючою крапкою. Команда має два операнди: джерело і приймач. Як операнд-джерело може бути ХММ-регістр або 128-розрядний елемент пам’яті; як приймач – ХММ-регістр:

sqrtps xmm, xmm/mem128.

SQRTSS приймач, джерело

Скалярне обчислення квадратного кореня

Команда sqrtss виконує скалярне обчислення квадратного кореня

з упакованого числа з плаваючою крапкою. Як операнд-джерело можеь бути 32-розрядний елемент пам’яті або ХММ-регістр. У тому випадку, якщо джерелом є ХММ-регістр, використовується молодший 32-розрядний операнд, при цьому решта операндів не змінюється. Як операнд-приймач повинен бути ХММ-регістр:

sqrtss xmm, xmm/mem32. Розглянемо приклад паралельного обчислення квадратного кореня

з масиву упакованих чисел з плаваючою крапкою. Листинг 17.8. Паралельне обчислення квадратного кореня з масиву

упакованих чисел з плаваючою крапкою: .686 ; директива визначення типу мікропроцесора .model flat ; завдання лінійної моделі пам’яті

Page 433: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

432

.XMM ; директива визначення команд XMM-розширення option casemap:none ; відмінність малих та великих літер

.data ; директива визначення даних mas1 DD 12.13, 15.01, 325.12, 77.1, 55.66, 77.88 len EQU $- mas1 ; визначення кількості байтів масиву mas1 res DD len DUP(0) ; резервування пам’яті для масиву res

.code ; директива початку коду програми _sqrt_ex proc

mov EAX, len ; завантаження 24 байтів масиву mas1 shr EAX, 2 ; len/4 = 6 – визначення кількості чисел mov EBX, 4 xor EDX, EDX ; ініціалізація EDX перед діленням div EBX ; (eax, edx) визначення кількості циклів mov ECX, EAX ; кількість циклів – у лічильник lea ESI, mas1 ; завантаження адреси масиву mas1 lea EDI, res ; завантаження адреси масиву

next: sqrtps XMM0, [esi] ; паралельне обчислення квадратних коренів movups [EDI], XMM0 add ESI, 16 ; підготовка до нового циклу add EDI, 16 loop next ; перейти, якщо ecx ≠ 0 cmp EDX, 0 ; порівняння залишку jz exit mov ECX, EDX next1: sqrtss XMM0, [ESI] ; обчислення кореня скалярною командою movss [EDI], XMM0 ; скалярна пересилка add ESI, 4 add EDI, 4 dec ECX jnz next1 exit: lea EAX, res ; збереження адреси масиву res в еах ret ; повернення з процедури _sqrt_ex endp ; закінчення процедури end ; закінчення програми

Page 434: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

433

У прикладі початковий масив містить 6 подвійних слів (подання

коротких чисел з плаваючою крапкою). За допомогою команди sqrtps можна обробити 4 подвійних слова (16 байт), а ті, що залишилися (2 подвійних слова), – командою sqrtss.

MAXPS приймач, джерело

Паралельне обчислення квадратного кореня

Команда maxps виконує паралельне обчислення максимального

значення для кожної пари упакованих чисел з плаваючою крапкою. Команда має два операнди: джерело і приймач. Як операнд-джерело може бути ХММ-регістр або 128-розрядний елемент пам’яті; як приймач – ХММ-регістр, в який поміщаються максимальні елементи кожної пари. Вміст операнда-джерела після виконання операції не змінюється:

maxps xmm, xmm/mem128.

MINPS приймач, джерело

Паралельне обчислення мінімального значення для кожної пари упакованих чисел

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

значення для кожної пари упакованих чисел з плаваючою крапкою. Команда має два операнди: джерело і приймач. Як операнд-джерело може бути ХММ-регістр або 128-розрядний елемент пам’яті; як приймач – ХММ-регістр, в який поміщаються максимальні елементи кожної пари. Вміст операнда-джерела після виконання операції не змінюється:

minps xmm, xmm/mem128.

MAXSS приймач, джерело

Скалярне обчислення максимального значення для молодшої пари упакованих чисел 32-розрядних операндів

Команда maxss виконує скалярне обчислення максимального

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

Page 435: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

434

32-розрядне значення в пам’яті або молодший операнд ХММ-регістра. Після виконання операції вміст операнда-джерела залишається незмінним:

maxss xmm, xmm/mem32.

MINSS приймач, джерело

Скалярне обчислення мінімального значення для молодшої пари упакованих чисел 32-розрядних операндів

Команда minss виконує скалярне обчислення мінімального

значення для молодшої пари упакованих 32-розрядних операндів приймача і джерела. Результат поміщається в операнд-приймач, яким може бути один з ХММ-регістрів, при цьому його молодший операнд заміщається мінімальним значенням. Як операнд-джерело може бути 32-розрядне значення в пам’яті або молодший операнд ХММ-регістра. Після виконання операції вміст операнда-джерела залишається незмінним:

minss xmm, xmm/mem32. Арифметичні команди обчислення обернених значень Арифметичні команди обчислення обернених значень, як і

більшість SSE-команд, оперують або чотирма упакованими 32-розрядними значеннями (паралельні), або молодшими 32-розрядними операндами (скалярні). Команди обчислення обернених значень забезпечують точність не менше 11 бітів. Це означає, що максимальне значення відносної похибки буде менш ніж 1,5 × 2–12. Для кращого розуміння можна виразити значення відносної похибки формулою

RCPPS приймач, джерело Паралельне обчислення обернених значень упакованих операндів

Команда rcpps виконує паралельне обчислення обернених

значень упакованих операндів. Якщо X – значення одне з 32-розрядних операндів, то воно обчислюється як 1/х. Вхідний операндом може бути XMM-регістр або 128-розрядний елемент пам’яті, а вихідним операндом повинен бути ХММ-регістр:

точне значення – приблизне значення приблизне значення ≤ 1,5 × 2–12.

Page 436: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

435

rcpps xmm, xmm/mem128. RCPSS приймач, джерело

Скалярне обчислення оберненого значення молодшого 32-розрядного операнда

Команда rcpss виконує скалярне обчислення оберненого значення

молодшого 32-розрядного операнда. Як вхідний операнд може бути ХММ-регістр або 32-розрядний елемент пам’яті, а вихідним операндом повинен бути ХММ-регістр. Операція не зачіпає вмісту старших операндів ХММ-регістра:

rcpss xmm, xmm/mem32.

RSQRTPS приймач, джерело

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

Команда rsqrtps виконує паралельне обчислення обернених значень квадратного кореня упакованих операндів. Якщо X – значення з 32-розрядних операндів, то воно обчислюється як 1/√Х. Як вхідний операнд може використовуватися ХММ-регістр або 128-розрядний елемент пам’яті, а вихідним операндом повинен бути ХММ-регістр:

rsqrtps xmm, xmm/mem128.

RSQRTSS приймач, джерело

Скалярне обчислення оберненого значення квадратного кореня молодшого операнда

Команда rsqrtss виконує скалярне обчислення оберненого

значення квадратного кореня молодшого 32-розрядного операнда. Як вхідний операнд може бути ХММ-регістр або 32-розрядний елемент пам’яті, а вихідним операндом повинен бути ХММ-регістр. Операція не зачіпає вмісту старших операндів ХММ-регістра:

rsqrtss xmm, xmm/mem32.

17.3. Команди порівняння Команди порівняння дозволяють визначати відповідність операндів

вказаним умовам і, залежно від результату порівняння, встановлюють в потрібному елементі операнда-приймача двійкові нулі (якщо умова не виконується) або двійкові одиниці (якщо умова виконується). Команди порівняння можуть виконуватися паралельно над упакованими операндами, скалярні команди – над молодшими подвійними словами. Всі команди мають два операнди: як вхідний операнд, або операнд-

Page 437: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

436

джерело, може бути ХММ-регістр або елемент пам’яті (128-розрядна для паралельних команд і 32-розрядна для скалярних). Вихідним операндом, або операндом-приймачем, може бути тільки один з ХММ-регістрів, в якому задіяні або 128 бітів (паралельні команди), або молодші 32 біта (скалярні команди). Результ ат ом порівняння є або всі нулі, або всі одиниці.

Група паралельних команд порівняння

CMPEQPS приймач, джерело

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

Команда cmpeqps перевіряє умову рівності 32-розрядних

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

cmpeqps xmm, xmm.

CMPLTPS приймач, джерело

Паралельна перевірка умови «менше» для 32-розрядних упакованих операндів

Команда cmpltps перевіряє умову «менше» (less-than) для 32-

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

cmpltps xmm, xmm.

CMPLEPS приймач, джерело

Паралельна перевірка «менше або дорівнює» для 32-розрядних упакованих операндів

Команда cmpleps перевіряє умову «менше або дорівнює» (less-

than-or-equal) для 32-розрядних упакованих операндів і встановлює відповідні значення в операнді-приймачі. Вміст операнда-джерела після виконання операції не змінюється:

cmpleps xmm, xmm. CMPUNORDPS приймач, джерело

Паралельна перевірка умови «невпорядкованості» для 32-розрядних упакованих операндів

Команда cmpunordps перевіряє умову «невпорядкованості»

Page 438: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

437

(unordered) для 32-розрядних упакованих операндів і встановлює відповідні значення в операнді-приймачі. Вміст операнда-джерела після виконання операції не змінюється:

cmpunordps xmm, xmm.

CMPNEQPS приймач, джерело

Паралельна перевірка умови «не дорівненості» для 32-розрядних упакованих операндів

Команда cmpneqps перевіряє умову «не дорівнює» (not-equal-to)

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

cmpneqps xmm, xmm.

CMPNLTPS приймач, джерело

Паралельна перевірка умови «не менше» для 32-розрядних упакованих операндів

Команда cmpnltps перевіряє умову «не менше» (not-less-than) для

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

cmpnltps xmm, xmm.

CMPNLEPS приймач, джерело

Паралельна перевірка умови «не менше або дорівнює» для 32-розрядних упакованих операндів

Команда cmpnleps перевіряє умову «не менше або дорівнює»

(not-less-than-or-equal-to) для 32-розрядних упакованих операндів і встановлює відповідні значення в операнді-приймачі. Вміст операнда-джерела після виконання операції не змінюється:

cmpnleps xmm, xmm.

CMPORDPS приймач, джерело

Паралельна перевірка умови «впорядкованості» для 32-розрядних упакованих операндів

Команда cmpordps перевіряє умову «впорядкованості» (ordered)

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

Page 439: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

438

cmpordps xmm, xmm. Група скалярних команд порівняння

CMPEQSS приймач, джерело

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

Команда cmpeqss перевіряє умову рівності молодших 32-

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

cmpeqss xmm, xmm.

CMPLTPS приймач, джерело

Перевірка умови «менше» для молодших 32-розрядних упакованих операндів і встановлення відповідного значення в молодшому подвійному слові операнда-приймача

Команда cmpltps перевіряє умову «менше» (less-than) для

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

cmpltps xmm, xmm.

CMPLEPS приймач, джерело

Перевірка умови «менше або дорівнює» для молодших 32-розрядних упакованих операндів і встановлення відповідного значення в молодшому подвійному слові операнда-приймача

Команда cmpleps перевіряє умову «менше або дорівнює» (less-

than-or-equal) для молодших 32-розрядних упакованих операндів і встановлює відповідне значення в молодшому подвійному слові операнда-приймача. Вміст операнда-джерела після виконання операції не змінюється:

cmpleps xmm, xmm.

CMPUNORDPS приймач, джерело

Перевірка умови «невпорядкованості» для молодших 32-розрядних упакованих операндів і встановлення відповідного значення в молодшому

Page 440: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

439

подвійному слові операнда-приймача Команда cmpunordps перевіряє умову «невпорядкованості»

(unordered) для молодших 32-розрядних упакованих операндів і встановлює відповідне значення в молодшому подвійному слові операнда-приймача. Вміст операнда-джерела після виконання операції не змінюється:

cmpunordps xmm, xmm.

CMPNEQPS приймач, джерело

Перевірка умови «не дорівнює» для молодших 32-розрядних упакованих операндів і встановлення відповідного значення в молодшому подвійному слові операнда-приймача

Команда cmpneqps перевіряє умову «не дорівнює» (not-equal-to)

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

cmpneqps xmm, xmm.

CMPNLTPS приймач, джерело

Перевірка умови «не менше» для молодших 32-розрядних упакованих операндів і встановлення відповідного значення в молодшому подвійному слові операнда-приймача

Команда cmpnltps перевіряє умову «не менше» (not-less-than) для

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

cmpnltps xmm, xmm.

CMPNLEPS приймач, джерело

Перевірка умови «не менше або дорівнює» для молодших 32-розрядних упакованих операндів і встановлення відповідного значення в молодшому подвійному слові операнда-приймача

Команда cmpnleps перевіряє умову «не менше або дорівнює»

(not-less-than-or-equal-to) для молодших 32-розрядних упакованих операндів і встановлює відповідне значення в молодшому подвійному слові операнда-приймача. Вміст операнда-джерела після виконання

Page 441: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

440

операції не змінюється: cmpnleps xmm, xmm.

CMPORDPS приймач, джерело

Перевірка умови «впорядкованості» для молодших 32-розрядних упакованих операндів і встановлення відповідного значення в молодшому подвійному слові операнда-приймача

Команда cmpordps перевіряє умову «впорядкованості» (ordered)

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

cmpordps xmm, xmm.

COMISS/UCOMISS приймач, джерело

Скалярне порівняння молодших 32-розрядних операндів. Вміст обох операндів після виконання операції порівняння залишається незмінним, але в регістрі прапорців EFLAGS процесора певним чином встановлюються деякі прапорці

До групи команд порівняння входять ще дві команди: comiss і

ucomiss. Команди мають два операнди і виконують скалярне порівняння молодших 32-розрядних операндів. Особливістю цих команд є те, що вміст обох операндів після виконання операції порівняння залишається незмінним, але в регістрі прапорців EFLAGS процесора певним чином встановлюються прапорці ZF, PF і CF, а прапорці OF, SF і AF скидаються в 0. Вхідними операндами обох команд можуть бути ХММ-регістри або 32-розрядні змінні в пам’яті, вихідними операндами можуть бути тільки ХММ-регістри:

comiss xmm, xmm/mem32; ucomiss xmm, xmm/mem32.

Команди ucomiss та comiss відрізняються тим, що вони генерують

виняткові ситуації для різних форматів не-чисел (NAN). Ці команди дуже зручні при організації галужень в програмах, оскільки за станом прапорців можна по-різному інтерпретувати результат порівняння. У табл. 17.1 наводиться співвідношення між порівнюваними операндами і встановлюваними прапорцями.

Page 442: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

441

Таблиця 17.1

Результат порівняння op1 та ор2 ZF PF CF Операнди неврегульовані 1 1 1

opl < ор2 0 0 1 opl > ор2 0 0 0 opl = ор2 1 0 0

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

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

SSE-команд, в паралельному і скалярному контекстах. Наведемо цію групу команд.

CVTPS2PI приймач, джерело

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

Команда cvtps2pi виконує паралельне перетворення двох

молодших упакованих 32-розрядних чисел з плаваючою крапкою в короткому форматі в два 32-розрядних цілих числа. Команда має два операнди. Як вхідний операнд може бути ХММ-регістр або 128-розрядний елемент пам’яті. Вихідним операндом може служити один з регістрів ММХ. На результат перетворення впливає установлення бітів поля гс, що визначає режим округлення, регістра керування/стану (MXCSR):

cvtps2pi mmx, xmm/mem64.

CVTSS2SI приймач, джерело

Скалярне перетворення молодшого 32-розрядного числа з плаваючою крапкою в

короткому форматі в 32-розрядне ціле число Команда cvtss2si виконує скалярне перетворення молодшого 32-

розрядного числа з плаваючою крапкою в короткому форматі в 32-розрядне ціле число. Команда має два операнди. Як вхідний операнд може бути ХММ-регістр або 128-розрядний елемент пам’яті. Вихідним операндом може служити один з 32-розрядних регістрів загального

Page 443: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

442

призначення. Як і для команди cvtps2pi, на результат перетворення впливає установлення бітів поля гс, що визначає режим округлення, регістра керування/стану (MXCSR):

cvtss2si r32/r64, xmm/mem32.

CVTTPS2PI приймач, джерело

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

Команда cvttps2pi виконує паралельне перетворення двох

молодших упакованих 32-розрядних чисел з плаваючою крапкою в короткому форматі в два 32-розрядних цілих числа шляхом відсікання дробової частини початкових операндів. Команда має два операнди. Як вхідний операнд може бути ХММ-регістр або 128-розрядний елемент пам’яті. Вихідним операндом може служити один з ММХ-регістров. Установлення бітів поля гс, що визначає режим округлення, регістра керування/стану (MXCSR) на результат не впливає:

cvttps2pi mmx, xmm/mem64.

CVTTSS2SI приймач, джерело

Скалярне перетворення молодшого 32-розрядного числа з плаваючою крапкою в короткому форматі в 32-розрядне ціле число шляхом відсікання дробової частини вхідного операнда

Команда cvttss2si виконує скалярне перетворення молодшого 32-

розрядного числа з плаваючою крапкою в короткому форматі в 32-розрядне ціле число шляхом відсікання дробової частини вхідного операнда. Команда має два операнди. Як вхідний операнд можуть бути ХММ-регістр або 128-розрядний елемент пам’яті, а вихідним операндом може служити один з 32-розрядних регістрів загального призначення. Установлення бітів поля гс, що визначає режим округлення, регістра керування/стану (MXCSR) на результат не впливає:

cvttss2si r32/r64, xmm/mem32. CVTPI2PS приймач, джерело

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

Page 444: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

443

Команда cvtpi2ps виконує перетворення двох цілих 32-розрядних

чисел із знаком в два 32-розрядних числа з плаваючою крапкою в короткому форматі. Команда має два операнди. Як вхідний операнд, або операнд-джерело, може бути ММХ-регістр або 64-розрядний операнд в пам’яті. Вихідним операндом може служити тільки ХММ-регістр. Результат перетворення поміщається в молодших два 32-розрядних елементи ХММ-регістра, старші два елементи залишаються без змін. На результат перетворення впливає установлення бітів поля гс, що визначає режим округлення, регістра керування/стану (MXCSR):

cvtpi2ps xmm, mmx/mem64.

CVTSI2SS приймач, джерело

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

Команда cvtsi2ss виконує перетворення 32-розрядного числа в

цілочисельному форматі в 32-розрядне число з плаваючою крапкою в короткому форматі. Команда має два операнди. Як вхідний операнд, або операнд-джерело, може бути 32-розрядний регістр загального призначення або операнд в пам’яті. Вихідним операндом може служити тільки ХММ-регістр. Результат перетворення поміщається в молодший 32-розрядний елемент ХММ-регістра, при цьому три старших елементи залишаються без змін. На результат перетворення впливає установлення бітів поля гс, що визначає режим округлення, регістра керування/стану (MXCSR):

cvtsi2ss xmm, r/mem32; cvtsi2ss xmm, r/mem64.

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

На відміну від більшості команд SSE-расширения, всі логічні

команди є паралельними і дозволяють виконувати операції логічного І, АБО, І-НІ, що виключає АБО над окремими парами бітів операндів.

ANDPS приймач, джерело Паралельна операція логічного І над

парами бітів упакованих чисел Команда andps виконує паралельну операцію логічного І над

Page 445: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

444

парами бітів упакованих чисел з плаваючою точкою операнда-джерела і операнда-приймача. Команда має два операнди: як вхідний операнд (джерело) може бути ХММ-регістр або 128-розрядний елемент пам’яті, а як вихідного (приймач) – ХММ-регістр. Після виконання команди вміст операнда-джерела не змінюється, а результат поміщається в операнд-приймач:

andps xmm, xmm/mem128.

ANDNPS приймач, джерело

Паралельна операція логічного І-НІ над парами бітів упакованих чисел з плаваючою точкою

Команда andnps виконує паралельну операцію логічного І-НІ над

парами бітів упакованих чисел з плаваючою точкою операнда-джерела і операнда-приймача. Команда має два операнди: як вхідний операнд (джерело) може бути ХММ-регістр або 128-розрядний елемент пам’яті, а як вихідний (приймач) – ХММ-регістр. Після виконання команди вміст операнда-джерела не змінюється, а результат поміщається в операнд-приймач:

andnps xmm, xmm/mem128.

ORPS приймач, джерело

Паралельна операція логічного АБО над парами бітів упакованих чисел з плаваючою точкою

Команда orps виконує паралельну операцію логічного АБО над

парами бітів упакованих чисел з плаваючою точкою операнда-джерела і операнда-приймача. Команда має два операнди: як вхідний операнд (джерело) може бути ХММ-регістр або 128-розрядний елемент пам’яті, а як вихідного (приймач) – ХММ-регістр. Після виконання команди вміст операнда-джерела не змінюється, а результат поміщається в операнд-приймач:

orps xmm, xmm/mem128.

XORPS приймач, джерело

Паралельна логічна операція “виключне АБО” над парами бітів упакованих чисел з плаваючою точкою

Команда xorps виконує паралельну логічну операцію “виключне

АБО” над парами бітів упакованих чисел з плаваючою точкою операнда-джерела і операнда-приймача. Команда має два операнди: як вхідний операнд (джерело) може бути ХММ-регістр або 128-розрядний

Page 446: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

445

елемент пам’яті, а як вихідний (приймач) – ХММ-регістр. Після виконання команди вміст операнда-джерела не змінюється, а результат поміщається в операнд-приймач:

xorps xmm, xmm/mem128.

17.6. Команди керування станом До групи команд керування станом відносяться команди, що

виконують завантаження/збереження регістрів стану і керування.

LDMXCSR приймач, джерело

Завантаження регістра керування/стану вмістом 32-розрядного елементу пам’яті

Команда ldmxcsr виконує завантаження регістра керування

керування/стану (MXCSR) вмістом 32-розрядного елемента пам’яті, яка і є єдиним операндом:

ldmxcsr mem32.

STMXCSR приймач, джерело

Збереження вмісту регістра керування/стану в 32-розрядному осередку пам’яті

Команда stmxcsr виконує збереження вмісту регістра

керування/стану (MXCSR) в 32-розрядному осередку пам’яті, яка і є єдиним операндом:

stmxcsr mem32.

FXRSTOR приймач, джерело

Завантаження заздалегідь збереженого стану співпроцесора, ММХ- і SEE-розширення з області пам’яті розміром 512 байт

Команда fxrstor виконує завантаження заздалегідь збереженого

стану співпроцесора, ММХ- і SEE-розширения з області пам’яті розміром 512 байт. Як операнд виступає адреса області пам’яті, який повинен бути вирівняний по 16-байтовій межі:

fxrstor mem512byte.

FXSAVE приймач, джерело

Збереження стану співпроцесора, ММХ- і SSE-расширення в область пам’яті розміром в 512 байт

Page 447: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

446

Команда fxsave виконує збереження стану співпроцесора, ММХ- і

SSE-расширения в область пам’яті розміром в 512 байт. Як операнд виступає адреса області пам’яті:

fxsave mem512byte.

17.7. Команди розпаковування даних

UNPCKHPS приймач, джерело

Паралельне переміщення старших подвійних слів

Команда unpckhps виконує паралельне переміщення старших

подвійних слів з операнда-джерела і операнда-приймача в операнд-приймач. При цьому два старших подвійних слова операнда-джерела стають старшими подвійними словами в 64-розрядних елементах операнда-приймача, а два старших подвійних слова операнда-приймача – молодшими подвійними словами в 64-розрядних елементах операнда-приймача. Вхідним операндом (джерелом) може бути ХММ-регістр або 128-розрядний елемент пам’яті; як вихідний операнд повинен бути ХММ-регістр:

unpckhps xmm, xmm/mem128. Схему виконання команди наведено на рис. 17.3.

UNPCKLPS приймач, джерело

Паралельне переміщення молодших подвійних слів

Команда unpcklps виконує паралельне переміщення молодших

подвійних слів з операнда-джерела і операнда-приймача в операнд-

Рис. 17.3. Схема виконання команди unpckhps XММ0, XММ1

XММ0

XММ1 unpckhps XММ0, XММ1

127 0 XММ0

127 0 127 0

Page 448: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

447

приймач. При цьому два молодших подвійні слова операнда-джерела стають старшими двійковими словами в 64-розрядних елементах операнда-приймача, а два молодших подвійних слова операнда-приймача – молодшими подвійними словами в 64-розрядних елементах операнда-приймача. Вхідним операндом (джерелом) може бути ХММ-регістр або 128-розрядний елемент пам’яті; як вихідний операнд повинен бути ХММ-регістр:

unpcklps xmm, xmm/mem128.

Схема роботи команди наведена на рис. 17.4.

SHUFPS приймач, джерело, маска

Переставлення 32-розрядних упакованих операндів відповідно до заданої маски

Команда shufps виконує переставлення 32-розрядних упакованих

операндів відповідно до заданої маски. Команда має три операнди: вхідний, вихідний і операнд-маску. Маска є безпосереднім 8-розрядним значенням, яка задає порядок переставлення операндів. Кожна пара бітів маски визначає номер упакованого 32-розрядного операнда в приймачі або джерелі, яке повинне поміщатися в операнд-приймач. При цьому порядок розміщення 32-розрядних операндів такий: молодші 4 біта маски указують номери двох упакованих чисел приймача, які стають молодшими упакованими значеннями результату, а старші 4 біта – номери упакованих чисел джерела, які стають старшими упакованими значеннями результату:

shufps xmm, xmm/mem128, imm8. Переставлення виконуються одночасно, тобто паралельно. Краще

зв все схему роботи команди ілюструє рис. 17.5.

Рис. 17.4. Схема команди unpckhps XММ0, XММ1

XММ0

XММ1 unpckhps XММ0, XММ1

128 0

128 0 XММ0

128 0

Page 449: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

448

17.8. Команди керування кешуванням Необхідність керування кешуванням викликана тим, що більшість

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

MASKMOVQ приймач, джерело

Вибіркове збереження в пам’яті упакованих даних ММХ-регістра

Команда maskmovq виконує вибіркове збереження в пам’яті

упакованих даних ММХ-регістра. Як операнд-джерело використовується один з ММХ-регістров, а операндом-приймачем служить область пам’яті, адреса якої задана в регістрі EDI. Маска указує, які байти будуть збережені в пам’яті, і формується із старших розрядів кожного байта, що знаходиться в ММХ-регістрi:

maskmovq mem, mem.

MOVNTQ приймач, джерело

Запис в пам’ять, минувши кеш, цілочисельних упакованих даних у форматі ММХ

Команда movntq виконує запис в пам’ять, минаючи кеш,

цілочисельних упакованих даних у форматі ММХ. Операндом-джерелом тут виступає ММХ-регістр, а операндом-приймачем – 64-розрядний елемент пам’яті:

Рис. 17.5. Схема команди shufps XMM0,XMM1, 7Ah

XММ0

XММ1 shufps XMM0,XMM1, 7Ah

X1 X2 X3 X4 Y1 Y2 Y3 Y4 128 0

128 0 Y3 Y1 X2 X2 XММ0

128 0

Маска: 7Ah = | 01 | 11 | 10 | 10 |

Page 450: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

449

movntq mem64, mmx.

MOVNTPS приймач, джерело

Запис в пам’ять, минаючи кеш, упакованих чисел з плаваючою крапкою в короткому форматі

Команда movntps виконує запис в пам’ять, минаючи кеш,

упакованих чисел з плаваючою крапкою в короткому форматі. Операндом-джерелом тут виступає ХММ-регістр, а операндом-приймачем – 128-розрядний елемент пам’яті, адреса якої повинна бути вирівняною по 16-байтовій межі:

movntps mem128, xmm.

PREFETCHT0 mem8 PREFETCHT1 mem8 PREFETCHT2 mem8 PREFETCHTА mem8

Перенести дані у кеш Т0 Перенести дані у кеш Т1 Перенести дані у кеш Т2 Перенести дані у кеш NТA

Команда prefetcht mem8 переміщує дані з адреси mem8 в кеш: Т0 – переміщує дані в кеш всіх рівнів; Т1 – переміщує дані в кеш всіх рівнів, крім нульового; Т2 – переміщує дані в кеш всіх рівнів, крім нульового та першого; NТA – переміщує дані в кеш для постійних даних.

17.9. Лабораторна робота

“SSE-команди” Мета заняття: – поглибити і закріпити знання з архітектури МП платформи х86 і

навички його програмування; – придбати практичні навички складання, налагодження і

виконання програм з використанням команд SSE, написаних мовою асемблеру для програмування МП платформи х86.

Постановка задачі Згідно з останньою цифрою номера в групі вибрати варіант та

написати на асемблері програму обчислення одного з виразів з використанням дійсних чисел та виведенням їх на екран з використанням АРІ-функцій.

Page 451: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

450

Завдання: 1. Виконати паралельне порівняння за допомогою SSE-команд 2-х

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

(a – e)b – d/b, де a = 0,1; b = 1,05; c = 2,1; d = 3,2; інакше – виконати операцію d/b.

2. Виконати операцію паралельного логічного множення чисел за допомогою SSE-команд. Якщо значення другого числа більше 20, то виконати операцію

(de – e)/(c – a), де a = 3,1; b = 9,11; c = 2,3; d = 5,5; інакше – виконати операцію de – e.

3. Виконати паралельне порівняння за допомогою SSE-команд 2-х масивів по 10 чисел. Якщо перший масив більший від другого, то виконати операцію

(a – c)/b + c, де a = 0,2; b = 10,05; c = 2,3; інакше – виконати операцію a – c.

4. Виконати паралельне порівняння за допомогою SSE-команд 2-х масивів по 9 чисел. Якщо один масив менший від другого, то виконати операцію

a – e/c – ab, де a = 0,2; b = 10,05; c = 2,3; e = 21,07, інакше – виконати операцію: a c.

5. Виконати паралельну операцію логічного АБО над парами бітів упакованих чисел з плаваючою точкою за допомогою SSE-команд 2-х масивів. Якщо значення другого числа результату більше 25, то виконати операцію

a/b – cd, де a = 4,5; b = 12,3; c = 2,5; d = 6,5; інакше – виконати операцію a/b – d.

6. Виконати операцію паралельного логічного додавання за допомогою SSE-команд над масивами чисел. Якщо друге число результату порівняння більше 55, то виконати операцію

a – e/b – de, де a = 0,2; b = 8,05; c = 2,2; d = 3,3; інакше – виконати операцію a – e/b.

7. Виконати операцію паралельного логічного множення за допомогою SSE-команд над масивами чисел. Якщо друге число результату порівняння більше 555, то виконати операцію

(b + d)/ba – с, де a = 0,2; b = 7,05; c = 2,3; d = 3,4; інакше – виконати операцію ba – с.

8. Виконати паралельне обчислення квадратного кореня з масиву чисел і додати всі отримані результати. Якщо 0 та 1 біти дорівнюють

Page 452: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

451

одиницям, то виконати операцію ae – d/c – b, де a = 1,2; b = 5,05; c = 0,3; d = 3,5;

інакше – виконати операцію d/c. 9. Виконати паралельне обчислення мінімального значення для

кожної пари упакованих чисел і додати всі отримані результати. Якщо 1 та 3 біти дорівнюють нулям, то виконати операцію

(ab – d)/b – d, де a = 3,6; b = 9,17; c = 2,8; d = 3,9; інакше – виконати операцію ab – d.

0. Виконати операцію паралельного додавання за модулем за допомогою SSE-команд над масивами цілих чисел. Якщо друге слово менше 15, то виконати операцію

(b – dс)/a – с, де a = 0,2; b = 6,05; c = 1,3; d = 3,5; інакше – виконати операцію b – dс.

Зміст звіту 1. Постановка задачі для конкретного варіанта. 2. Блок-схема алгоритму виконання прикладу з детальним

коментарем та описом роботи. 3. Листинг програми з виведенням даних на екран монітора з

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

4. Рrint screen екрана 32-розрядного налагоджувача з виконаною програмою.

5. Висновки за результатами роботи.

Page 453: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

452

18. SSE2-РОЗШИРЕННЯ Технологію SSE2 (Streaming SIMD Extensions 2) розроблено для

застосування в процесорах Intel Pentium 4. Її призначення – підвищити ефективність операцій з 128-розрядними даними у форматі плаваючої крапки з подвійною точністю (double-precision floating point) та з цілочисельними даними. Ця технологія дозволяє розробляти високопродуктивні застосування для 3D-графіки і 3D-геометрії, моделювання і симуляції процесів, обробки сигналів, 3D-анімації, кодування/декодування, розпізнавання мови і так далі.

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

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

точності; розширити до 128 біт діапазон оброблюваних 64-розрядними

командами операндів. До групи SSE2 входять інструкції, що виконують 144 нові операції

[9 – 10]. Якщо ж підрахувати кількість нових імен інструкцій, то їх опиниться значно менше. Розбіжність пояснюється тим, що одному імені інструкції може відповідати декілька різних кодів операцій. Типовий приклад інструкції пересилання даних, у яких код операції залежить від напряму пересилання – з регістра в пам’ять або з пам’яті в регістр.

Більшість нових інструкцій двоадресні. Перший операнд є приймачем (dest), а другий – джерелом (src). Приймач, як правило, знаходиться в 128-bit регістрі XMM, джерело може знаходитися як в регістрі XMM, так і в оперативній пам’яті. Виключенням є тільки інструкції пересилання, у яких приймач може розташовуватися в

Page 454: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

453

пам’яті. Третій операнд (якщо він є) – це ціле число, розмір якого не перевищує одного байта.

При роботі з дійсними числами можливе виконання тієї самої операції над однією або двома парами чисел. У першому випадку ім’я операції закінчується буквами sd (скалярні дані), а в другому – буквами pd (упаковані дані). Для SSE2 2 вираз "упаковані дані" означає, що два 64-bit числа розташовані в одному 128-bit регістрі або в пам’яті підряд один за одним. А вираз "скалярні дані" означає, що одне 64-bit число розташоване в молодшій половині 128-bit регістра.

SSE-команди використовують вісім 128-розрядних регістрів (XMM0 – XMM7) і можуть працювати в скалярному або паралельному режимі. SSE2-команди оперують з такими типами даних:

– упаковані і скалярні числа з плаваючою крапкою в короткому форматі;

– упаковані і скалярні числа з плаваючою точкою подвійної точності;

– упаковані і скалярні цілі числа розміром 128 бітів. Формат даних 64-розрядного упакованого числа SSE2-розширення

наведено на рис. 18.1. За допомогою паралельних команд можна одночасно обробляти всі

упаковані операнди, тоді як за допомогою скалярних – тільки молодший операнд. Команди SSE2-розширення в більшості випадків вимагають вирівнювання адрес операндів в пам’яті по 16-байтовій межі, хоча з цього правила є деякі виключення, наприклад, команда завантаження, або збереження, операнда в невирівняній області пам’яті.

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

127 64 63 0

Рис. 18.1. Формат даних 64-розрядного упакованого числа SSE2-розширення

Порядок Мантиса

61 62 52 51 0 знак

Page 455: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

454

цього потрібно, виконавши команду cpuid, проаналізувати 26-й біт регістра EDX: якщо цей біт відмінний від нуля, то технологія SSE2 підтримується процесором.

Для визначення підтримки SSE-команд можна скористатися програмою з листингу 18.1.

Листинг 18.1. Тестова програма для визначення підтримки SSE2-

команд: .686 ; директива визначення типу мікропроцесора .model flat ; лінійна модель пам’яті option casemap: none ; відмінність малих та великих літер

.data ; директива визначення даних testSSE2 DB 1

.code ; директива початку коду програми st: ; мітка початку програми з ім’ям st

mov EAX, 1 cpuid ; ідентифікація мікропроцесора test EDX, 4000000h ; edx:= edx ∧ 400 0000h (26 розряд) jnz exit ; перейти на exit, якщо не нуль mov testSSE2, 0

exit: xor EAX, EAX mov AL, testSSE2

ret ; повернення керування ОС end st ; закінчення програми з ім’ям st Програма з листингу 18.1 повертає 1 у регістр AL, якщо технологія

SSE підтримується процесором. Команд обробки 128-розрядних даних з плаваючою крапкою

поділяються на такі групи команд: переміщення (пересилання, передавання) даних; арифметичні (складання, віднімання, множення, ділення,

витягання квадратного кореня і пошуку максимуму/мінімуму); порівняння; логічних операцій; розпаковування і розподілення даних; перетворення форматів даних; керування станом обчислень; керування кешуванням даних.

Page 456: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

455

18.1. Команди передавання даних

18.1.1. Обмін 128-bit кодами між операт ивною пам’ят т ю (ОЗП) т а регіст рами xmm

Для вирівнювання 128-розрядного коду ці інструкції необхідно

розташовувати за адресами, кратними 16 розрядам. Передбачено спеціальну інструкцію для запису коду в ОЗП без кешування, тобто при її виконанні вміст кеша не змінюється.

MOVNTPD приймач, джерело

Пересилання 128-розрядних кодів в ОЗП без кешування за адресами, кратними 16

Команда movntpd пересилає 128-розрядні коди в ОЗП без

кеширування. Код, що пересилається, повинен мати адресу, кратну 16, інакше виникає аварійна ситуація (порушення захисту):

movntpd m128, xmm.

MOVAPD приймач, джерело

Пересилання 128-розрядних кодів між ОЗП та регістром xmm за адресами, кратними 16

Команда movapd пересилає 128-розрядні коди з ОЗП в регістр

xmm. Код, що пересилається, повинен мати адресу, кратну 16, інакше виникає аварійна ситуація (порушення захисту):

movapd xmm, xmm/m128; movapd xmm/m128, xmm.

MOVUPD приймач, джерело Пересилання 128-розрядними кодами

між ОЗП і регістрами xmm Команда movupd пересилає 128-розрядні коди між ОЗП та

регістром xmm. Ця інструкція призначена для застосування в тих випадках, коли дані не вирівняні або коли невідомо, вирівняні вони чи ні:

movupd xmm, xmm/m128; movupd xmm/m128, xmm.

18.1.2. Обмін 64-розрядними кодами між ОЗП і регіст рами xmm

Якщо дані "вирівняні", то звернення до ОЗП займає 1 такт, інакше –

Page 457: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

456

2 такти. Вирівнювання означає, що адреса 64-розрядних кодів повинна бути кратною 8.

MOVSD приймач, джерело

Пересилання скалярних даних між ОЗП та молодшими 64 розрядами регістра xmm

Команда movsd пересилає дані між ОЗП та молодшими 64

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

movsd xmm, xmm/m64; movsd xmm/m64, xmm.

MOVHPD приймач, джерело Пересилання даних між ОЗП та

старшими 64 розрядами регістра xmm Команда movhpd пересилає дані між ОЗП та старшими 64

розрядами регістра xmm: movhpd xmm, m64; movhpd m64, xmm.

MOVLPD приймач, джерело Пересилання даних між ОЗП та

молодшими 64 розрядами регістра xmm Команда movlpd пересилає дані між ОЗП та молодшими 64

розрядами регістра xmm: movlpd xmm, m64; movlpd m64, xmm.

18.1.3. Використ ання масок

Ці інструкції працюють зі знаковими розрядами регістрів xmm.

Одна з них копіює стан 63-го і 127-го розрядів в регістр загального призначення (r32), в документації це називається формуванням знакової маски.

Друга – дозволяє вибірково змінювати вміст 16 байтів при накладенні на екрані одного рисунка на іншій (на початковий фон). Для цього застосовується маска, яка вказує, які байти підлягають зміні, а які не підлягають. Код (або частина коду) крапки займає 1 байт. Код маски для кожної крапки так само займає 1 байт. Якщо знаковий розряд байта маски встановлений, то код крапки початкового фону замінюється

Page 458: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

457

новим, інакше він залишається без змін. Зазвичай інструкція працює з відеопам’яттю, тому запис проводиться, минаючи кеш. Початкова адреса пам’яті повинна знаходитися в регістрах ds:di або ds:edi. Вирівнювання адреси не потрібне, тому що в даному випадку така вимога була б безглуздою.

MOVMSKPD приймач, джерело

Пересилання вмісту знакових розрядів xmm в два молодших розряди r32

Команда movmskpd пересилає вміст знакових розрядів xmm (63

та 127) в два молодших розряди r32 (0 і 1), решта розрядів r32 очищається:

movmskpd r32, xmm.

MASKMOVDQU приймач, джерело Пересилання за маскою Команда maskmovdqu виконує пересилання за маскою. Перший

операнд містить код, що пересилається, а другий операнд – маску. Третій операнд явно не указується, його адреса повинна знаходитися в ds:di або в ds:edi. Для кожного з 16 байтів виконується наступне: якщо знаковий розряд i-го байта маски встановлений, то dest[i] = src[i]. Якщо знаковий розряд байта маски очищений, то вміст dest не змінюється:

maskmovdqu xmm, xmm.

18.2. Арифметичні операції

18.2.1. Паралельні операції з упакованими числами

ADDPD приймач, джерело

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

Команда addpd виконує паралельне додавання двох упакованих

64-розрядних чисел з плаваючою точкою подвійної точності. Команда приймає два операнди: як вхідний операнд може виступати ХММ-регістр або елемент пам’яті; вихідним операндом може бути тільки ХММ-регістр:

addpd xmm, xmm/m128.

SUBPD приймач, джерело

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

Page 459: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

458

Команда subpd виконує паралельне віднімання двох упакованих 64-розрядних чисел з плаваючою точкою подвійної точності. Команда приймає два операнди: як вхідний операнд може виступати ХММ-регістр або елемент пам’яті; вихідним операндом може бути тільки ХММ-регистр. Команда віднімає вміст операнда-джерела з вмісту операнда-приймача і зберігає результат в операнді-приймачі:

subpd xmm, xmm/m128.

MULPD приймач, джерело

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

Команда mulpd виконує паралельне множення двох упакованих

64-розрядних чисел з плаваючою точкою подвійної точності. Команда приймає два операнди: як вхідний операнд може виступати ХММ-регістр або елемент пам’яті; вихідним операндом може бути тільки ХММ-регістр:

mulpd xmm, xmm/m128.

DIVPD приймач, джерело

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

Команда divpd виконує паралельне ділення двох упакованих 64-

розрядних чисел з плаваючою точкою подвійної точності. Команда приймає два операнди: як вхідний операнд може виступати ХММ-регістр або елемент пам’яті; вихідним операндом може бути тільки ХММ-регістр. Команда виконує ділення вмісту операнда-приймача на вміст операнда-джерела і зберігає результат в операнді-приймачі:

divpd xmm, xmm/m128.

SQRTPD приймач, джерело

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

Команда sqrtpd виконує паралельне витягання квадратного кореня

з двох упакованих 64-розрядних чисел з плаваючою точкою подвійної точності. Команда приймає два операнди: як вхідний операнд може виступати ХММ-регістр або елемент пам’яті; вихідним операндом може бути тільки ХММ-регістр:

sqrtpd xmm, xmm/m128.

Page 460: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

459

MAXPD приймач, джерело

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

Команда maxpd виконує паралельний пошук максимального

значення в парах упакованих 64-розрядних чисел з плаваючою точкою подвійної точності. Команда приймає два операнди: як вхідний операнд може виступати ХММ-регістр або елемент пам’яті; вихідним операндом може бути тільки ХММ-регістр. Результат зберігається у вихідному операнді:

maxpd xmm, xmm/m128.

MINPD приймач, джерело

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

Команда minpd виконує паралельний пошук мінімального

значення в парах упакованих 64-розрядних чисел з плаваючою точкою подвійної точності. Команда приймає два операнди: як вхідний операнд може виступати ХММ-регістр або елемент пам’яті; вихідним операндом може бути тільки ХММ-регістр. Результат зберігається у вихідному операнді:

minpd xmm, xmm/m128.

18.2.2. Арифмет ичні операції зі скалярними числами При виконання арифметичних операцій зі скалярними числами

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

ADDSD приймач, джерело

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

Команда addsd виконує складання молодших 64-розрядних

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

addsd xmm, xmm/m64.

Page 461: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

460

SUBSD приймач, джерело

Віднімання молодших 64-розрядних операндів з плаваючою точкою подвійної точності

Команда subsd виконує віднімання молодших 64-розрядних

операндів з плаваючою точкою подвійної точності. Команда приймає два операнди: як вхідний операнд може виступати xmm-регістр або елемент пам’яті; вихідним операндом може бути тільки xmm-регістр. Команда віднімає вміст операнда-джерела з вмісту операнда-приймача і зберігає результат в операнді-приймачі:

subsd xmm, xmm/m64.

MULSD приймач, джерело

Скалярне множення молодших 64-розрядних операндів з плаваючою точкою подвійної точності

Команда mulsd виконує скалярне множення молодших 64-

розрядних операндів з плаваючою точкою подвійної точності. Команда приймає два операнди: як вхідний операнд може виступати xmm-регістр або елемент пам’яті; вихідним операндом може бути тільки xmm-регістр. Команда не зачіпає старші частини операндів:

subsd xmm, xmm/m64.

DIVSD приймач, джерело

Скалярне ділення молодших 64-розрядних операндів з плаваючою точкою подвійної точності

Команда divsd виконує скалярне ділення молодших 64-розрядних

операндів з плаваючою точкою подвійної точності. Команда приймає два операнди: як вхідний операнд може виступати xmm-регістр або елемент пам’яті; вихідним операндом може бути тільки xmm-регістр. Команда виконує ділення вмісту операнда-приймача на вміст операнда-джерела і зберігає результат в операнді-приймачі, не зачіпаючи старші частини операндів:

divsd xmm, xmm/m64.

SQRTSD приймач, джерело

Скалярне добуття квадратного кореня з молодших 64-розрядних операндів з плаваючою точкою подвійної точності

Команда sqrtsd виконує скалярне добуття квадратного кореня з

молодших 64-розрядних операндів з плаваючою точкою (ПТ) подвійної точності. Команда приймає два операнди: як вхідний операнд може

Page 462: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

461

виступати xmm-регістр або елемент пам’яті; вихідним операндом може бути тільки xmm-регістр. Старші операнди під час виконання не змінюються:

sqrtsd xmm, xmm/m64.

MAXSD приймач, джерело

Пошук максимального значення в парі молодших 64-розрядних операндів з ПТ подвійної точності

Команда maxsd виконує пошук максимального значення в парі

молодших 64-розрядних операндів з плаваючою точкою подвійної точності. Команда приймає два операнди: як вхідний операнд може виступати xmm-регістр або елемент пам’яті; вихідним операндом може бути тільки xmm-регістр. Результат зберігається в молодшій частині вихідного операнда, не зачіпаючи старший операнд:

maxsd xmm, xmm/m64.

MINDS приймач, джерело

Пошук мінімального значення в парі молодших 64-розрядних операндів з ПТ подвійної точності

Команда minds виконує пошук мінімального значення в парі

молодших 64-розрядних операндів з плаваючою точкою подвійної точності. Команда приймає два операнди: як вхідний операнд може виступати xmm-регістр або елемент пам’яті; вихідним операндом може бути тільки xmm-регістр. Результат зберігається в молодшій частині вихідного операнда, не зачіпаючи старший операнд:

minsd xmm, xmm/m64.

18.3. Команди порівняння

18.3.1. Порівняння без зміни ст ану розрядів EFLAGS Для кожної порівнюваної пари дійсних чисел при позитивному

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

CMPPD приймач, джерело, маска

Паралельне порівняння двох пар упакованих 64-розрядних чисел з ПТ подвійної точності

Page 463: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

462

Команда cmppd (cmpхххpd) виконує паралельне порівняння двох дійсних чисел. Результат поміщається у відповідні половини приймача:

cmppd xmm, xmm/m128, imm8.

Умову, що перевіряється, задає третій операнд (табл. 18.1). У документації Intel обумовлено два способи указання умови, що перевіряється.

Таблиця 18.1

Умова Указується значення imm8

Використовується ім’я псевдооперації

Дорівнює CMPPD xmm, xmm/m128, 0

CMPEQPD xmm, xmm/m128

Менше CMPPD xmm, xmm/m128, 1

CMPLTPD xmm, xmm/m128

Менше або дорівнює

CMPPD xmm, xmm/m128, 2

CMPLEPD xmm, xmm/m128

Не порівнянні CMPPD xmm, xmm/m128, 3

CMPUNORDPD xmm, xmm/m128

Не дорівнює CMPPD xmm, xmm/m128, 4

CMPNEQPD xmm, xmm/m128

Не менше CMPPD xmm, xmm/m128, 5

CMPNLTPD xmm, xmm/m128

Не менше або дорівнює

CMPPD xmm, xmm/m128, 6

CMPNLEPD xmm, xmm/m128

Порівнянні CMPPD xmm, xmm/m128, 7

CMPORDPD xmm, xmm/m128

CMPSD приймач, джерело, константа

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

Команда cmpsd (cmpхххsd) виконує скалярне порівняння

молодших частин 128-розрядних операндів. Результат поміщається в молодшу половину dest[l], вміст старшої половини dest[h] не змінюється:

cmpsd xmm, xmm/m128, imm8. 18.3.2. Команди порівняння, які змінюють регістр EFLAGS Зміну станів розрядів EFLAGS виконують дві інструкції, що

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

Page 464: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

463

операнди не є числами (NAN).

COMISD приймач, джерело

Скалярне порівняння молодших частин 128-розрядних операнді зі зміною ознак регістра EFLAGS

Команда comisd виконує порівняння двох дійсних чисел з

можливістю виникнення виняткової ситуації: comisd xmm, xmm/m64.

UCOMISD приймач, джерело

Скалярне порівняння молодших частин 128-розрядних операнді зі зміною ознак регістра EFLAGS

Команда ucomisd виконує порівняння двох дійсних чисел з

можливістю виникнення виняткової ситуації: ucomisd xmm, xmm/m64.

Відношення між порівнюваними числами указують ознаки OF, AF,

SF, які очищаються (табл. 18.2).

Таблиця 18.2

18.4. Логічні операції Логічні операції обчислюють функції булевої алгебри. Зазвичай

вони застосовуються для виділення або об’єднання окремих частин кодів.

Pentium 4 дозволяє обчислювати логічні функції за допомогою груп інструкцій, що виконують аналогічні дії.

ANDPD приймач, джерело

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

Відношення Стан розрядів EFLAGS ZF PF CF

Не порівнянні 1 1 1 op1 < op2 0 0 1 op1 > op2 0 0 0 op1 = op2 1 0 0

Page 465: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

464

Команда ANDPD виконує логічну функцію кон’юнкції ("І") над парами бітів упакованих 128-розрядних чисел:

andpd xmm, xmm/m128.

ANDNPD приймач, джерело

Паралельна операція інверсії та логічного І над парами бітів упакованих 128-розрядних чисел

Команда andnpd виконує інверсію операнда приймача, після чого

– логічну функцію І: andnpd xmm, xmm/m128.

ORPD приймач, джерело

Паралельна операція логічного АБО над парами бітів упакованих 128-розрядних чисел

Команда ORPD виконує логічну функцію диз’юнкції ("АБО"):

orpd xmm, xmm/m128.

XORPD приймач, джерело

Паралельна операція логічного “виключне АБО” над парами бітів упакованих 128-розрядних чисел

Команда xorpd виконує логічну функцію "виключне АБО":

xorpd xmm, xmm/m128.

18.5. Команди розпаковування і розподілення даних Розпаковування і перегрупування кодів є своєрідним різновидом

пересилань. Позначимо вміст двох половин прм як прмl і прмh, а вміст двох половин прд як прдl і прдh. Наступні три операції дозволяють записати в прм комбінацію цих величин.

UNPCKHPD приймач, джерело

Операція розпаковування: передавання старших половин чисел

Команда unpckhpd виконує операцію розпаковування:

прм = прдh, прмh – у прм копіюється вміст старших половин прд та прм:

unpckhpd xmm, xmm/m128.

Page 466: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

465

UNPCKLPD приймач, джерело

Операція розпаковування: передавання молодших половин чисел

Команда unpcklpd виконує операцію розпаковування:

прм = прдl, прмl – у прм копіюється вміст молодших половин прд та прм:

unpcklpd xmm, xmm/m128.

SHUFPD приймач, джерело, константа

Керуюче передавання частин операнда

Команда shufpd виконує операцію прм = прдh/прдl, прмh/прмl –

перегрупування: bit0 imm8 вказує, яка половина прм копіюється в його молодші розряди; bit1 imm8 указує, яка половина прд копіюється в старші розряди прм. У обох випадках 0 відповідає молодшій половині, а 1 – старшій. Наприклад, якщо прм та прд знаходяться в одному регістрі, то imm8 = 1 викличе перестановку чисел в прм:

shufpd xmm, xmm/m128, imm8. Схему виконання команди shufpd наведено на рис. 18.1.

18.6. Команди перетворення форматів даних

18.6.1. Групові перет ворення формат ів даних Можливі два типи перетворень: a) дійсні числа перетворяться в дійсні числа зі зміною точності їх

подання (з подвійної точності в звичайну або навпаки). в) цілі числа перетворяться в дійсні числа або дійсні числа – в цілі.

У останньому випадку можливе округлення або відсікання залишку. Два цілих числа можуть знаходитися в регістрах xmm або mmx.

Рис. 18.3. Дія команди shufpd XММ0, XMM0, 3h

ММ0 29.31 29.31

ММ0 29.31 -3.25 127 64 63 0

До операції

Після операції

Маска: 3h = 00 00 00 11

Page 467: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

466

CVTPD2PS приймач, джерело

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

Команда cvtpd2ps виконує паралельне перетворення двох дійсних

чисел з формату з подвійною точністю у формат із звичайною точністю: cvtpd2ps xmm, xmm/m128.

CVTPS2PD приймач, джерело

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

Команда cvtps2pd виконує паралельне перетворення двох дійсних

чисел з формату із звичайною точністю у формат з подвійною точністю. Якщо джерелом є xmm, то перетворяться два молодших числа:

cvtps2pd xmm, xmm/m64.

CVTPS2DQ приймач, джерело

Паралельне перетворення чотирьох дійсних чисел із звичайною точністю в чотири цілих 32-розрядних числа

Команда cvtps2dq виконує паралельне перетворення чотирьох

дійсних чисел із звичайною точністю в 4 цілих 32-х розрядних числа: cvtps2dq xmm, xmm/m128.

CVTTPS2DQ приймач, джерело

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

Команда cvttps2dq виконує паралельне перетворення чотирьох

дійсних чисел із звичайною точністю в 4 цілих 32-розрядних числа з відсіканням залишку:

cvttps2dq xmm, xmm/m128.

CVTDQ2PS приймач, джерело

Паралельне перетворення чотирьох 32- розрядних чисел в чотири дійсних числа, поданих із звичайною точністю

Команда cvtdq2ps виконує перетворення 4 цілих 32-розрядних

чисел в 4 дійсних числа, представлених із звичайною точністю:

Page 468: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

467

cvtdq2ps xmm, xmm/m128.

CVTPD2DQ приймач, джерело

Паралельне перетворення двох дійсних чисел подвійної точності в два цілих 32-розрядних числа

Команда cvtpd2dq виконує перетворення двох дійсних чисел

подвійної точності в два цілих 32-розрядних числа: cvtpd2dq xmm, xmm/m128.

CVTPD2DQ приймач, джерело

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

Команда cvttpd2dq виконує перетворення двох дійсних числа

подвійної точності в два цілих 32-розрядних числа з відсіканням залишку: cvttpd2dq xmm, xmm/m128.

CVTDQ2PD приймач, джерело

Паралельне двох цілих 32-розрядних числа в два дійсних числа, поданих з подвійною точністю

Команда cvtdq2pd виконує перетворення двох цілих 32-розрядних

числа в два дійсних числа, поданих з подвійною точністю. Якщо джерелом є xmm, то перетворяться два молодших числа:

cvtdq2pd xmm, xmm/m64.

CVTPD2PI приймач, джерело

Паралельне перетворення двох дійсних чисел подвійної точності в два цілих 32-розрядних числа та збереження результату в регістрі mmx

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

cvtpd2pi mmx, xmm/m128.

CVTTPD2PI приймач, джерело

Паралельне перетворення двох дійсних чисел подвійної точності в два цілих 32-розрядних числа з відсіканням залишку і записом в регістр mmx

Команда cvttpd2pi виконує перетворення двох дійсних чисел

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

Page 469: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

468

залишку і записом в регістр mmx: cvttpd2pi mmx, xmm/m128.

CVTPI2PD приймач, джерело

Паралельне перетворення двох цілих 32-розрядних чисел, що знаходяться в регістрі mmx, в два дійсних числа, поданих з подвійною точністю

Команда cvtpi2pd виконує перетворення двох цілих 32-розрядних

чисел, що знаходяться в регістрі mmx, в два дійсних числа, поданих з подвійною точністю:

cvtpi2pd xmmx, mmx/m64.

18.6.2. Перет ворення формат у одного числа Можливі два типи перетворень: a) змінюється точність подання дійсного числа з подвійної на

звичайну або навпаки. в) ціле число перетворюється в дійсне число або дійсне число – в

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

CVTSD2SS приймач, джерело

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

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

з формату з подвійною точністю у формат із звичайною точністю. У приймачеві не змінюється вміст розрядів 32 – 127:

cvtsd2ss xmm, xmm/m64.

CVTSS2SD приймач, джерело

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

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

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

cvtss2sd xmm, xmm/m32.

Page 470: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

469

CVTSD2SI приймач, джерело

Скалярне перетворення дійсного числа подвійної точності в ціле 32-розрядне число

Команда cvtsd2si виконує скалярне перетворення молодшого

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

cvtsd2si r32, xmm/m64. Результат округляється у відповідності зі значенням бітів поля rc

регістра керування/стану.

CVTTSD2SI приймач, джерело

Скалярне перетворення дійсного числа подвійної точності в ціле 32-розрядне число

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

подвійної точності в ціле 32-розрядне число: cvttsd2si r32, xmm/m64.

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

CVTSI2SD приймач, джерело

Скалярне перетворення двох цілих 32-розрядних чисел, що знаходяться в регістрі mmx, в два дійсних чисел, поданих з подвійною точністю

Команда cvtsi2sd виконує скалярне перетворення цілого

32-розрядного числа в дійсне число, подане з подвійною точністю. Вміст старшої половини dest не змінюється:

cvtsi2sd xmm, r32/m32.

18.7. Керуванням кешем Кеш – посередник між процесором і ОЗП. Всі інструкції, окрім

спеціальних, для читання і запису даних звертаються до кеша, а не до ОЗП. Все, що було записане в кеш, колись потрапить в ОЗП, а все, що було зчитано з ОЗП, колись потрапить в кеш. У Pentium III з’явилася інструкція PREFETCHT, що виконує попереджальну вибірку даних з ОЗП в кеш. Але якщо кеш містить дані, ще не записані в ОЗП, то при попереджальному завантаженні вони будуть втрачені. Тому відразу була введена інструкція sfence, яка дозволяла захистити записані в кеш дані,

Page 471: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

470

ще не збережені в ОЗП. У Pentium 4 було додано ще дві інструкції: для захисту та очищення рядка кеша, що містить вже непотрібні дані.

Команда LFENCE припиняє прочитування даних з кеша до

закінчення раніше запитаної операції завантаження. Команда MFENCE припиняє будь-які звернення до кеша до

закінчення всіх операцій обміну між ОЗП і кешем. Команда CFLUCH m8 очищує рядок кеша, номер (адреса) якого в

кеш задає операнд, що має розмір байта.

18.8. Операції з цілими числами. Нові можливості інструкцій MMX Інструкції групи MMX вперше з’явилися у Pentium MMX, а потім у

Pentium II. Всього в цю групу входило 57 інструкцій, яким відповідали 47 мнемонічних позначень (імен). Більшість з них виконувала групові операції з цілими числами, що мають розмір байта, слова або подвійного слова, а деякі могли працювати з 64-розрядними даними (QWORD). У Pentium III з’явилася група інструкцій SSE1, 14 з яких виконували групові операції з цілими числами, тобто доповнювали набір інструкцій MMX. Але як старі, так і нові інструкції могли працювати тільки з 64-bit даними, що знаходяться в регістрах mmx або в ОЗП.

З випуском Pentium IV більшість вказаних інструкцій отримали доступ до 128-bit регістрів xmm. Виключень небагато: у групі MMX – інструкція EMMS, а в групі SSE1 – три інструкції: MASKMOVQ, MOVNTQ і PSHUFW. Решту всіх інструкцій виконують групові операції як з 64-bit, так і з 128-bit даними. Імена інструкцій не змінилися, а розмір групи визначається відповідно до імені регістра (mmx або xmm). Вище були наведені варіанти запису логічних операцій групи MMX при роботі з 128-bit даними.

Таким чином, розширений набір інструкцій MMX дозволяє виконувати операції над групами, що складаються з 16-ти байтів, 8-ми слів, 4-х подвійних (32-bit) слів або 2-х квадро (64-bit) слів. Логічні операції і зрушення можуть виконуватися і над одним 128-bit операндом.

Інструкції групи команд SSE2, призначених для роботи з цілими числами, які з’явилися у Pentium IV, наведено у розділі про ММХ-команди.

Page 472: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

471

18.9. Лабораторна робота “SSE2-команди”

Мета заняття: – поглибити і закріпити знання з архітектури МП платформи х86 і

навички його програмування; – придбати практичні навички складання, налагодження і

виконання програм з використанням команд SSE, написаних мовою асемблеру для програмування МП платформи х86.

Постановка задачі Згідно з останньою цифрою номера в групі вибрати варіант та

написати на асемблері програму обчислення одного з виразів з використанням дійсних чисел та виведенням їх на екран з використанням АРІ-функцій.

Завдання: 1. Виконати паралельне порівняння за допомогою SSE2-команд 2-х

масивів по 11 чисел. Якщо 0 та 1 біти двох масивів однакові, то виконати пошук максимального значення в парах упакованих чисел, а в протилежному випадку – мінімального.

2. Задано два масиви по 5 чисел. За допомогою SSE2-команд визначити суму чисел всіх масивів та виконати аналіз 0 та 1 бітів результату. Якщо ці біти нульові, то виконати операцію добуття квадратного кореня з нього.

3. Виконати паралельне порівняння за допомогою SSE2-команд 2-х масивів по 9 чисел. Якщо перший масив більший від другого, то виконати операцію

(a – e)b – d/b, де a = 0,1; b = 1,05; c = 2,1; d = 3,2; інакше – виконати операцію d/b.

3. Виконати паралельне порівняння за допомогою SSE2-команд 2-х масивів по 9 чисел. Якщо один масив менший від другого, то виконати операцію

(a – e)b – d/b, де a = 0,1; b = 1,05; c = 2,1; d = 3,2; інакше – виконати операцію d/b.

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

(a – c)/b + c, де a = 0,2; b = 10,05; c = 2,3; інакше – виконати операцію a – c.

Page 473: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

472

5. Виконати паралельне порівняння за допомогою SSE2-команд 2-х масивів по 10 чисел. Додати всі результати. Якщо сума всіх отриманих чисел більше 100, то виконати обчислення квадратного кореня, а в протилежному випадку – не виконувати.

6. Виконати паралельне множення двох упакованих 64-розрядних чисел з плаваючою точкою подвійної точності. Додати всі результати та обчислити квадратний корінь.

7. Виконати паралельне ділення двох упакованих 64-розрядних чисел з плаваючою точкою подвійної точності. Додати всі результати та виконати перетворення дійсного числа з формату з подвійною точністю у формат із звичайною точністю.

8. Виконати паралельний пошук максимального значення в парах упакованих 64-розрядних чисел з плаваючою точкою подвійної точності. Додати всі результати та виконати перетворення дійсного числа подвійної точності в ціле 32-розрядне число.

9. Виконати паралельний пошук мінімального значення в парах упакованих 64-розрядних чисел з плаваючою точкою подвійної точності. Додати всі результати та обчислити квадратний корінь.

0. Виконати паралельне добуття квадратного кореня з двох упакованих 64-розрядних чисел з плаваючою точкою подвійної точності. Додати всі результати та обчислити квадратний корінь.

Зміст звіту 1. Постановка задачі для конкретного варіанта. 2. Блок-схема алгоритму виконання прикладу з детальним

коментарем та описом роботи. 3. Листинг програми з виведенням даних на екран монітора з

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

4. Рrint screen екрана 32-розрядного налагоджувача з виконаною програмою.

5. Висновки за результатами роботи.

Page 474: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

473

19. SSE3-РОЗШИРЕННЯ З випуском 90-нм процесора Pentium IV під кодовою назвою

Prescott (http://www.ixbt.com/cpu/intel-prescott.shtml), анонсованого Intel 2 лютого 2004 року, архітектура Intel Netburst придбала ряд нових інструкцій, що отримали офіційну назву – SSE3. Це набір з 13 нових інструкцій, які потрібні для підвищення продуктивністі процесора у ряді операцій потокової обробки даних. Доповнення торкнулися набору команд SSE (Streaming SIMD Extensions), що працюють з чотирикомпонентними векторами з одинарною точністю, SSE2 (Streaming SIMD Extensions 2), що працюють з двовимірними векторами чисел подвійної точності, а також x87 FPU.

19.1. Перетворення чисел з плаваючою крапкою (x87) в цілі числа

У цю підгрупу входить одна інструкція зі всього набору Prescott

New Instructions (SSE3), яка працює на рівні x87 FPU. Команда fisttp зберігає цілочисельне значення із звільненням

елемента стека x87 з округленням убік нуля. Її поведінка аналогічна поведінці стандартної інструкції fistp, але відмінністю є використання округлення убік нуля незалежно від того, який спосіб округлення вибраний в даний момент в контрольному слові FPU.

19.2. Дублювання даних

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

початкового операнда (пам’яті або XMM-регістра) в операнд призначення з дублюванням першого і третього 32-бітових елементів:

Операнд A (128 біт , 4 елемент и): a3 | a2 | a1 | a0 Операнд B (128 біт , 4 елемент и): b3 | b2 | b1 | b0

movsldup A, B Результ ат (операнд A): b2 | b2 | b0 | b0 Команда movshdup виконує завантаження 128-бітового значення з

початкового операнда в операнд призначення з дублюванням другого і четвертого 32-бітових елементів:

Операнд A (128 біт , 4 елемент и): a3 | a2 | a1 | a0 Операнд B (128 біт , 4 елемент и): b3 | b2 | b1 | b0

movshdup A, B Результат (операнд A): b3 | b3 | b1 | b1

Page 475: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

474

Команда movddup виконує завантаження 64-бітового значення з

пам’яті або початкового регістра (біти [63 – 0]) з дублюванням Операнд A (128 біт , 2 елемент и): a1 | a0 Операнд B (64 біт , 1 елемент ): b0

movddup A, B Результат (операнд A): b0 | b0

19.3. Завантаження невирівняних змінних Дану підгрупу представляє команда lddqu. Це операція

завантаження невирівняного 128-бітового значення з пам’яті, що виключає можливість «розриву» (перетину кордону) рядка кеша.

У випадку, якщо адреса завантажуваного елемента вирівняна по 16-байтной межі, команда lddqu здійснює звичайне завантаження 16-байтного значення (тобто, по суті, поводиться аналогічно інструкціям movaps/movapd/movdqa із стандартного набору SSE/SSE2). Інакше lddqu завантажує цілих 32 байти, починаючи з вирівняної адреси з подальшим витяганням потрібних 16 байт. Використання цієї інструкції дозволяє досягти значного збільшення продуктивності при завантаженні невирівняних 128-бітових значень з пам’яті, в порівнянні із стандартними інструкціями movups/movupd/movdqu SIMD-розширень SSE/SSE2.

19.4. Одночасне додавання/віднімання

У цю підгрупу входять дві команди, перша з яких працює з

чотирикомпонентними векторами чисел одинарної точності (SSE), а друга – з двокомпонентними векторами чисел подвійної точності (SSE2).

Команда addsubps виконує додавання другого і четвертого елементів з одинарною точністю з одночасним відніманням першого і третього елементів. Ця інструкція корисна при роботі з комплексними числами у разі використання відповідного типу змінних.

Операнд A (128 біт , 4 елемент и): a3 | a2 | a1 | a0 Операнд B (128 біт , 4 елемент и): b3 | b2 | b1 | b0

addsubps A, B Результат (операнд A): a3+b3 | a2-b2 | a1+b1 | a0-b0 Команда addsubpd поводиться аналогічно команді addsubps, але

працює з числами подвійної точності (двоелементними операндами

Page 476: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

475

SSE2): Операнд A (128 біт , 2 елемент и): a1 | a0 Операнд B (128 біт , 2 елемент и): b1 | b0 addsubpd A, B Результ ат (операнд A): a1+b1 | a0-b0

19.5. Горизонтальне додавання/віднімання П’ята підгрупа представлена чотирма командами, що здійснюють

принципово нові операції для SIMD розширень сімейства SSE/SSE2. Перші дві з них працюють з чотирикомпонентними векторами з одинарною точністю, а останні – з двокомпонентними векторами з подвійною точністю.

Команда haddps здійснює горизонтальне складання елементів з одинарною точністю. Перший елемент, записуваний в операнд призначення, є сумою першого і другого елементів першого (початкового) операнда; другий елемент – сумою третього і четвертого елементів першого операнда; третій елемент – сумою першого і другого елементів другого операнда (операнда призначення) і, нарешті, четвертий елемент – сумою третього і четвертого елементів другого операнда. Для наочності зобразимо це, як і раніше, у вигляді схеми:

Операнд A (128 біт , 4 елемент и): a3 | a2 | a1 | a0 Операнд B (128 біт, 4 елементи): b3 | b2 | b1 | b0

haddps A, B ; горизонтальне складання елементів з одинарною точністю Результат (операнд A): b2+b3 | b0+b1 | a2+a3 | a0+a1 Команда hsubps здійснює горизонтальне віднімання елементів з

одинарною точністю. Її поведінка аналогічна команді haddps, єдиною відмінністю є використання операції віднімання замість складання:

Операнд A (128 біт, 4 елементи): a3 | a2 | a1 | a0 Операнд B (128 біт, 4 елементи): b3 | b2 | b1 | b0

hsubps A, B ; горизонтальне віднімання елементів з одинарною точністю Результат (операнд A): b2-b3 | b0-b1 | a2-a3 | a0-a1 Команда haddpd здійснює горизонтальне складання елементів з

подвійною точністю. Першим (нижчим) результуючим елементом є сума нижньої і верхньої частин першого (початкового) операнда, другим (верхнім) – сума нижньої і верхньої половин другого операнда (операнда призначення):

Операнд A (128 біт, 2 елементи): a1 | a0

Page 477: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

476

Операнд B (128 біт, 2 елементи): b1 | b0

haddpd A, B ; горизонтальне складання елементів з подвійною точністю Результат (операнд A): b0+b1 | a0+a1 Команда hsubpd здійснює горизонтальне віднімання елементів з

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

Операнд A (128 біт, 2 елементи): a1 | a0 Операнд B (128 біт, 2 елементи): b1 | b0

hsubpd A, B ; горизонтальне віднімання елементів з подвійною точністю Результат (операнд A): b0-b1 | a0-a1

19.6. Синхронізація потоків У останню підгрупу можна включити дві інструкції, націлені на

використання в системному програмуванні з метою надання можливості ефективнішої синхронізації потоків. Ці інструкції використовуються при розробці операційних систем і драйверів пристроїв з метою поліпшення продуктивності процесора і зниження енергоспоживання останнього, коли він знаходиться в режимі «порожнього» очікування (разом з введеною в розширення SSE2 інструкцією pause).

Команда monitor встановлює діапазон адрес пам’яті (зазвичай використовується один рядок кеша), за яким здійснюється відстежування записів за стандартним протоколом write-back.

Команда mwait вводить логічний процесор в режим низького енергоспоживання при очікуванні записів по простору адрес, заданих інструкцією monitor. З архітектурної точки зору її поведінка ідентична команді nop. Вихід з оптимізованого стану здійснюється у разі запису по встановленому простору адрес, а також при спрацьовуванні будь-якого переривання або виключення.

19.7. Використання SSE3 в розробці і оптимізації програм

19.7.1. Розрахункові завдання, що використ овуют ь x87 FPU

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

професійного програмного забезпечення) може виявитися вельми корисною інструкція швидкого перетворення дійсних чисел в цілих (fisttp), єдина зі всього набору SSE3, що працює на рівні x87 FPU.

Page 478: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

477

Відомо, що правильним, з погляду стандарту C/С++/fortran, способом перетворення змінних типу float (чисел з плаваючою крапкою) в змінні типу int (цілі числа) в операціях вигляду

float f; int i = (int)f

є округлення убік нуля (truncate). В той же час вибраним за умовчанням способом округлення x87 FPU є округлення убік найближчого точного числа (round-to-nearest). Необхідність існування операції округлення пов’язана зовсім не з перетворенням дійсних чисел в цілі, а з кінцевим способом подання нескінченної безлічі чисел з плаваючою крапкою (32 біта для чисел одинарної точності, 64 біта для чисел подвійної точності, 80 біт для змінних з розширеною точністю, а також для внутрішнього подання даних в x87 FPU). При цьому найбільш точне кінцеве представлення чисел з плаваючою крапкою досягається при такому способі округлення.

У зв’язку з цим, наведений вище C-код в процесорах IA-32 буде перетворений будь-яким компілятором, відповідно до вимог стандарту ANSI C, в асемблерний код приблизно такого вигляду:

DWORD cwold, cwnew; __asm { fld dword ptr[f] // завантаження значення float fnstcw word ptr[cwold] // збереження FPUCW movzx eax, word ptr[cwold] or eax, 0x0c00 // установка режиму округлення // у бік нуля (truncate) mov dword ptr[cwnew], eax fldcw word ptr[cwnew] // завантаження нового значення FPUCW

fistp dword ptr[i] // збереження значення int fldcw word ptr[cwold] // відновлення FPUCW } Така процедура містить в собі три явно зайві операції, пов’язані зі

збереженням, завантаженням і відновленням значення контрольного слова x87 FPU. Час виконання кожною з них вимірюється як мінімум декількома тактами процесора (у ряді випадків – десятьма і більше, залежно від конкретної реалізації мікроархітектури процесора). З погляду оптимізації коду, що існує в рамках архітектури IА-32, можна намітити два виходи з цієї ситуації.

Перший – це зберегти значення контрольного слова FPU,

Page 479: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

478

завантажити нове значення контрольного слова FPU з потрібним способом округлення, після чого зробити відразу цілий ряд перетворень, і, нарешті, відновити початковий стан FPU. Саме такий спосіб рекомендується застосовувати у документації по оптимізації коду для процесорів x86 (зокрема, для AMD Athlon). Трудність такого підходу полягає в тому, що, по-перше, необхідна реорганізація коду, яка б дозволила згрупувати всі перетворення значень float в int. По-друге, саму процедуру перетворення доведеться писати у вигляді асемблерної вставки.

Другий– це використовувати доступні SIMD-розширення, на зразок SSE або 3Dnow! У першому випадку, для цієї мети підходять команди cvtss2si і cvtps2pi (остання дозволяє здійснювати два перетворення одночасно, але використовує MMX-регістр, що, у свою чергу, приводить до необхідності перемикання режимів FPU/mmx. У другому випадку перетворення пари дійсних значень в цілочисельні можна здійснювати за допомогою команди pf2id. Тут знов присутні труднощі, властиві набору 3Dnow! – використання MMX-регістрів, і, як наслідок, необхідність перемикання режимів роботи процесора (або очищення, або збереження/відновлення вмісту FPU-стека і MMX-регістрів). Як найбільш просту процедуру перетворення можна використати процедуру, оформлену у вигляді асемблерної вставки:

__asm { cvttss2si eax, dword ptr[f] mov dword ptr[i], eax } Використання команд SSE, на відміну від команд mmx/3Dnow!, не

вимагає додаткових витрат, пов’язаних з перемиканням режиму роботи процесора.

З командами розширення SSE3 це перетворення може бути таким: __asm { fld dword ptr[f] // завантаження значення float fisttp dword ptr[i] // збереження значення int в режимі truncate } Використання нової інструкції fisttp дозволяє досягти значного

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

Page 480: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

479

19.7.2. Обчислення з комплексними числами Комплексна арифметика досить часто зустрічається у різних

спектральних завданнях, зокрема – у завданнях обробки аудіоданих. До них відносяться швидке перетворення Фур’є, частотна фільтрація і таке інше. Серед нових розширень SSE3 можна виділити п’ять інструкцій, що дозволяють прискорити обчислення з комплексними числами. Сюди відносяться інструкції одночасного складання-віднімання addsubps і addsubpd і інструкції дублювання даних movsldup, movshdup і movddup (початковий операнд яких може бути адресою пам’яті). Перші дозволяють виключити операції зміни знака у частини елементів даних (зазвичай здійснювані за допомогою xorps/xorpd), другі – зайві операції розпаковування даних, що завантажуються з пам’яті (unpcklps/ unpcklpd, shufps/shufpd).

Використання SSE3 в завданнях комплексної арифметики дозволяє досягти істотного виграшу в швидкості (час виконання цього коду, що використовує нові розширення, майже в два рази менший, ніж час виконання аналогічного SSE2-коду).

19.7.3. Кодування відео

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

завданнях кодування відеоданих зазвичай є операція, в якій блоки поточного кадру порівнюються з блоками попереднього кадру з метою знаходження якнайкращої відповідності (критерієм останнього зазвичай є сума абсолютних різниць). Особливість такого алгоритму полягає в тому, що адреси блоків поточного кадру є вирівняними, тоді як блоки попереднього кадру зазвичай не є вирівняними по 16-байтній межі. У існуючій архітектурі IА-32 операції невирівняного завантаження SSE/SSE2 мають два серйозних недоліки:

відсутність апаратної підтримки; можливість «розриву» (перетину кордону) рядка кеша. Інструкція спеціалізованого завантаження невирівняних 128-

бітових значень lddqu покликана вирішити цю проблему. В той же час, оскільки ця команда завантажує більшу кількість даних (32 байти, починаючи з вирівняної адреси), є ряд обмежень на її використання. Зокрема, її не рекомендується використовувати для некешованих даних, або для даних з об’єднанням запису, а також в ситуаціях, коли може очікуватися «завантаження після збереження».

Заміна movdqu на lddqu зменшує час виконання такого коду.

Page 481: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

480

19.7.4. Вект орні операції Векторні операції найчастіше присутні в 3D-графічних

застосуваннях, які мають відношення до геометрії. До них відносяться тривимірне моделювання, методи трасування променів і моделювання комп’ютерних ігор.

Це операції з три- або чотиривимірними векторами: складання, віднімання і скалярне множення (множення вектора на число). Операндами інструкцій набору SSE є 128-бітові регістри XMM (або 128-бітове значення в пам’яті, яке повинне бути вирівняне по 16-байтной межі), вміст яких можна розглядати як чотиривимірні вектори, побудовані з чисел з одинарною точністю:

struct __declspec(align(16)) VECTOR4F { float x; float y; float z; float w; } Арифметичні інструкції набору SSE дозволяють оперувати з такими

векторами як єдиним цілим, тобто здійснювати ту саму операцію (складання, множення, віднімання, ділення) з кожним з компонентів двох векторів одночасно. За рахунок цього при використанні розширень SSE досягається значний виграш в продуктивності. Як приклад розглянемо операцію складання двох трикомпонентних векторів: A і B (четвертий компонент векторів в даному випадку не використовується).

VECTOR4F A, B; __asm { movaps xmm0, xmmword ptr[A] movaps xmm1, xmmword ptr[B] addps xmm0, xmm1 movaps xmmword ptr[A], xmm0 } З цього прикладу видно, що для здійснення операції додавання

необхідна всього одна інструкція addps (за умови, що як початкові вектори, так і результат складання зберігаються в XMM-регістрах, тобто операції завантаження-вивантаження даних не потрібні). Для здійснення подібної операції за допомогою FPU треба було б використовувати набагато більшу кількість операцій:

VECTOR4F A, B;

Page 482: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

481

__asm { fld dword ptr[A] fadd dword ptr[B] fld dword ptr[A+4] fadd dword ptr[B+4] fld dword ptr[A+8] fadd dword ptr[B+8] fxch st(2) fstp dword ptr[A] fstp dword ptr[A+4] fstp dword ptr[A+8] } Такий самий виграш в швидкості при використанні SSE можна

отримати і в будь-яких інших операціях з векторами, які здійснюються поелементно, іншими словами, вертикально (тобто коли та сама арифметична операція застосовується по відношенню до кожного i-го елемента обох векторів: A і B). Проте, у векторній алгебрі відомий і ряд інших операцій з векторами, здійснюваних з різними елементами того самого вектора, або горизонтально. Найяскравіший тому приклад – скалярний добуток двох векторів або обчислення довжини вектора (квадратного кореня з скалярного добутку вектора самого на себе).

Команди розширення SSE3 дозволяють отримати серйозний виграш в продуктивності.

Page 483: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

482

20. ОСНОВИ СТВОРЕННЯ ВІКНА ОС WINDOWS

20.1. Створення вікна

Вікно (з погляду користувача) – це прямокутна область екрана, що відповідає додатку або його частині. Додаток може керувати декількома вікнами, серед яких виділяють одне головне вікно-рамку (Frame Window).

З погляду операційної системи, вікно – це в більшості випадків кінцевий пункт, в якому прямують повідомлення.

З погляду програміста, вікно – це об’єкт, атрибути якого (тип, розмір, положення на екрані, вид курсора, меню, значок, заголовок) повинні бути спочатку сформовані, а потім зареєстровані системою. Маніпуляція з вікном здійснюється за допомогою спеціальної віконної функції, яка має свою структуру.

Етапи створення вікна: 1. Створення образу вікна – класу, який визначає ціле сімейство

вікон процедурою WndClassEx (WNDCLASSEX). 2. Реєстрація класу процедурою REGISTERСLASSEX, щоб образ

вікна став доступний в програмі. 3. Створення вікна процедурою CREATEWINDOWEX за зразком,

який задано класом. За перший етап (створення образу вікна) відповідає функція

(процедура) WNDCLASSEX, яка обробляє всі повідомлення і має вид структури:

WNDCLASSEX STRUCT ; функція створення образу вікна cbSize DWORD ? ; розмір структури style DWORD ? ; стиль вікна

lpfnWndProc DWORD ? ; адреса проц. яка реагує на повідомлення cbClsExtra DWORD ? ; кількість байтів для структури cbWndExtra DWORD ? ; кількість доп. байтів для доп. структур

Page 484: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

483

hlnstance DWORD ? ; дескриптор програмі створення вікна hlcon DWORD ? ; дескриптор «великої» піктограми hCursor DWORD ? ; визначає курсор hbrBackGround DWORD ? ; описує колір заповнення вікна IpszMenuName DWORD ? ; визначає ім’я ресурсу меню IpszClassName DWORD ? ; визначає ім’я класу hlconSm DWORD ? ; маленьке віконце

WNDCLASSEX ENDS Параметри цієї структури такі: • cbSize – число байтів, зайнятих структурою WNDCLASSEX,

що зазвичай визначається як SIZEOF WNDCLASSEX; • style – визначає поведінку вікна даного класу. Поле style

задається константами, що починаються з букв CS_. Всі вони дорівнюють ступеням двійки, тому їх об’єднання оператором OR рівносильно установці відповідних «прапорців». Наприклад, CSVREDRAW дорівнює 20, а CS_HREDRAW – 21. Отже, їх об’єднання CS_HREDRAW or CS_VREDRAW встановить нульовий і перший двійкові розряди поля style, а це означає, що вікно даного класу повинне перемальовуватися при зміні як горизонтального, так і вертикального розмірів;

• lpfnWndProc – адреса процедури, яка реагує на повідомлення, що прийшли від вікна;

• cbСlsЕxtra, cbWndExtra – ці поля використовуються рідко і тому дорівнюють нулю;

• hInstance – дескриптор програми, в якій створюється вікно; • hIcon – дескриптор «великої» піктограми, яка показується на

екрані при натисненні клавіш Alt+tab; • hCursor – дескриптор курсора миші. Звичайна стрілка задається

константою IDC_ARROW. Але якщо задати курсор як IDC_WAIT, то курсор миші перетвориться на зображення пісочного годинника;

• hbrBackGround – описує колір заповнення вікна. Найчастіше цей колір білий або сірий;

• lpszMenuName – адреса імені меню. Якщо меню не використовується, то параметр дорівнює NULL;

• lpszClassName – указівник на рядок з нульовим символом у кінці, який містить ім’я класу вікна. Це ж ім’я має бути у параметрі lpszСlassName функції CreateWindow().

Page 485: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

484

• hlconSm – дескриптор «маленької» піктограми, яка показується на панелі завдань Windows в лівому верхньому кутку вікна.

За другий етап створення вікна відповідає функція (процедура) RegisterClassEx, яка створений клас вікна робить доступним програмі, щоб та змогла за його образом і подобою створювати справжні вікна.

За третій етап створення вікна відповідає функція

CreateWindowEx, яка має вигляд:

invoke CreateWindowEx, \ ; створення вікна з розширеним стилем NULL, \ ; додатковий стиль ADDR ClassName, \ ; адреса імені класу ADDR AppName, \ ; адреса імені вікна WS_OVERLAPPEDWINDOW,\ ; базовий стиль CW_USEDEFAULT, \ ; горизонтальна координата вікна CW_USEDEFAULT, \ ; вертикальна координата вікна CW_USEDEFAULT, \ ; ширина вікна CW_USEDEFAULT, \ ; висота вікна NULL, \ ; дескриптор батьківського вікна NULL, \ ; дескриптор меню hInstance, \ ; дескриптор програми NULL CW_USEDEFAULT задає значення за умовчанням, а

WS_OVERLAPPEDWINDOW – найпоширеніший стиль вікна.

20.2. Обробка повідомлень Будь-яке вікно призначене для прийому повідомлень. Ці

повідомлення в ОС Windows повинні мати структуру MSG: MSG STRUCT

hwnd DWORD ? message DWORD ? wParam DWORD ? lParam DWORD ? time DWORD ? pt POINT <>

MSG ENDS

Page 486: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

485

де: • hwnd – дескриптор джерела повідомлення; • message – тип повідомлення (наприклад WM_LBUTTONUP –

повідомлення про те, що піднята ліва кнопка миші); • wParam та lParam – параметри повідомлення, що залежать від

його типу; • time – час приходу повідомлення; • pt – структура, що зберігає координати повідомлення. Довга черга повідомлень розбивається ОС на декілька дрібних.

Кожна така черга обробляється конкретною програмою в циклі: .WHILE TRUE

invoke GetMessage, ADDR msg, NULL, 0, 0 ; прийом повідомлення or eax, eax jz Quit

invoke DispatchMessage, ADDR msg ; відправка повідомлення .ENDW

Quit: Функція GetMessage приймає повідомлення, призначене для даної

програми, a DispatchMessage відправляє його функції WndProc, яка обслуговує конкретне вікно. У простому випадку така функція реагує тільки на повідомлення WM_DESTROY, яке свідчить про те, що вікно, яке його послало, в даний момент знищується (наприклад, через натиснення “хрестика” на вікні):

WndProc proc hWnd:HWND. uMsg:UINT, \ wParam:WPARAM, IParam:LPARAM

.IF uMsg==WM_DESTROY ; якщо тип “дорівнює знищенню” invoke PostQuitMessage,NULL ; то передача WM_QUIT

.ELSE ; інакше invoke DefWindowProc, hWnd, uMsg, wParam, lParam ; обробка

ret .ENDIF

Функція WndProc обробляє повідомлення, послані їй Windows.

Тільки Windows може викликати процедуру WndProc(). Параметри процедури WndProc:

• hWnd – дескриптор примірника вікна, що пересилає

Page 487: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

486

повідомлення; • uMsg – фактичний ідентифікатор (тип) повідомлення; • wParam та lParam – інформаційні 32-розрядні параметри для

повідомлення. Функція WndProc визначає існування вікна. Якщо воно існує, то

повідомлення WM_DESTROY не виникає, і всякі інші повідомлення відправляється стандартній функції DefWindowProc, у якій вони і обробляються. Якщо ж вікно знищується, функція PostQuitMessage генерує повідомлення WM_QUIT, яке стає в загальну чергу, а потім передає функції GetMessage.

Функція GetMessage відповідає на повідомлення WM_QUIT тим, що повертає нуль в регістр еах. Тому цикл .WHILE припиняється і програма завершує роботу, переходячи до мітки QUIT.

Функція DefWindowProc() передбачає обробку за умовчанням

повідомлень, не оброблених в додатку. Параметри: • hWnd – дескриптор вікна, що отримує повідомлення; • uMsg – поле найменування повідомлення; • wParam та lParam – параметри повідомлення.

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

вікно. Для перемальовування вікна служить повідомлення WM_PAINT. Це повідомлення посилає функція UpdateWindow. Повідомлення прямує безпосередньо віконній процедурі, минаючи чергу повідомлень. Якщо область оновлення порожня, повідомлення не відправляється.

Для того щоб програма могла відобразити на екрані повідомлення, необхідно додати гілку.ELSEIF. Повний текст програми наведено в листингу 20.1.

Листинг 20.1. .386 ; директива визначення типу мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows option casemap:none ; відмінність малих та великих літер include \masm32v9_0\include\windows.inc include \masm32v9_0\include\user32.inc

Page 488: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

487

include \masm32v9_0\include\kernel32.inc include \masm32v9_0\include\gdi32.inc includelib \masm32v9_0\lib\user32.lib includelib \masm32v9_0\lib\kernel32.lib includelib \masm32v9_0\lib\gdi32.lib WinMain proto hInst:HINSTANCE,CmdShow:DWORD

.data ; директива визначення даних ClassName db "Первый класс",0 AppName db "Перше вікно",0 Hello db "Перше повідомлення!!!",0

.data? ; директива невизначених даних hInstance HINSTANCE ?

.code ; директива початку сегмента команд start: ; мітка початку програми з ім’ям start invoke GetModuleHandle, NULL

mov hInstance,eax invoke WinMain, hInstance,SW_SHOWDEFAULT invoke ExitProcess,eax

WinMain proc hInst:HINSTANCE,CmdShow:DWORD LOCAL wc:WNDCLASSEX LOCAL msg:MSG LOCAL hwnd:HWND push hInstance pop wc.hInstance mov wc.cbSize,SIZEOF WNDCLASSEX mov wc.style, CS_HREDRAW or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.hbrBackground,COLOR_WINDOW+1

invoke GetStockObject, WHITE_BRUSH ; читання описувача mov wc.hbrBackground, eax mov wc.lpszMenuName,NULL mov wc.lpszClassName,OFFSET ClassName

invoke LoadIcon,NULL,IDI_APPLICATION ; ресурс піктограми mov wc.hIcon,eax mov wc.hIconSm,eax

Page 489: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

488

invoke LoadCursor,NULL,IDC_ARROW ; ресурс курсора mov wc.hCursor,eax mov wc.cbClsExtra,NULL mov wc.cbWndExtra,NULL

invoke RegisterClassEx, ADDR wc ; функція регістрації класу вікна invoke CreateWindowEx, \ ; функція створення вікна за зразком NULL,ADDR ClassName, \ ; стиль та адреса імені класу ADDR AppName,\ ; адреса імені вікна WS_OVERLAPPEDWINDOW, \ ; базовий стиль CW_USEDEFAULT,CW_USEDEFAULT, \ ; координати вікна CW_USEDEFAULT,CW_USEDEFAULT, \ ; розміри вікна NULL,NULL,\ ; дескриптори батьківського вікна та меню hInst,NULL ; дескриптор програми

mov hwnd,eax invoke ShowWindow, hwnd,SW_SHOWNORMAL ; видимість вікна

.WHILE TRUE invoke GetMessage, ADDR msg,NULL,0,0 ; читання повідомлення

or eax,eax jz Quit

invoke DispatchMessage, ADDR msg ; передача повідомлення .ENDW

Quit:

mov eax,msg.wParam ret WinMain endp

WndProc proc hWnd:HWND, uMsg:UINT, \ wParam:WPARAM, lParam:LPARAM LOCAL hdc:HDC LOCAL ps:PAINTSTRUCT LOCAL rect:RECT

.IF uMsg==WM_DESTROY invoke PostQuitMessage,NULL ; передача повідомлення

.ELSEIF uMsg==WM_PAINT

Page 490: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

489

invoke BeginPaint,hWnd, ADDR ps ; виклик підготовчої процедури mov hdc,eax

invoke GetClientRect,hWnd, ADDR rect ; визначення характер. вікна invoke DrawText, hdc,ADDR Hello,-1, ADDR rect, \ ; малювання тексту

DT_SINGLELINE or DT_CENTER or DT_VCENTER invoke EndPaint,hWnd, ADDR ps ; закінчення малювання

.ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ; обробка

ret .ENDIF

xor eax,eax ret ; повернення керування ОС

WndProc endp ; закінчення процедури WndProc end start ; закінчення програми з ім’ям start Для отримання виконуваного файла з ім’ям, наприклад, 20_1l.exe

необхідно використовувати командний файл ml /c /coff "20_1L.asm" link /SUBSYSTEM:windows "20_1L.obj" Вигляд вікна, створеного відповідно до програми з листингу 20.1,

наведено на рис. 20.1. Для завершення роботи додатка необхідне одне з повідомлень:

WM_DESTROY чи WM_QUIT. При виборі пункту виходу додатка з вікна (або кнопки закриття)

виконується:

Рис. 20.1. Вигляд вікна, створеного відповідно до програми з листингу 20.1

Page 491: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

490

1. Видалення вікна за допомогою функції DestroyWindow(). 2. Виклик повідомлення WM_DESTROY. 3. Обробка WM_DESTROY. 4. Виконання функції PostQuitMessage(). 5. Виклик повідомлення WM_QUIT.

Процедура BeginPaint отримує загальні параметри пристрою, але їй не відоме положення вікна і його розміри.

Процедура GetClientRect заносить в спеціальну структуру rect положення вікна і його розміри.

Малюванням вікна займається процедура DrawText, яка керує п’ятьма параметрами:

дескриптором контексту; початковою адресою рядка символів; числом символів (якщо рядок завершується нулем – ставиться -1); адресою структури rect, що описує положення і розмір вікна; параметром, що визначає стиль виведення. Цей параметр можна

задати за допомогою бітових прапорів, сполучених операторами OR. У нашому випадку задається виведення єдиного рядка (DTSINGLELINE) в центрі вікна по горизонталі (DTCENTER) і вертикалі (DTVCENTER).

Після виведення рядка контекст пристрою вже не потрібний, і щоб не забивати пам’ять зайвими параметрами, його слід видалити процедурою EndРaint.

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

створювався з параметрами CS_HREDRAW or CS_VREDRAW, які задають перемальовування вікна при зміні його горизонтальних (CS_HREDRAW) або вертикальних (CS_VREDRAW) розмірів. Як тільки вікно змінюється, Windows передає повідомлення WM_PAINT – і напис малюється наново.

20.4. Меню

Існує два види меню: – головне меню вікна; – висхідне (контекстне) меню. Основним елементом меню, що відображається, є рядок або

графічний об’єкт.

Page 492: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

491

Будь-яке вікно може мати меню. Головне меню знаходиться нижче заголовка вікна, його рядки розташовані в одну або декілька ліній. При виборі рядка головного меню, як правило, активізується розділ меню. Розділом меню є тимчасове меню.

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

За способом створення розрізняють статичне і динамічне меню. Статичне меню створюють до запуску і не змінюють в процесі роботи додатка. Динамічне меню створюють в процесі роботи додатка. Динамічне меню після створення можна змінювати або залишити незмінним. Робота з рядками статичних і динамічних меню нічим не відрізняється.

Самий простий шлях – це завдання меню в спеціальному файлі з розширенням .rc (листинг 20.2). Розширення .rc – це файл з ресурсами (малюнки, опис меню, курсори та таке ін.).

Листинг 20.2. Файл menu.rc завдання меню #define IDM_HELLO 1 #define IDM_EXIT 2 #define IDM_ABOUT 3 FirstMenu MENU { POPUP "программа"{ MENUITEM "Функции",IDM_HELLO MENUITEM SEPARATOR MENUITEM "Окончание",IDM_EXIT } POPUP "результаты"{ MENUITEM "About",IDM_ABOUT } } У головній програмі (листинг 20.3) потрібно задати константи, які

відповідають пунктам меню.

Page 493: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

492

Листинг 20.3. Головна програма керування меню: .386 ; директива визначення типу мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті ; та угоди ОС Windows

option casemap:none ; відмінність малих та великих літер

include \masm32v9_0\include\windows.inc include \masm32v9_0\include\user32.inc include \masm32v9_0\include\kernel32.inc includelib \masm32v9_0\lib\user32.lib includelib \masm32v9_0\lib\kernel32.lib IDM_HELLO equ 1 IDM_EXIT equ 2 IDM_ABOUT equ 3

.data ; директива визначення даних

ClassName db "SimpleWinClass",0 AppName db "Знакомство с меню",0 MenuName db "FirstMenu",0 Hello_string db "Ну, здравствуй!",0 Goodbye_string db "Прощай!",0 About_string db "Испытание меню",0 wc WNDCLASSEX <> msg MSG <> hwnd HWND ? hInstance HINSTANCE ?

.code ; директива початку сегмента команд start: ; мітка початку програми з ім’ям start

invoke GetModuleHandle, NULL ; зчитування описувача модуля mov hInstance,eax mov wc.cbSize,SIZEOF WNDCLASSEX mov wc.style, CS_HREDRAW or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.cbClsExtra,NULL mov wc.cbWndExtra,NULL push hInstance

Page 494: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

493

pop wc.hInstance mov wc.hbrBackground,COLOR_WINDOW+1 mov wc.lpszMenuName,OFFSET MenuName mov wc.lpszClassName,OFFSET ClassName invoke LoadIcon,NULL,IDI_APPLICATION ; ресурс піктограми mov wc.hIcon,eax mov wc.hIconSm,eax

invoke LoadCursor,NULL,IDC_ARROW ; ресурс курсору mov wc.hCursor,eax

invoke RegisterClassEx, addr wc ; регістрація класу вікна invoke CreateWindowEx,NULL, ADDR ClassName,\

ADDR AppName, WS_OVERLAPPEDWINDOW,\ CW_USEDEFAULT, CW_USEDEFAULT,\ CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\ hInstance,NULL mov hwnd,eax

invoke ShowWindow, hwnd,SW_SHOWNORMAL ; видимість вікна .WHILE TRUE

invoke GetMessage, ADDR msg,NULL,0,0 ; читання повідомлення or eax, eax jz Quit invoke DispatchMessage, ADDR msg ; передача повідомлення

.ENDW

Quit: mov eax,msg.wParam invoke ExitProcess, eax WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

.IF uMsg==WM_DESTROY invoke PostQuitMessage,NULL ; передача повідомлення

.ELSEIF uMsg==WM_COMMAND mov eax,wParam

.IF ax==IDM_HELLO invoke MessageBox, \ ; створення та відображення повідомлення

NULL,ADDR Hello_string, OFFSET AppName,MB_OK

Page 495: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

494

.ELSEIF ax==IDM_ABOUT invoke MessageBox, \ ; створення та відображення повідомлення NULL,ADDR About_string,OFFSET AppName, MB_OK

.ELSE invoke DestroyWindow,hWnd .ENDIF

.ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret

.ENDIF xor eax,eax ret ; повернення керування ОС WndProc endp end start ; закінчення програми з ім’ям start Командний файл для створення .ехе-файла повинен бути таким: ml /c /coff "20_2L.asm" rc "menu.rc" link /SUBSYSTEM:windows "20_2L.obj" "menu.res" При запуску файла menu.rc запускається С++ та відображається

меню, яке наведено на рис. 20.2.

Рис. 20.2. Меню програми з листингу 20_3L.asm при запуску файла menu.rc

Page 496: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

495

При запуску створеного exe-файла відображається меню, яке наведено на рис. 20.3.

20.5. Керування кольором

Встановлювати кольори вікна консолі можна двома шляхами. Можна змінювати поточний колір символів за допомогою функції SetConsoleTextAttribute, яка діє на всі подальші символи, що виводяться на консоль, або встановлювати атрибути окремих комірок, викликаючи функцію WriteСonsoleOutputAttribute.

Функція SetConsoleTextAttribute Ця функція дозволяє встановити колір символів і колір фону для

тексту, що виводиться на консоль. Її прототип наступний: SetConsoleTextAttribute PROTO outHandle:dword ; дескриптор консолі nColor:dword ; атрибути кольору Значення кольору зберігаються в молодшому байті параметра

nColor. Функція WriteConsoleOutputAttribute Ця функція копіює масив значень атрибутів послідовних комірок

екранного буфера консолі починаючи з вказаної позиції. Її прототип наступний:

WriteConsoleOutputAttribute PROTO outHandle:dword ; дескриптор виходу

Рис. 20.3. Меню програми при запуску exe- файла

Page 497: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

496

pAttribute:ptr word ; записувані атрибути nLength:dword ; кількість комірок xyCoord:coord ; координати першої комірки IpCountr:ptr dword ; кількість записаних комірок Параметр pAttribute вказує на масив атрибутів, де кожен молодший

байт включає інформацію про колір. Параметр nLength визначає довжину масиву. Параметр xyCoord визначає початкову комірку. Параметр IpCountr указує на змінну, яка містить кількість записаних комірок.

Page 498: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

497

ДОДАТОК 1

СИСТЕМА БАЗОВИХ КОМАНД МП ПЛАТФОРМИ х86 Таблиця Д1.1

Система базових команд МП платформи х86 у компактній формі Мнемокод Операнд 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 499: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

498

Закінчення табл. Д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 500: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

499

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

Вплив команд на прапорці ілюструє табл. Д1.3, в яку включені

Page 501: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

500

тільки ті команди, що цей вплив здійснюють. Знак питання відповідає випадкам, коли стан прапорця після виконання команди довільний (наприклад, залежить від конкретних значень операндів).

Таблиця Д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 – Г – – – –

Примітка. "+" – результат операції впливає на прапорець; "–" – не

впливає; 1 – встановлює в "1"; 0 – встановлює в "0"; Г – інвертує; ? – не визначений.

У табл. Д1.2 використовуються такі позначення: disp 8/16 – зміщення у форматі команди, що складається з одного чи двох байтів; d 8/16 – одно- чи двобайтова константа; sbr – ім’я підпрограми; diff – різниця між адресою переходу і вмістом указівника команд IP (при адресації відносно IP); label – мітка до переходу. Приклад ланцюгових команд: MOVSB – пересилання байтів, MOVSW – пересилання слів.

Зведену систему команд МП платформи х86 наведена в табл. Д1.4.

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 502: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

501

Таблиця Д1.4 Зведена система базових команд МП платформи х86

Мне-моніка

Операнди Ознаки Символічне позначення операції

Зміст операції

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

Логічна операція АБО

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 503: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

502

Продовження табл. Д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

Page 504: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

503

Продовження табл. Д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, D (dst) ← 0FFH- (dst)

(dst) ← 0FFFFH – (dst) AND AND

dst, src dst, data

O = 0, C = 0 S, P, Z

B, W, D B, W, D

(dst) ← (dst) ٨ (src)

(dst) ← (dst) ٨ data ОR OR

dst, src dst, data

O = 0, C = 0 S, P, Z

B, W, D B, W, D

(dst) ←( dst) ٧ (src)

(dst) ← (dst) ٧ data XOR XOR

dst, src dst, data

O = 0, C = 0 S, P, Z

B, W, D B, W, D

(dst) ← (dst) + src)

(dst) ← (dst) + data TEST TEST

dst, src dst, data

O = 0, C = 0 S, P, Z

B, W, D B, W, D

(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 505: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

504

Продовження табл. Д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 Перехід при відсутності

переповнення

Page 506: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

505

Закінчення табл. Д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 507: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

506

У табл. Д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 508: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

507

ДОДАТОК 2

API-ФУНКЦІЇ, ЯКІ ЧАСТО ВИКОРИСТОВУЮТЬСЯ

Спрощене виведення повідомлень: MessageBox, MessageBoxEx, MessageBoxIndirect, MessageBeep (функція не виводить повідомлення, а тільки видає відповідний звуковий сигнал).

Створення і знищення вікон: CreateWindow (найбільш популярна функція створення вікон), CreateWindowEx, CloseWindow (функція закриття вікна), DestroyWindow.

Створення і знищення діалогів: CreateDialog, CreateDialogIndirect, CreateDialogIndirectParam, CreateDialogParam (ці функції тільки створюють діалог); DialogBox, DialogBoxIndirect, DialogBoxIndirectParam, DialogBoxParam (ці функції дозволяють створювати модальні діалоги; керування не повертається програмі, поки діалог не буде закритий); EndDialog, DestroyWindow.

Читання і зміна текстів вікон: GetWindowText, GetDlgItemText (читання тексту вікна або елементу діалогу); GetWindowTextLength (читання довжини тексту вікна); GetDlgItemInt (читання тексту елементу діалогу як 32-бітового числа); SetWindowText, SetDlgItemText, SetDlgItemInt (установка нового тексту вікна або елементу діалогу).

Зміна видимості, позиції і інших подібних властивостей вікна: Enablewindow (активація/деактивація вікна); ShowWindow; ShowWindowAsync (зміна видимості і стану вікна, зокрема – дозволяє мінімізувати або навпаки – розвернути вікно); SetWindowPos, MoveWindow (зміна положення вікна); SetWindowWord (застаріла функція), SetWindowLong – функції, що дозволяють модифікувати широкий спектр параметрів вікна; Getwindowword, Getwindowlong – функції читання параметрів вікна.

Завантаження ресурсів: Loadimage (універсальна функція завантаження зображень, ікон і курсорів); LoadBitmap, LoadIcon, LoadCursor,

Page 509: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

508

FindResource, FindResourceEx, LoadResource (функції завантаження ресурсів будь-якого типу в пам’ять).

Відображення зображень і текстів на екрані: BitBlt, StretchBlt, MaskBlt (функції копіювання Bitmap’ів на екран); Drawtext, Textout, Tabbedtextout (звичайне виведення тексту); GrayString (рідко використовувана функція, виводить на екран рядок із стилем напису на неактивному елементі, що керує).

Робота з файлами: OpenFile (застаріла функція); CreateFile (основна функція відкриття файлів та директорій); ReadFile, ReadFileEx (функції читання з файлів); WriteFile, WriteFileEx (функції запису у файл); Setfilepointer (переміщення по файлу); Getfiletime, Getfileattributes, Setfiletime, Setfileattributes (читання і модифікація часу створення і атрибутів файлів/директорій); Setendoffile (зміна розмірів файлу).

Операції з реєстром: Regopenkey, Regopenkeyex, Regcreatekey, Regcreatekeyex (відкриття і створення ключів реєстру); RegQueryInfoKey (запит інформації про ключ, зокрема – для перевірки факту існування підключа); Regqueryvalue,regqueryvalueex (читання значень з реєстру); Regsetvalue, Regsetvalueex (запис ключів в реєстр); Regclosekey (закриття ключа реєстру).

Читання і запис INI-файлів: GetProfileSection, WriteProfileSection, GetProfileInt, GetProfileString, WriteProfileString, WriteProfileInt (функції для роботи з файлом Win.ini, в даний час вважаються застарілими, але іноді використовуються); GetPrivateProfileSection, GetPrivateProfileSectionNames, WritePrivateProfile Section, GetPrivateProfileInt, GetPrivateProfileString, GetPrivateProfileStruct, WritePrivateProfileString, WritePrivateProfileInt, Write PrivateProfileStruct (функції роботи з областю реєстру, відведеною для зберігання настройок програм, або з довільним INI-файлом; ця група функцій вважається застарілою).

Робота з датою і часом: GetSystemTime, GetLocalTime, GetSystemTimeAsFileTime (читання поточного часу); Setsystemtime, Setlocaltime (встановлення нового часу);

Page 510: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

509

Localtimetofiletime, Filetimetolocaltime, Filetimetosystemtime, Systemtimetofiletime (перетворення формату часу); Comparefiletime (порівняння двох змінних, що зберігають час); Getfiletime, Setfiletime (запис і читання часу створення, останньої модифікації і останнього доступу до файлу).

Процеси та потоки: створення та управління: WinExec (застаріла функція запуску виконуваних файлів); CreateProcess (функція, зазвичай використовувана для запуску виконуваних файлів); ShellExecute, ShellExecuteEx (пара «альтернативних» функцій для запуску додатків (стосовно виконуваних файлів) або відкриття, друку і тому подібне); ExitProcess («стандартне» завершення процесу, ця функція здатна завершити тільки той процес, усередині якого вона викликана); TerminateProcess (примусове завершення процесу; ця функція здатна «убити» будь-який процес (у NT – за наявності відповідних привілеїв), що іноді використовується захистами для придушення крекерського софту); CreateThread (штатна функція створення нового потоку); CreateRemoteThread (функція «живе» тільки під ОС NT і в захистах практично не використовується. Широко використовується крекерами для втручання в чужий процес; ExitThread, TerminateThread (штатне завершення і аварійне знищення потоків відповідно).

Завантаження і вивантаження DLL: Loadlibrary, Loadlibraryex (функції завантаження динамічних бібліотек); Loadmodule (застаріла функція завантаження DLL); GetProcAddress (функція, що повертає адресу функції або змінної, оголошеної в експорті DLL по імені цієї функції/змінної (відповідна DLL повинна бути підвантажена поточним процесом). Ця функція широко використовується як в захистах, щоб виклик якої-небудь функції не «світився» в дизасембльованому листингу, так і для прийомів типу push <бажана адреса повернення>; jmp <адреса функції, отримана через Getprocaddress>, використовуваних для заховання крапки, звідки була викликана функція); FreeLibrary (функція примусового вивантаження DLL).

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 511: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

510

ЛІТЕРАТУРА 1. Голуб Н.Г. Искусство программирования на Ассемблере. Лекции

и упражнения. –2-е изд.. – СПб.: “ДиаСофтЮП”, 2002. – 656 с. 2. Главчев М.І., Клименко А.М., Рисований О.М., Філоненко А.М./

За ред. О.М. Рисованого: Цифрові пристрої та мікропроцесори. Організація та програмування: Навч. посіб. – Х.: ХВУ, 2001. – 327 с.

3. Григорьев В.Л. Программирование однокристальных микропроцессоров. – М.: Энергоатомиздат, 1987. – 288 с.

4. Гук М., Юров В. Процессоры Pentium 4, Athlon и Duron. – СПб.: Питер, 2001. – 512 с.

5. Зубков С.В. Assemler для DOS, Windows и Unix . – М.: ДМК Пресс; СПб.: Питер, 2006. – 608 с.

6. Ирвин Кип. Язык ассемблера для процессоров Intel, 3-е издание.: Пер. с англ. – М.: Издат. дом “Вильямс”, 2002. – 616 с.

7. Кравець В.О., Рисований О.М. Системне програмування. Програмування на мові асемблера. Навч. посібник. – Харків: НТУ “ХПІ”, 2007. – 448 с.

8. Крупник А. Асемблер. Самоучитель. – СПб.: Питер, 2005. – 2005. – 235 с.: ил.

9. Магда Ю.С. Использование ассемблера для оптимизации программ на С++. – СПб.: Питер, 2004. – 496 с.

10. Магда Ю.С. Ассемблер для процессоров Intel Pentium. – СПб.: Питер, 2006. – 410 с.

11. Моделі та структури даних у системах автоматизованого керування/ Фурман І.О., Краснобаєв В.А., Далека В.Д., Корольова Н.А., Рисований О.М.: Підручник для ВНЗ. – К., 2004. – 253 с.

12. Микропроцессоры и микропроцессорные системы. Кн. 1: Архитектура и функционирование/ Кравец В.А., Рысованый А.Н., Домнин Ф.А., Зыков И.С., Скороделов В.В., Шеин А.Н.: Учеб. пособ. –Х.: ХВУ, 2000. – 282 с.

13. Микропроцессоры и микропроцессорные системы. Кн. 2:

Page 512: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

511

Программирование, разработка устройств и систем. Кравец В.А., Домнин Ф.А., Скороделов В.В., Зиков И.С., Рысованый А.Н.: Учеб. пособ. – ХВУ, 2000. – 350 с.

14. Мікропроцесорні пристрої. Проектування тестових програм вузлів персонального комп’ютера/За ред. В.О. Кравця, О.М. Рисованого: Навч. посіб. – Х.: ХВУ, 2001. – 226 с.

15. Пирогов В.Ю. Ассемблер под Windows. – СПб.: БХВ-Петербург, 2003.

16. Пирогов В.Ю. Асемблер и дизасемблирование. – СПб.: БХВ-Петербург, 2006. – 464 с.

17. Подбельский В.В. Язык С++: Учеб. пособ. – М.: Финансы и статистика, 2004.

18. Проектування тестових програм вузлів персонального комп’ютера. В.О. Кравець, Ю.М. Колибін, П.О. Качанов, І.Ф. Домнін, М.Й. Заполовський, О.М. Рисований / За ред. В.О. Кравця, О.М. Рисованого: Навч. посіб. – Х.: НТУ “ХПІ”, 2001. – 225 с.

19. Рудаков П.И., Финогенов К.Г. Программируем на языке асемблера IBM PC: В 4-х частях – М.: Энтрон, 1995. – 164 с.

20. Рисований О.М., Кавун С.В., Грушенко М.В., Калачова В.В., Осієвський С.В. Комп’ютерні системи / За ред. М.Ф. Пічугіна: Навч. посіб. – МОУ, Х.: ХУПС, 2005. – 328 с.

21. Рисований О.М., Грушенко М.В. Цифрові пристрої і мікропроцесори. Архітектура і програмне забезпечення: Навч. посіб. – Х.: ХУПС, 2005. – 384 с.

22. Рогожина С.І., Рисований О.М., Федорченко В.М. Системне програмування та операційні системи. Частина II. Навч. посіб. – Х.: ХУПС, 2007 р. – 200 с.

23. Фельдман С.К. Системное программирование на персональном компьютере. – М.: Бук-пресс, 2006. – 512 с.

24. Цифрові пристрої та мікропроцесори. Організація та функціонування / За ред. О.М. Рисованого: Навч. посіб. – Х.: ХВУ, 2002. – 328с.

25. Юров В. ASSEMBLER: Практикум – СПб.: Питер, 2001. 26. Юров В. ASSEMBLER: Спец. справочник. – СПб.: Питер, 2004. 27. Юров В. ASSEMBLER: Учебник – СПб.: ПИТЕР, 2004.

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 513: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів

Навчальне видання

КРАВЕЦЬ Валерій Олексійович РИСОВАНИЙ Олександр Миколайович

СИСТЕМНЕ ПРОГРАМУВАННЯ Асемблер під Win32 API

Навчальний посібник

Роботу до видання рекомендував В.Д. Дмитрієнко

Редактор Л.Л. Яковлева

План 2008 р., поз. №1/56 Підписано до друку 12.05.2008. Формат 60х84 1/16. Папір офісний. Riso-друк. Гарнітура Times New Roman. Ум. друк. арк. 27,5. Обл.-вид. арк. 29,9. Наклад 300 прим. Зам. № Ціна договірна.

Видавничий центр НТУ «ХПІ». Свідоцтво про державну реєстрацію ДК № 116 від 10.07.2000 р.

61002, Харків, вул. Фрунзе, 21. Друкарня НТУ «ХПІ», 61002, Харків, вул. Фрунзе, 21.

Александр
Текст
http://blogs.kpi.kharkov.ua/v2/asm
Page 514: Р54blogs.kpi.kharkov.ua/v2/asm/wp-content/uploads/sites/20/... · 2017-03-04 · Лабораторна робота “Передача параметрів ... Набір символів