Синтаксис команд мовою асемблера 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Синтаксис команд мовою асемблера



Програма мовою асемблера – набір речень, які можуть бути командами, макрокомандами, директивами або коментарями. Для запису речень використовуються наступні поняття:

· ім’я мітки – ідентифікатор, значенням якого є адреса першого байта того речення, яке він позначає;

· ім’я – ідентифікатор, за допомогою якого можна відрізнити дану директиву від інших;

· код операції (коп) і директива – мнемонічне позначення машинної команди, макрокоманди або директиви;

· операнди – частини команди, макрокоманди або директиви, які позначають об’єкти, над якими виконуються дії. Операнди описуються виразами з числовими і текстовими сталими, мітками і ідентифікаторами змінних з використанням знаків операцій і певних зарезервованих слів.

Припустимі символи:

1. Всі латинські букви A-Z, a-z. Великі і малі букви не розрізняються за домовленістю.

2. Цифри від 0 до 9.

3. Знаки?, @, $, _, &.

4. Розділювачі,.: [ ] () < > { } + – * / %! “ ”? \ = # ^

Речення формуються з лексем – наборів, які синтаксично нероздільні для мови допустимих символів. Лексемами є:

· Ідентифікатори – набори символів, які використовуються для позначення кодів операцій, імен змінних і міток. Ідентифікатор може складатися з одного або декількох символів. Як символ можна використовувати букви латинського алфавіту, цифри і спеціальні знаки – _,?, $, @. Ідентифікатор не може починатися символом цифри. Довжина ідентифікатора до 255 символів, хоча транслятор сприймає лише перші 32, а решту ігнорує. Можна регулювати довжину ідентифікаторів, використовуючи опцію /mvn. Можна вказати, щоб транслятор розрізняв (опція /ml), не розрізняв (опція /mu) великі і малі букви (або розрізняв великі і малі букви (опція /mx) тільки в спільних ідентифікаторах);

· ланцюжки символів – набори символів, які знаходяться між апострофами або взяті в лапки;

· цілі числа в одній із систем числення: двійковій (набір двійкових цифр, після якого вказано символ b. Наприклад, 11010001b), десятковій та шістнадцятковій, причому шістнадцяткові числа – набір шістнадцяткових цифр (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, A, b, B, c, C, d, D, e, E, f, F), який закінчується символом h. Якщо цей набір починається символами a, A, b, B, c, C, d, D, e, E, f, F, то перед цим числом потрібно писати обов’язково 0;

 

 

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

· сталі (безпосередні операнди) – число, рядок, ім’я або вираз, які мають певні фіксовані значення. Ім’я не повинно бути переміщуваним, тобто залежати від адреси завантаження програми в пам’ять. Воно може бути визначене операторами equ або =

const equ 7

ind = const – 3

mov bl, ind; еквівалентно mov bl, 4; 4 тут безпосередній операнд

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

· лічильник адреси – специфічний операнд. Позначається знаком $. Специфіка в тому, що коли транслятор зустрічає в початковій програмі цей символ, то підставляє замість нього поточне значення лічильника адреси.

· регістровий операнд – ім’я регістра (імена регістрів визначені в програмній моделі процесора).

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

· арифметичні оператори. До них відносяться унарні оператори “+” і “–”, бінарні “+”, “–”, оператори множення “*”, цілочислового ділення “/”, одержання залишку від ділення “mod”;

· індексний оператор []. Наприклад

mov dx, mas[si]; пересилка слова за адресою mas+(si) в регістр dx

· оператор перевизначення типу type ptr для перевизначення або уточнення типу мітки або змінної. Тип type може набувати значень: byte, word, dword, qword, tbyte, near, far. Наприклад:

d_wrd dd 0

mov al, byte ptr d_wrd +1; пересилка другого байта з подвійного слова

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

mov bx, fs:array;

сегментна складова змінної array обчислюватиметься відносно сегментної складової з регістра fs

· оператор одержання сегментної складової seg повертає фізичну адресу сегмента для виразу, яким може бути мітка, змінна, ім’я сегмента або деяке символьне ім’я. Синтаксис цього оператора

seg вираз

· оператор одержання зміщення виразу offset, синтаксис якого:

offset вираз

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

data segment

x dw 14

code segment

mov ax, seg x

mov es, ax

mov di, offset x; У парі регістрів es:di повна адреса x

 

 


Команди передач даних

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

Найпотужнішою серед них є команда mov (MOVe – передати, переслати). Її дія еквівалентна дії оператора присвоєння в мовах високого рівня. Має узагальнене зображення

mov dst, src; dst=(src)

Результат виконання: вміст джерела src (source) dst (destination)

mov reg, imm; завантаження довільної сталої в регістр

mov reg/mem, imm; завантаження довільної сталої в регістр або пам’ять

mov reg/mem, reg; передача з регістра в регістр або пам’ять

mov reg, reg/mem; передача з регістра або пам’яті в регістр

mov sreg, reg/mem16; завантаження сегментного регістра

mov reg/mem16, sreg; збереження сегментного регістра.

Особливості команди.

1. Тільки за допомогою команди mov (і стекових команд) можна завантажувати і зберігати сегментні регістри; тільки в команді mov з регістровою адресацією дозволяється вказувати системні регістри керування cri, налагодження dri і перевірки tri.

