- •Лабораторна робота №4-1 Організація взаємозв'язку програм мовою Асемблера з програмами мовою Паскаль
- •Перше заняття
- •Друге заняття
- •Лабораторна робота №4-2
- •1) Оголошення зовнішніх асемблерних процедур
- •2) Опис глобальних змінних
- •1) Директива завдання набору допустимих команд процесора
- •2) Директива public
- •3) Модель пам’яті
- •6) Локальні параметри
- •7) Повернення значень з асемблерної процедури
- •8) Організація повернення з підпрограми
- •9) Поле операндів директиви end
- •1) Створення проекту
- •2) Створення *.Asm файлу
- •3) Налагодження програми
- •Перше заняття
- •Друге заняття
- •Варіанти завдань
- •Додаткові експерименти
6) Локальні параметри
У процедурах мовою Асемблера можна використовувати локальні параметри, що існують лише під час виконання процедури. Вони описуються за допомогою ключового слова local з асемблерними типами (byte, word, dword):
local ідентифікатор:тип, …, ідентифікатор:тип
Простір для локальних параметрів також виділяється у стеку шляхом зменшення ESP на загальний розмір цих параметрів. Таким чином, враховуючи встановлений перед цим вміст EBP, локальні параметри зберігатимуться за адресами вигляду [EBP-зміщення] (рис. ) (загальна кількість зайнятих кожним з них байтів округлюється до більшого кратного 4 значення).
-
Більша адреса пам'яті (початкове значення ESP)
Останній параметр
---
Перший параметр
EBP + зміщення
Адреса повернення
Попередній вміст EBP
EBP + 0
Перший локальний параметр
EBP – зміщення
---
Менша адреса пам'яті (значення ESP після виклику підпрограми)
Останній локальний параметр
Рис. Стан стеку за умови локальних параметрів.
Наприклад:
local TmpAddr:dword, number:word, symbol:byte
Адреси цих параметрів у стеку становлять відповідно:
TmpAddr – [EBP-4]
number – [EBP-6]
symbol – [EBP-7]
Ці локальні параметри займатимуть 8 байтів у стеку (7 округлюється до 8).
Потрібно пам’ятати, що значення локальних параметрів у стеку поки що не визначені, тому підпрограма має їх ініціалізувати. Перед виходом з підпрограми стек потрібно вивільнити від них, збільшивши відповідним чином покажчик стеку ESP.
7) Повернення значень з асемблерної процедури
Отримане значення функції перед поверненням із асемблерної процедури необхідно розмістити:
В регістрі AL, якщо на тип даних у C++ відводиться один байт;
В регістрі AХ, якщо на тип даних у C++ відводиться одне слово;
В регістрі EAХ, якщо на тип даних у C++ відводиться одне подвійне слово.
Результат булевої функції зберігається у регістрі AL.
8) Організація повернення з підпрограми
Збережений на початку асемблерної процедури вміст регістра EBP має відновлюватися по закінченню її роботи. У відповідності до конвенції С, обов'язки щодо забезпечення початкового значення ЕSP покладаються на С/C++ програму. Тому підпрограма повинна закінчуватись командами:
pop ebp
ret
9) Поле операндів директиви end
Програма мовою Асемблера не повинна бути основною, а це означає, що поле операндів директиви END повинно бути порожнім.
10) Виклик C++ функції з асемблерної програми
Для виклику в асемблерній програмі функцій C++ програми потрібно ідентифікатори функцій описати в асемблерній програмі за допомогою директиви PROTO (та вказівкою асемблерних типів) наступним чином:
Ім’я PROTO параметр:тип, …, параметр:тип
Слід зауважити, що в C++ програмі прототипи таких функцій повинні бути описані у тілі extern "C".
Для виклику функції також може використовуватися макровизначення invoke. Воно полегшує виклик функції й автоматично передає параметри та очищує стек після закінчення роботи функції.
Наприклад, викликаємо функцію, якій в якості параметрів передаємо вміст регістрів eax та dx. Тобто функція має 2 параметри розміром відповідно 2 та 4 байти:
oddfunc PROTO first:WORD, second:DWORD
Виклик функції
invoke oddfunc, dx, eax
відповідає наступним командам:
push eax
push dx
call oddfunc
add esp,6 ; dx та eax займали 6 байтів
4-2.2.4 Налаштування середовища Visual Studio для роботи з модулем мовою Асемблера
