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

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

Жанры

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

Магда Юрий

Шрифт:

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

Директива proc может принимать один из двух параметров: near или far. Параметр near указывает на то, что процедура является ближней, a far указывает на то, что процедура дальняя. Если параметр отсутствует, то считается, что процедура имеет тип near (поэтому параметр near обычно и не указывается).

К ближней (near) процедуре можно обращаться только из того сегмента команд, где она объявлена, а к дальней (far) процедуре – из любых сегментов команд, включая тот, где она объявлена. Для 32-разрядных приложений все вызовы процедур считаются ближними.

Следует отметить, что в языке ассемблера имена и метки, описанные в процедуре, должны быть уникальными и не должны совпадать с другими именами в программе. В языке ассемблера имеется возможность создавать вложенные процедуры, то есть процедуры внутри процедур, но особых преимуществ это не дает и используется относительно редко.

Можно обойтись и без явного определения процедуры, пометив первую строку программы некоторой меткой, как проиллюстрировано в следующем фрагменте программного кода:



В этом случае отсутствуют директивы ргос и endp и говорят, что подпрограмма (процедура) определяется неявно. Подобные записи процедур используются редко, поскольку значительно затрудняют анализ исходных текстов и отладку программ. Мы не будем применять такое определение процедур, а воспользуемся директивами ргос и endp, как было сказано в начале главы. Вызов процедуры выполняется с помощью команды call, которая передает управление процедуре, сохранив в стеке адрес возврата в вызывающую программу. Процедура должна завершаться командой ret, которая извлекает из стека адрес возврата и возвращает управление команде, следующей за командой call.

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

В момент вызова процедуры команда call помещает в стек адрес команды, следующей непосредственно за call, уменьшая значение указателя стека SP (ESP). Команда ret вызываемой процедуры использует этот адрес для возврата в вызывающую программу, автоматически увеличивая при этом указатель вершины стека.

Типы адресации (near или far) команд ret и call должны соответствовать друг другу. Вызываемая процедура может вызвать с помощью команды call следующую процедуру и т. д., поэтому стек должен иметь достаточный размер для того, чтобы хранить в нем все записываемые данные.

Следует сказать, что команда ret не анализирует состояние или содержимое стека. Она извлекает из вершины стека слово или двойное слово, в зависимости от типа адресации, полагая, что это адрес возврата, по которому передается управление. Если к моменту выполнения команды ret указатель стека окажется смещенным в ту или иную сторону, содержимое вершины стека может представлять все что угодно, поэтому передача управления по этому адресу приведет к краху программы.

Команда call может иметь один из перечисленных ниже форматов вызова:

– прямой ближний (в пределах текущего программного сегмента);

– прямой дальний (вызов процедуры, расположенной в другом программном сегменте);

– косвенный ближний (в пределах текущего программного сегмента с использованием переменной, содержащей адрес перехода);

– косвенный дальний (вызов процедуры, расположенной в другом программном сегменте, с использованием переменной, содержащей адрес перехода).

Тип адресации при вызове процедуры зависит от используемой модели памяти. Директива .model автоматически устанавливает атрибут near или far для вызываемых процедур, при этом модели tiny, smal1 и compact устанавливают атрибут near, а модели medium, large и huge – атрибут far. Ассемблер генерирует far-вызовы для моделей medium, large и huge автоматически. Для 32-разрядных приложений, использующих модель fIat, все вызовы процедур считаются ближними (near).

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

Требуемая для вычисления этого адреса величина смещения от точки возврата до точки перехода содержится в коде самой команды, занимающем 3 байта (код операции E8h плюс смещение к точке перехода).

Команда call прямого дальнего вызова помещает в стек два слова: вначале сегментный адрес текущего программного сегмента, затем относительный адрес точки возврата в этом программном сегменте. После этого выполняется модификация регистров EIP и CS: в EIP помещается относительный адрес точки перехода в том сегменте, куда осуществляется переход, а в CS – селектор адреса для этого сегмента.

Оба эти значения извлекаются из кода команды, занимающего 5 байт (код операции 9Ah, эффективный адрес вызываемой процедуры и селектор сегмента). Для указания прямого дальнего вызова используется директива far ptr, которая говорит компилятору и компоновщику, что вызов является дальним.

В листинге 6.3 показан фрагмент программного кода, демонстрирующий дальний вызов процедуры.


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



Процедуры subr1 и subr2 находятся в другом сегменте команд той же программы и при вызове выводят на экран строки s1 и s2. При выполнении команды call процессор помещает в стек сначала сегментный адрес вызывающей программы, а затем относительный адрес возврата, как показано на рис. 6.7.



Рис. 6.7. Содержимое стека после вызова дальней процедуры


Поскольку процедура объявлена дальней (атрибут far), то команда ret имеет код OCBh, отличный от кода аналогичной команды для вызова ближней процедуры (0C3h), и выполняется по-другому: из вершины стека извлекаются два слова и помещаются в регистры EIP и CS, передавая тем самым управление вызывающей программе из другого сегмента команд. Для команды возврата из дальней процедуры существует специальное мнемоническое обозначение retf.

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

Камень. Книга восьмая

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

Фишер. По следу зверя. Настоящая история серийного убийцы

Рогоза Александр
Реальные истории
Документальная литература:
истории из жизни
биографии и мемуары
5.00
рейтинг книги
Фишер. По следу зверя. Настоящая история серийного убийцы

Корабль дураков

Портер Кэтрин Энн
Проза:
современная проза
4.00
рейтинг книги
Корабль дураков

Газлайтер. Том 25

Володин Григорий Григорьевич
25. История Телепата
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Газлайтер. Том 25

Неудержимый. Книга XXVII

Боярский Андрей
27. Неудержимый
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Неудержимый. Книга XXVII

Моров. Том 5

Кощеев Владимир
4. Моров
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Моров. Том 5

Изгой Проклятого Клана. Том 5

Пламенев Владимир
5. Изгой
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Изгой Проклятого Клана. Том 5

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

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

Дворянин

Злотников Роман Валерьевич
2. Император и трубочист
Фантастика:
боевая фантастика
альтернативная история
5.00
рейтинг книги
Дворянин

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

Винокуров Юрий
25. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
6.25
рейтинг книги
Кодекс Охотника. Книга XXV

Царь царей

Билик Дмитрий Александрович
9. Бедовый
Фантастика:
фэнтези
мистика
5.00
рейтинг книги
Царь царей

Неудержимый. Книга XXXVII

Боярский Андрей
37. Неудержимый
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Неудержимый. Книга XXXVII

Петля, Кадетский корпус. Книга третья

Алексеев Евгений Артемович
3. Петля
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Петля, Кадетский корпус. Книга третья

Законы Рода. Том 7

Мельник Андрей
7. Граф Берестьев
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Законы Рода. Том 7