| САМОУЧИТЕЛИ И УЧЕБНИКИ. БЕСПЛАТНЫЕ УЧЕБНЫЕ МАТЕРИАЛЫ.
САМОУЧИТЕЛИ И УЧЕБНИКИ

САМОУЧИТЕЛИ

УЧЕБНИКИ 

XD-3D_HD_BLC
Панель навигации
 
ГлавнаяГлавная
Личный кабинетЛичный кабинет
Самоучители и учебникиСамоучители и учебники
КонтактыКонтакты
Скачать самоучители и учебникиСкачать самоучители и учебники
Интересные статьиИнтересные статьи
РекомендоватьРекомендовать
Лента новостей
 

XD-3D_HD_BLC
Ссылки
 
 

XD-3D_HD_BLC
Наши опросы
 
Был ли полезен Вам наш сайт?

Да, весьма полезен.
Да, я нашел кое-что полезное для себя.
Нет, все это старо как мир.
Пока еще не решил.


Результаты
Другие опросы

Всего голосов: 2016
 

РЕКЛАМА

    
 
  

 

вызовы подпрограмм

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

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

 

 
 
XD-3D_HD_BLC
User Info
 


Добро пожаловать,
Guest

Регистрация или входРегистрация или вход
Потеряли пароль?Потеряли пароль?

Логин:
Пароль:
Код:Секретный код
Повторить:

Сейчас онлайн
ПользователейПользователей: 0
ГостейГостей: 17
ВсегоВсего: 17
 

XD-3D_HD_BLC
Ваша помощь
 
Мы обращаемся к тем, кому наш сайт не безразличен, к тем, кому он уже помог. Сделайте доброе дело и помогите нам в развитии нашего сайта. Просто нажмите на изображении кошелька и следуйте инструкциям.

Огромное спасибо за поддержку.

BANKSMS.RU
 

XD-3D_HD_BLC
Наши опросы
 
Купили бы Вы все самоучители и учебники сайта (2ГБ) на диске?

Да.
Да, но если цена на CD (DVD) - не более 70 руб. (100 руб.)
Я бы подумал.
Цена для меня слишком высока.
Нет.


Результаты
Другие опросы

Всего голосов: 609
Комментарии: 9
 


Design copyright by Breeze



[AD]
Генерация страницы: 0.098 сек. и 28 запросов к базе данных за 0.011 сек.
Web site engine code is Copyright © 2006 by SLAED CMS. All rights reserved.