Все про Assembler українською мовою на сайті net.kr.ua

 

:: Меню ::

Головна
Введення
Архітектура реального режиму
Основи програмування
Команди і алгоритми
Розширені можливості сучасних мікропроцесорів
Система команд процесорів Intel
Книга для гостей
Контакти
Добавити у вибране

:: Друзі ::

  В нашей организации купить мужские кроссовки недорого по низким ценам.   По вашему желанию масло черного тмина купить на лучших условиях.   Только сейчас доставка шаров дешево всем и каждому.   С реальной скидкой Проститутки Нижневартовска на лучших условиях.
 

:: Лічильники ::

=

 

 

 

 

fff00e50

Виклики підпрограм

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

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 в даному прикладі) залежить від способу адресації. Непрямий дальній виклик, як і непрямий ближній, дозволяє використовувати різні способи адресації.

-

:: Наша кнопка ::

Отримати код:

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


:: Популярне ::

-


:: Посилання ::

-


 

 

 


Copyright © net.kr.ua, 2019-2025 (assem.us)