Чтение онлайн

на главную - закладки

Жанры

Ассемблер для процессоров Intel Pentium

Магда Юрий

Шрифт:

Рассмотрим косвенный ближний вызов. В этом случае адрес процедуры содержится либо в ячейке памяти, либо в регистре. Это позволяет, как и в случае косвенного ближнего перехода, модифицировать адрес вызова, а также осуществлять вызов без использования метки по известному абсолютному адресу. Следующее 16-разрядное приложение иллюстрирует механизм косвенного вызова процедуры (листинг 6.4).


Листинг 6.4. Демонстрация косвенного вызова процедуры (16-разрядная версия)



Процедуры subr1 и subr2 с атрибутом near находятся в том же сегменте, что и вызывающая программа, а их относительные адреса – в переменных addrl и addr2 в сегменте данных. Процедуры при вызове выводят соответствующие сообщения (строки s1 и s2) на экран.

Косвенный ближний вызов позволяет использовать разнообразные способы адресации процедур:



В листинге 6.5 приведен исходный текст 16-разрядного приложения, демонстрирующий один из вариантов реализации косвенного ближнего вызова. Здесь для вычисления смещения (эффективного адреса) процедуры используются регистры s1 и ВХ, причем в регистре s1 содержится адрес таблицы tbl смещений подпрограмм, а регистр ВХ содержит индекс.

Листинг 6.5. Демонстрация косвенного ближнего вызова (16-разрядная версия)



Исходный текст программы несложен, хочу лишь обратить внимание на инструкцию

add BX, 2

Эта инструкция находится в цикле



Поскольку таблица tbl содержит смещения процедур в виде слов, то для перехода к следующему элементу таблицы содержимое ВХ увеличивается на 2. Результатом выполнения подпрограммы будет вывод на экран строк:



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

 

Пример косвенного дальнего вызова приведен в листинге 6.6. Это 16-разрядное приложение, в основу которого положен исходный текст предыдущего примера.

Листинг 6.6. Демонстрация косвенного дальнего вызова (16-разрядная версия)



Листинг 6.6 (продолжение)



Программа довольно сложная, поэтому остановимся на ней подробно.

Анализ процедуры начнем со структуры таблицы tbl. Эта таблица содержит дальние адреса трех процедур (subr1, subr2 и subr3), находящихся в трех разных сегментах кода (codel, code2 и code3). Каждый элемент таблицы представляет собой двойное слово. Младшее слово двухсловного элемента содержит смещение (эффективный адрес) процедуры, старшее – адрес сегмента программного кода, в котором данная процедура находится. Таким образом, в таблице tbl зарезервировано 12 байт памяти для адресов трех процедур.

Программа заполняет 4-байтовые ячейки памяти необходимой информацией так, как это делается, например, для процедуры subr2:



После заполнения таблицы нужной информацией основная программа (находящаяся в программном сегменте codeO) в цикле next, состоящем из трех итераций, выполняет дальние косвенные вызовы каждой из процедур:



Результатом работы программы является вывод следующих трех строк на экран:



Прежде чем закончить тему адресации процедур, хочу сделать некоторые замечания. Если вы работаете с 32-разрядными приложениями (используется директива .model flat), то понятия «дальний вызов» не существует. Приложение выполняется в едином линейном адресном пространстве размером вплоть до 4 Гбайт, где данные и код перемешаны, а сегментные регистры установлены в одно и то же значение. Все вызовы и команды переходов считаются ближними (атрибут near ptr). Для таких вызовов можно применять те же режимы, что и для ближних вызовов в 16-разрядных моделях памяти (прямой ближний и косвенный ближний), но использовать при этом 32-разрядные переменные и регистры.

Для иллюстрации вышеизложенного приведу фрагмент 32-разрядной программы, вычисляющей сумму и разность двух целых чисел с использованием двух процедур. Исходный текст программного кода показан в листинге 6.7.

Программный код включает в себя вызывающую процедуру _far_demo32 и вызываемые процедуры subi и sub2. Процедура subi вычисляет сумму чисел i1 и 12, помещая результат в младшее двойное слово переменной res. Процедура sub2 вычисляет разность тех же чисел и помещает результат в старшее двойное слово переменной res. Процедура _far_demo32 вызывает процедуры по адресу, находящемуся в регистре ESI. Регистр ESI получает его из таблицы tbl, содержащей соответствующие адреса в двухсловных переменных.


Листинг 6.7. Демонстрация косвенного ближнего вызова (32-разрядная версия)



Процедура _far_demo32 возвращает в программу адрес переменной res, содержащей два двойных слова с результатами сложения и вычитания. Как видно из листинга, 32-разрядный код намного упрощает механизм вызова подпрограмм, поскольку отпадает необходимость в сегментации программы и данных, а это значительно повышает производительность программ в целом.

Поделиться:
Популярные книги

Камень

Минин Станислав
1. Камень
Фантастика:
боевая фантастика
6.80
рейтинг книги
Камень

Слезы Эйдена 1

Владимиров Денис
11. Глэрд
Фантастика:
боевая фантастика
фэнтези
попаданцы
5.00
рейтинг книги
Слезы Эйдена 1

Рассвет русского царства 3

Грехов Тимофей
3. Новая Русь
Фантастика:
историческое фэнтези
альтернативная история
5.00
рейтинг книги
Рассвет русского царства 3

Гримуар темного лорда VI

Грехов Тимофей
6. Гримуар темного лорда
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Гримуар темного лорда VI

На границе империй. Том 10. Часть 4

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 4

Точка Бифуркации

Смит Дейлор
1. ТБ
Фантастика:
боевая фантастика
7.33
рейтинг книги
Точка Бифуркации

Печать мастера

Лисина Александра
6. Гибрид
Фантастика:
попаданцы
технофэнтези
аниме
фэнтези
6.00
рейтинг книги
Печать мастера

Старый, но крепкий 2

Крынов Макс
2. Культивация без насилия
Фантастика:
рпг
уся
эпическая фантастика
5.00
рейтинг книги
Старый, но крепкий 2

Князь Андер Арес 5

Грехов Тимофей
5. Андер Арес
Фантастика:
историческое фэнтези
фэнтези
героическая фантастика
5.00
рейтинг книги
Князь Андер Арес 5

Вперед в прошлое 10

Ратманов Денис
10. Вперед в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 10

Я уже барон

Дрейк Сириус
2. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я уже барон

Рассвет русского царства

Грехов Тимофей
1. Новая Русь
Документальная литература:
историческая литература
5.00
рейтинг книги
Рассвет русского царства

Ермак. Регент

Валериев Игорь
10. Ермак
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Ермак. Регент

Око василиска

Кас Маркус
2. Артефактор
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Око василиска