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

на главную

Жанры

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

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

Заставь меня остановиться 2

Юнина Наталья
2. Заставь меня остановиться
Любовные романы:
современные любовные романы
6.29
рейтинг книги
Заставь меня остановиться 2

Усадьба леди Анны

Ром Полина
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Усадьба леди Анны

Мимик нового Мира 10

Северный Лис
9. Мимик!
Фантастика:
юмористическое фэнтези
альтернативная история
постапокалипсис
рпг
5.00
рейтинг книги
Мимик нового Мира 10

Кодекс Охотника. Книга IX

Винокуров Юрий
9. Кодекс Охотника
Фантастика:
боевая фантастика
городское фэнтези
попаданцы
5.00
рейтинг книги
Кодекс Охотника. Книга IX

Игрок, забравшийся на вершину. Том 8

Михалек Дмитрий Владимирович
8. Игрок, забравшийся на вершину
Фантастика:
фэнтези
рпг
5.00
рейтинг книги
Игрок, забравшийся на вершину. Том 8

Физрук: назад в СССР

Гуров Валерий Александрович
1. Физрук
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Физрук: назад в СССР

Темный Патриарх Светлого Рода 6

Лисицин Евгений
6. Темный Патриарх Светлого Рода
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Темный Патриарх Светлого Рода 6

Энфис 5

Кронос Александр
5. Эрра
Фантастика:
героическая фантастика
рпг
аниме
5.00
рейтинг книги
Энфис 5

Хочу тебя навсегда

Джокер Ольга
2. Люби меня
Любовные романы:
современные любовные романы
5.25
рейтинг книги
Хочу тебя навсегда

Я все еще не князь. Книга XV

Дрейк Сириус
15. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я все еще не князь. Книга XV

Волк 5: Лихие 90-е

Киров Никита
5. Волков
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Волк 5: Лихие 90-е

Разбуди меня

Рам Янка
7. Серьёзные мальчики в форме
Любовные романы:
современные любовные романы
остросюжетные любовные романы
5.00
рейтинг книги
Разбуди меня

Ученик

Первухин Андрей Евгеньевич
1. Ученик
Фантастика:
фэнтези
6.20
рейтинг книги
Ученик

Не грози Дубровскому! Том IX

Панарин Антон
9. РОС: Не грози Дубровскому!
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Не грози Дубровскому! Том IX