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

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

Жанры

Ассемблер для процессоров 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-разрядный код намного упрощает механизм вызова подпрограмм, поскольку отпадает необходимость в сегментации программы и данных, а это значительно повышает производительность программ в целом.

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

Эволюционер из трущоб. Том 12

Панарин Антон
12. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Эволюционер из трущоб. Том 12

Буря империи

Сай Ярослав
6. Медорфенов
Фантастика:
аниме
фэнтези
фантастика: прочее
эпическая фантастика
5.00
рейтинг книги
Буря империи

Наследник

Шимохин Дмитрий
1. Старицкий
Приключения:
исторические приключения
5.00
рейтинг книги
Наследник

Мы – Гордые часть 8

Машуков Тимур
8. Стальные яйца
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Мы – Гордые часть 8

Звездная Кровь. Изгой VII

Елисеев Алексей Станиславович
7. Звездная Кровь. Изгой
Фантастика:
боевая фантастика
технофэнтези
рпг
фантастика: прочее
попаданцы
5.00
рейтинг книги
Звездная Кровь. Изгой VII

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

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

Эволюционер из трущоб. Том 8

Панарин Антон
8. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Эволюционер из трущоб. Том 8

Моя простая курортная жизнь 3

Блум М.
3. Моя простая курортная жизнь
Юмор:
юмористическая проза
5.00
рейтинг книги
Моя простая курортная жизнь 3

Битва за Изнанку

Билик Дмитрий Александрович
7. Бедовый
Фантастика:
городское фэнтези
мистика
5.00
рейтинг книги
Битва за Изнанку

Лекарь Империи 6

Карелин Сергей Витальевич
6. Лекарь Империи
Фантастика:
городское фэнтези
боевая фантастика
аниме
попаданцы
5.00
рейтинг книги
Лекарь Империи 6

Хозяин Стужи 2

Петров Максим Николаевич
2. Злой Лед
Фантастика:
аниме
фэнтези
попаданцы
5.75
рейтинг книги
Хозяин Стужи 2

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

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

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

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

Наследие Маозари 5

Панежин Евгений
5. Наследие Маозари
Фантастика:
фэнтези
юмористическое фэнтези
5.00
рейтинг книги
Наследие Маозари 5