Основи асемблера
-
Олена Раєвська 2 роки тому Переглядів:
4 значеннями як такими може лише математичний співпроцесор. Робота з речовими числами потребує окремого розгляду. Беззнакові числа є звичайним перетворенням числа в двійкове; отже, діапазон значень беззнакових чисел: 0. 2П – 1, де п – це розрядність числа. Старший біт знакових чисел означає знак числа: якщо старший біт - одиниця, то число негативне. Решта бітів - це модуль числа. Діапазон знакового числа: – 2 n n-1-1. Принципи складання та віднімання цілих, знакових і беззнакових чисел однакові; відмінності виникають при множенні та розподілі чисел. Команди SUB і ADD Команда ADD, як зрозуміло з назви, складає обидва операнда і зберігає отриманий результат у операнді призначення. Синтаксис команди ADD: add , . Формат операндів ідентичний до формату операндів команди MOV. Обидва операнди складаються, і результат зберігається в призначенні. Після операції додавання в залежності від результату змінюються відповідні біти в регістрі прапорів. Можна здогадатися, що команда SUB здійснює віднімання - а якщо бути точніше, то з операнда призначення вона віднімає операнд джерела і зберігає його в операнді призначення. Синтаксис SUB повністю ідентичний команді ADD. Якщо після складання (віднімання) двох операндів результат не міститься в операнді призначення (число занадто велике і негативне), відбувається переповнення і прапор OF встановлюється в 1. Якщо відбувся перенесення або позику зі старшого біта (наприклад, з біта 17 або 33), то встановлюється прапор перенесення. Зазвичай ці два прапори завжди супроводжують один одного, тобто якщо встановлюється один, то встановлюється другий. У разі віднімання можеі не встановити прапор переповнення. Також є ще дві команди збільшення та зменшення операнда – це INC та DEC. Ці команди збільшують та зменшують операнд на одиницю відповідно. Вони приймають лише один операнд, якою може бути регістр чи значення пам'яті. Розмір операнда може бути будь-яким (1, 2, 4, 8 байт). Як параметри всіх вищеописаних команд можуть виступати як знакові, і беззнакові числа. Команда MUL - беззнакове множення. Синтаксис команди: mul. Команда MUL множить операнд із регістром EAX(AL, АХ, RAX) і зберігає його в регістрах EDX:EAX (АХ, DX:AX, RDX:RAX). Операндом може бути регістр або значення пам'яті. У табл. 1.7 представлені можливі результати цієї команди. Таблиця 1.7. Залежність результату роботи команди MUL від розміру операнда Розмір операнда Результат 1 байт АХ = AL * 2 байти DX: AX = АХ * 4 байти EDX: EAX = ЕАХ * 8 байт RDX: RAX = RAX * Команда DIV - беззнаковий поділ. Синтаксис команди: div. Команда DIV ділить регістри EDX:EAX (АХ, DX:AX, RDX:RAX) на операнд і зберігає результат поділу в ЕАХ (AL, АХ, RAX), а також залишок від розподілу в EDX (АН, DX, RDX). У табл. 1.8 показано можливі результати роботи цієї команди.
5 Таблиця 1.8. Залежність результату роботи команди DIV від розміру операнда Розмір операнда Джерело Результат поділу Залишок розподілу 1 байт АХ AL АН 2 байта DX: AX AX DX 4 байта EDX: EAX EAX EDX 8 байт RDX: RAX RAX RDX Команда IMUL - знакове множення. Команда може приймати до трьох операндів. Ця команда має три форми запису залежно від того, скільки операндів вказано. 1. Перша форма – лише один операнд. Команда працює так само, як і MUL, тільки множення відбувається з урахуванням знака. 2. Друга форма – два операнди. Синтаксис: imul, . Як перший операнда може виступати лише регістр загального призначення, а другим операндом може бути регістр, значення пам'яті або безпосередньо значення. Операнди може бути будь-якого розміру, але якщо другий операнд - безпосередньо значення, воно може бути розміром 8 байт. Перший операнд множиться з урахуванням знака другого, і результат зберігається у першому операнді. 3. Третя форма – це три операнда. Формат: imul , , . Як перший операнда може виступати лише регістр загального призначення. Як другий операнда може виступати регістр або значення пам'яті. Перший і другий операнди мають бути однакового розміру. Третій операнд може лише безпосереднім значенням і може бути розміром 8 байт. З використанням цієї форми команда множить з урахуванням знака другий операнд на третій результат зберігає у першому. Команда IDIV - знаковий поділ. Команда IDIV за результатом роботи повністю ідентична команді DIV. Відмінність команди IDIV від DIV у тому, що й операнди мають різні знакові біти, то результат (приватне і залишок) буде негативним; якщо ж у операнда знакові біти будуть рівні, то результат (приватне і залишок) буде позитивним. Команди DIV та IDIV не впливають на регістр прапорів. Команда МUL встановлює прапори OF та CF у нуль, якщо старша частина результату (АН, DX, EDX, RDX) дорівнює нулю; у будь-якому іншому випадку ці біти встановлюються в одиницю. При використанні команди IMUL у першій формі прапори OF і CF встановлюються в одиницю, якщо будь-які значні біти переносяться у старшу частину результату (АН, DX, EDX, RDX), і в нуль, якщо у старшу частину результату переносів не було. Таким чином, якщо прапори OF і CF скинуті, то результат може бути зчитаний тільки з молодшої частини, і він буде вірним. При використаннікоманди IMUL у другій та третій формі прапори OF та CF встановлюються в одиницю, якщо розмірність результату більша, ніж розмір операнда, зазначеного як результат. Таким чином, якщо після операції множення виставлені прапори OF і CF, значить твір у результуючому операнді неправильний (усічений). Логічні операції Є кілька базових логічних операцій: операція "або" (команда OR), логічне "і" (команда AND), логічне заперечення (команда NOT), "що виключає або" (команда XOR).
6 Команда OR - операція бітового логічного АБО. Синтаксис команди: or , . Ця команда виробляє побітове логічне складання між переданими операндами і зберігає результат призначення. Операнди може бути розміром 1,2,4, 8 байт. При логічному додаванні результат є одиницею (істиною) при істинності будь-якого з операндів. Команда AND - операція бітового логічного І. Синтаксис команди: and . Ця команда здійснює побітове логічне множення переданих операндів і зберігає результат у призначенні. Операнди можуть бути розміром 1, 2, 4, 8 байт. При логічному множенні результат є одиницею (істиною) за істинності обох операндів. Команда NOT – операція бітового логічного заперечення. Синтаксис команди: not. Ця команда робить побітове логічне заперечення операнда. При логічному запереченні результат є запереченням операнда, т. е. якщо 1, то виходить 0, якщо 0 - виходить 1. Операнд може бути розміром 1,2,4,8 байт. Команда XOR - операція бітового, що виключає АБО. Синтаксис команди: хоr , . Команда XOR здійснює операцію побитового виключає «або» над переданими операндами і зберігає результат у призначенні. Операнди може бути розміром 1, 2,4,8 байт. Якщо операнди однакові, то результат 0, якщо різні – то 1. Такимчином, якщо вказати як обох операндів той самий регістр, то регістр буде обнулено. Цей прийом дуже корисним при оптимізації коду. Усі чотири перераховані вище логічні операції в залежності від результату операції змінюють відповідні біти в регістрі прапорів. Зрушення Зсув - це побитовий зсув операнда вправо чи вліво. Наприклад, зсув числа на 3 в результаті дасть всі команди зсуву мають однаковий синтаксис: команда , . Зрушення бувають різних видів: циклічні, арифметичні та логічні. Почнемо з логічних. SHL – логічне зрушення вліво. Команда здійснює зсув операнда вліво на вказану кількість біт. У біти, що звільнилися праворуч, заносяться нулі. Значення CF збігається зі значенням біта, який останнім витіснили за лівий край операнда. Якщо кількість бітів дорівнює 1, то ознака переповнення OF не визначено. Якщо ж кількість бітів дорівнює 1, тоді OF = 0, при тому що 2 старші біти вихідного значення операнда призначення збігалися; інакше OF = 1. SHR – логічний зсув вправо. Команда здійснює зсув операнда вправо на вказану кількість бітів. У біти, що звільнилися праворуч, заносяться нулі. Значення CF збігається зі значенням біта, який останнім витіснили за правий край операнда. Якщо біт знака зберігає своє значення, то ознака переповнення OF = 0, інакше OF = 1. Значення CF збігається зі значенням біта, який останнім витіснили за правий край операнда. Якщо кількість бітів дорівнює 1, то ознака переповнення OF не визначено. Якщо кількість дорівнює 1, то прапор OF дорівнює значенню старшого біта вихідного операнда. SAL – арифметичний зсув вліво. Команда повністю ідентична команді SHL. Це та сама команда, тільки імена різні. SAR – арифметичний зсув вправо. Команда ідентична команді SHR, за винятком того,що кожен знову вставлений зліва біт дорівнює найстаршому біту початкового операнда. Таким чином, при арифметичному зрушенні праворуч операнд не змінить свій знак. Наприклад, зсув числа на 3 біти вправо в результаті дасть
7 ROL - циклічний зсув ліворуч. Команда зсуває операнд вліво на вказану кількість бітів. Біт, що виходить за ліву межу, вставляється праворуч. Значення CF збігається зі значенням біта, який останнім витіснили за лівий край операнда. Якщо кількість бітів дорівнює 1, то ознака переповнення OF не визначено. Якщо кількість бітів дорівнює 1, то у прапор OF заноситься результат виконання операції виключає «або», застосованої до 2 старшим бітам вихідного значення операнда. ROR - циклічний зсув праворуч. Команда зсуває операнд праворуч на вказану кількість бітів. Біт, що виходить за ліву межу, вставляється зліва. Значення CF збігається зі значенням біта, який останнім витіснили за правий край операнда. Якщо кількість бітів дорівнює 1, то ознака переповнення OF не визначено. Якщо кількість бітів дорівнює 1, то OF заноситься результат виконання операції виключає «або», застосованої до 2 старшим бітів результату. RCL – циклічний зсув вліво через прапор CF. Команда зсуває операнд вліво на вказану кількість бітів. Біт, який виходить за лівий край, заноситься у прапор CF, а старе значення CF заноситься в правий біт, що звільнився. Якщо кількість бітів дорівнює 1, то ознака переповнення OF не визначено. Якщо ж кількість бітів дорівнює 1, то OF заноситься результат виконання операції виключає «або», застосованої до 2 старших бітів результату. RCR - циклічний зсув праворуч через прапор CF. Команда зсуває операнд праворуч на вказану кількість бітів. Біт, який виходить за правий край, заноситься у прапорCF, а старе значення CF заноситься в лівий біт, що звільнився. Якщо кількість бітів дорівнює 1, то ознака переповнення OF не визначено. Якщо ж кількість бітів дорівнює 1, то OF заноситься результат виконання операції виключає «або», застосованої до 2 старших бітів результату. У всіх команд операнд призначення може бути розміром 1,2,4,8 байт. Умовні та безумовні переходи є найважливішою частиною будь-якої програми; вони дозволяють писати програми з розгалуженими та циклічними алгоритмами. Дані Дані в програмах на асемблері оголошуються (або резервуються) директивами даних. Директиви визначення даних та їх розміри. Розмір (байти) Визначення даних 1 DB 2 DW, DU 4 DD 6 DF, DP 8 DQ 10 DT За директивою опису даних слід слідувати одне або кілька числових значень, розділених комами. Ці вирази визначають значення для найпростіших елементів даних, розмір яких залежить від того, яка використовується директива. Замість числового значення може бути символ; згодом його буде інтерпретовано як числовий код символу (символів). db 67h db 5dh, 0f6h db "z"; те ж саме, що і db 7ah db "w", "k", "y" dw 8a34h, 0c51h, 8bh
12 JNZ X! = Y ZF = 0 JO OF = 1 JP PF = 1 JPE PF = 1 JPO PF = 0 JS SF = 1 JZ Z = 1 Іноді має сенс використовувати команду TEST. Формат цієї команди майже такий самий, як і у команди БМР, але тільки як другий операнда не може виступати значення пам'яті. Ця команда здійснює операцію «логічного І» та змінює лише прапори SF, ZF, PF. Команда TEST корисна для перевірки відповідності значення операнда деякою бітовою маскою. Цикли Іноді одну і ту ж дію потрібно виконати кілька разів; для цього лічильник повторень можна помістити в деякий регістр і при кожному повторенні зменшувати наодиницю цього регістру. Якщо він дорівнює нулю, то повторювати дію не потрібно. mov есх, metkal: стело циклу> dec есх jnz metkal Останні два рядки - це код, який організовує цикл. Команда DEC зменшує значення регістру ЕСХ, і якщо воно дорівнюватиме нулю, то у прапор ZF буде поміщена одиниця; в результаті, якщо регістр не дорівнюватиме нулю, то відбудеться перехід на мітку. Але є простіший спосіб організації циклу. Команда LOOP приймає як єдиного операнда ближню мітку. Вона зменшує регістр ЕСХ (СХ, RCX) на одиницю і, якщо цей регістр не дорівнює нулю, відбувається передача управління мітці. Єдина перевага цієї команди полягає в тому, що вона займає менше місця. Також є дві команди організації циклів: LOOPE (LOOPZ) та LOOPNE (LOOPNZ). Команда LOOPE перед передачею управління перевіряє прапор ZF і якщо він не виставлений, то передачі управління не відбувається. Зворотну дію виконує команда LOOPNE: якщо прапор ZF виставлений, передачі управління не відбувається. На сучасних процесорах організація циклу з допомогою команд DEC/ JNZ/JZ краща з погляду продуктивності; в сумі вони будуть працювати вдвічі швидше, ніж одна інструкція LOOP. Робота з прапорами процесора Стан деяких бітів, що найчастіше використовуються, в регістрі прапорів можна змінити, використовуючи спеціально відведені для цього команди. Нижче перераховані команди, які працюють із прапорами процесора: 1. CLC - скидання прапора перенесення (CF=0). 2. CLD - скидання прапора напряму (DF=0). 3. СLI - скидання прапора роздільної здатності переривань (IF=0). 4. LAHF - збереження в регістрі АН вмісту першого байта регістра прапорів (прапори SF, ZF, AF, PF, CF)