|
Виклики підпрограм
ADO в Delphi AJAX Android C++ CakePHP CMS COM CSS Delphi Flash Flex HTML Internet Java JavaScript MySQL PHP RIA SCORM Silverlight SQL UML XML Бази даних Веб-розробка Генетичні алгоритми ГІС Гітара Дизайн Економіка Інтелектуальні СДН Колір Масаж Математика Медицина Музика Нечітка логіка ООП Патерни Подання знань Розкрутка сайту, SEO САПР Сесії в PHP Системне програмування Системний аналіз Тестологія Тестування ПЗ Фреймворки Штучний інтелект
|
Виклики підпрограм
Практично в будь-якій програмі, незалежно від її змісту, зустрічаються ділянки, які потрібно виконувати (можливо, з невеликими змінами) кілька разів по ходу програми. Такі ділянки, що повторюються, доцільно виділити із загальної програми, оформити у вигляді підпрограм і звертатися до них кожного разу, коли в основній програмі виникає необхідність їх виконання. Підпрограма, залежно від виконуваних нею функцій, може вимагати передачі із зухвалої програми певних даних (званих аргументами, або параметрами), повертати в зухвалу програму результати обчислень або обходитися і без того, і без іншого. Підпрограма може бути оформлена у вигляді процедури, і тоді ім'я цієї процедури служитиме точкою входу в підпрограму:
drawline proc ;Подпрограмма-процедура
. . . ;Тіло підпрограми
ret ;Команда повернення в зухвалу програму
drawline endp
З таким же успіхом можна обійтися без процедури, просто помітивши перший рядок програми деякою міткою:
drawline: ;Подпрограмма, що починається з мітки
. . . ;Тіло підпрограми
ret ;Команда повернення в зухвалу програму
. . . ;Продовження основної програми або
;інші підпрограми
У будь-якому випадку виклик підпрограми здійснюється командою call. Підпрограма повинна завершуватися командою ret, службовці для повернення управління в ту крапку, звідки підпрограма була викликана. Питання використання підпрограм, передачі в них параметрів і повернення результату будуть розглянуті в наступному розділі. Тут ми зупинимося тільки на таких принципових архітектурних питаннях, як механізм виконання і можливості команд call і ret. При цьому треба мати на увазі, що синтаксичні особливості і закономірності використання команд call і jmp багато в чому збігаються, і значна частина пояснень до команд переходу справедлива і для команд виклику. Команда виклику підпрограми call може використовуватися в 4 різновидах. Виклик може бути:
Розглянемо послідовно перераховані варіанти. Прямий ближній виклик. Як і у разі прямого ближнього переходу, в команді прямого виклику в явній формі указується адреса (зсув) точки входу в підпрограму; як ця адреса можна використовувати як ім'я процедури, так і ім'я влучні, що характеризує точку входу в підпрограму. У код команди, окрім коди операції E8h, входить зсув до підпрограми, що викликається. У приведеному нижче прикладі підпрограма оформлена у вигляді процедури.
code segment
main proc ;Основная програма
.
call sub ;Код Е8 dddd
.
main endp
sub proc near ;Подпрограмма
.
ret ;Код СЗ
sub endp
code ends
Процедура-програма знаходиться в тому ж сегменті команд, що і зухвала програма. У коді команди dddd позначає зсув в сегменті команд до точки входу в підпрограму. При виконанні команди call процесор поміщає адреса повернення (вміст регістра IP) в стек виконуваної програми (рис. 2.16), після чого до поточного вмісту IP додає dddd. В результаті в IP виявляється адреса підпрограми. Команда ret, якою закінчується підпрограма, виконує зворотну процедуру - витягує із стека адресу повернення і заносить її в IP.
![]() Рис. 2.16. Участь стека в механізмі виклику ближньої підпрограми. Участь стека в механізмі виклику підпрограми і повернення з неї є вирішальною. Оскільки в стеку зберігається адреса повернення, підпрограма, сама використовуючи стек, наприклад, для зберігання проміжних результатів, зобов'язана до моменту виконання команди ret повернути стек в початковий стан. Команда ret, природно, ніяк не аналізує стан або вміст стека. Вона просто знімає із стека верхнє слово, вважаючи його за адресу повернення, і завантажує це слово в покажчик команд IP. Якщо до моменту виконання команди ret покажчик стека виявиться зміщеним в ту або іншу сторону, команда ret як і раніше розглядатиме верхнє слово стека, як адресу повернення, і передасть по ньому управління, що неминуче приведе до краху системи. Прямий дальній виклик. Цей виклик дозволяє звернутися до підпрограми з іншого сегменту. У код команди, окрім коди операції 9ah, входить повна адреса (сегмент плюс зсув) підпрограми, що викликається. Зазвичай в початковому тексті програми за допомогою описувача far ptr указується, що виклик є дальнім, хоча, якщо транслятор налаштований на трансляцію в два проходи, цей описувач не обов'язковий. Структура програмного комплексу, що містить дальній виклик підпрограми, може виглядати таким чином:
codel segment
assume Cs:codel
main proc ;Основная програма
call far ptr subr ; Код 9а dddd ssss
.
main endp
codel ends
code2 segment
assume Cs:code2
subr proc far ;Объявляем підпрограму дальньої
.
ret ;Код СВ - дальнє повернення
subr endp
code2 ends
Процедура-підпрограма знаходиться в іншому сегменті команд тієї ж програми. У коді команди dddd позначає відносну адресу точки входу в підпрограму в її сегменті команд, а ssss - це сегментна адреса. При виконанні команди call процесор поміщає в стек спочатку сегментну адресу зухвалої програми, а потім відносну адресу повернення (рис. 2.17). Далі в сегментний регістр CS заноситься 5555 (у нас це значення code2), а в IP - dddd (у нас це значення subr). Оскільки процедура-підпрограма атрибутом far оголошена дальній, команда ret має код, відмінний від коди аналогічної команди ближньої процедури і виконується по-іншому: із стека витягуються два верхні слова і переносяться в IP і CS, чим і здійснюється повернення в зухвалу програму, що знаходиться в іншому сегменті команд. У мові асемблера існує і явне мнемонічне позначення команди дальнього повернення - retf.
![]() Рис. 2.17. Участь стека в механізмі виклику дальньої підпрограми. Непрямий ближній виклик. Адреса підпрограми міститься або в елементі пам'яті, або в регістрі. Це дозволяє, як і у разі непрямого ближнього переходу, модифікувати адресу виклику, а також здійснювати виклик не за допомогою мітки, а за відомою абсолютною адресою. Структура програми з непрямим викликом підпрограми може виглядати таким чином: code segment main proc ;Основная програма . call Ds:subadr ;Код FF 16 dddd main endp subr proc near ;Подпрограмма . ret ;Код СЗ subr endp code ends data segment . subadr dw subr ;Яейка з адресою підпрограми data ends Процедура-програма з атрибутом near знаходиться в тому ж сегменті, що і зухвала програма, а її відносна адреса в осередку subadr в сегменті даних. У коді команди dddd позначає відносну адресу слова subadr в сегменті даних. Другий байт коди команди (16h в даному прикладі) залежить від способу адресації. Непрямий виклик дозволяє використовувати різноманітні способи адресації підпрограми:
call BX ; У ВХ адреса підпрограми
call[BX]; У ВХ адреса осередку з адресою підпрограми
call[BX][SI];У ВХ адреса таблиці адрес підпрограм
;у SI індекс в цій таблиці.
tbl[SI];tbl - адреса таблиці адрес підпрограм
;у SI індекс в цій таблиці
Непрямий дальній виклик. Відрізняється від непрямого ближнього виклику лише тим, що підпрограма знаходиться в іншому сегменті, а в елементі пам'яті міститься повна адреса підпрограми, що включає сегмент і зсув.
codel segment
main proc ;Основная програма
call dword ptr subadr ;Код FF IE dddd
.
main endp
codel ends
code2 segment
subr proc far ;Подпрограмма
.
ret ;Код СВ
subr endp
code2 ends
data segment
.
subadr dd subr ;Двухсловная осередок з
;адресою підпрограми
data ends
Процедура-підпрограма з атрибутом far знаходиться в іншому сегменті команд тієї ж програми, а її повна двухсловний адреса - в осередку subadr в сегменті даних. Другий байт коди команди (IE в даному прикладі) залежить від способу адресації. Непрямий дальній виклик, як і непрямий ближній, дозволяє використовувати різні способи адресації. Зверніть увагу на додаткові посиланняГоловний розділСторінки, близькі за змістомзагрузка...
|
Сторінки, близькі за змістом ![]() Асемблер (англ. assembler) — загальноприйнята назва транслятора з автокоду. Асемблер переводить початкову програму, написану на автокоді, в переміщувану програму на мові машинній. Оскільки асемблер здійснює трансляцію на мову завантажувача, при завантаженні програми необхідна налаштування умовних адрес, тобто адрес, значення яких залежать від розташування даної програми в пам'яті ЦВМ і від її зв'язків з іншими незалежно трансльованими програмами. |
|
Copyright © 2008—2026 Портал Знань.
При використанні матеріалів посилання, для інтернет-ресурсів — гіперпосилання, на Znannya.org обов'язкове.
Зв'язок
|
НТУУ "КПІ" Інженерія програмного забезпечення КПІ Лабораторія СЕТ |
|