2. Неможливо за допомогою mov завантажувати сталу в сегментний регістр; для цього потрібно використовувати як проміжний загальний регістр (найчастіше використовується регістр ax).

3. Коли в команді вказано один з акумуляторів eax/ax/al, її довжина зменшується на 1.

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

5. Виконуючи команду mov ss, src, процесор забороняє апаратні переривання (навіть немасковані по входу nmi) на час виконання наступної команди. Вважається, що цією командою буде команда mov sp/esp, src (тобто команда завантаження регістра sp або esp для забезпечення правильної роботи стека).

Команда echg також відносить до загальних передач даних і має узагальнений формат

xchg dst, src;

та форми використання:

xchg reg, reg/mem,

xchg reg/mem, reg.

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

Команда xchg прискорює такі алгоритми сортування, в яких вимагається обмін двох елементів масиву в пам’яті. Наприклад, наступні три команди

xchg ax, data1; (data1) в ax, (ax) в data1,

xchg ax, data2; (data1) в data2, (data2) в ax,

xchg ax, data1; (data2) в data1, (ax) – початковий стан

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


Стекові передачі даних

Стек – структура даних, яка використовується для тимчасового зберігання даних і знаходиться в оперативній пам’яті в області поточного сегмента стека. Поточний сегмент стека визначається вмістом двох регістрів: сегментного регістра ss і загального регістра sp (тип сегмента use16) або esp (тип сегмента use32). Вміст регістра ss визначає розміщення в оперативній пам’яті початку сегмента, а вміст sp або esp (надалі писатимемо sp/esp), визначає адресу розміщення вершини стека відносно його початку (останнього елемента записаного в стек). Усі стекові операції автоматично модифікують вміст sp/esp, тобто вершина стека є рухомою.

Операція запису в стек ініціюється командою push src, алгоритм виконання якої можна описати так:

if StackAddrSize=16 * / якщо use16 / * Then */то використати /* sp else esp

if OperandSize=16 * / якщо use16 / * Then

sp/esp=(sp/esp) – 2;

Передати слово (src) у вершину стека ss:[sp/esp];

Else * / OperandSize=32 / *

sp/esp=(sp/esp) – 4;

Передати подвійне слово (src) у вершину стека ss:[sp/esp].

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

Як джерело, тобто src, можна використовувати: сегментний регістр sreg, загальний регістр reg16/32, комірку оперативної пам’яті mem16/32, безпосередню сталу imm16/32.

Три особливості використання команди push src:

1. У процесорі 8086 в стек командою push src записується змінений (sp) зменшений на 2, а в процесорах 80286, 80386 та i486 – (sp/esp) до декремента.

2. Доцільно розширювати 16-бітовий операнд до 32-бітового і записувати його в стек як подвійне слово, інакше може виникнути порушення вирівнювання пам’яті стека на межу подвійного слова.

3. Якщо не вистачає пам’яті для записування в стек, то процесори 80386 та i486 автоматично переходять у стан вимикання (shutdown).

Команда pusha – запису в стек восьми 16-бітових загальних регістрів у порядку: ax, cx, dx, bx, sp, bp, si, di. Для регістра sp в стек записується те значення, яке було до виконання команди pusha. Команда pushad – запису в стек восьми 32-бітових загальних регістрів у порядку: eax, ecx, edx, ebx, esp, ebp, esi, edi. Для регістра esp в стек записується те значення, яке було до виконання команди pushad. Зрозуміло, що одна команда pusha/pushad замінює вісім команд push.

Операція вибору (виштовхування) зі стека ініціюється командою

pop dst, алгоритм виконання якої можна описати так:

if StackAddrSize=16 * / якщо use16 / * Then */то використати /* sp else esp

if OperandSize=16 * / якщо use16 / * Then */то використати /* sp else esp

Передати слово з вершини стека ss:[sp/esp] в dst;

sp/esp=(sp/esp) + 2;

Else * / OperandSize=32 / *

Передати подвійне слово з вершини стека ss:[sp/esp] в dst;

sp/esp=(sp/esp) + 4.

Як dst можна використовувати: сегментний регістр sreg, загальний регістр reg16/32, комірку оперативної пам’яті mem16/32.

На час виконання наступної команди після команди pop ss процесор забороняє апаратні переривання з розрахунком на те, що вона завантажуватиме регістр sp/esp для правильної адресації стека.

Команда вибору зі стека pop sreg ініціює читання у відповідний тіньовий регістр дескриптора з таблиці GDT, який відповідає значенню селектора – вмісту сегментного регістра в sreg. Тому збільшується час виконання команди, можуть виникнути особливі випадки, а також вибір слів зі стека може порушити вирівнювання пам’яті на межу подвійного слова.

Команда popa/popad є двоїстою до команди pusha/pushad відповідно і виштовхує зі стека значення восьми загальних регістрів у зворотному порядку, в якому записувала їхній вміст pusha/pushad. Значення регістра sp/esp при цьому ігнорується.



Поделиться:


Последнее изменение этой страницы: 2017-01-27; просмотров: 290; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.133.119.66 (0.021 с.)