Организация интерфейса с процедурой 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Организация интерфейса с процедурой



Аргумент — это ссылка на некоторые данные, которые требуются для выполнения возложенных на модуль функций и размещенных вне этого модуля. По аналогии с макрокомандами рассматривают понятия формального и фактического аргументов. Исходя из этого, формальный аргумент можно рассматривать не как непосредственные данные или их адрес, а как «местодержатель» для действительных данных, которые будут подставлены в него с помощью фактического аргумента. Формальный аргумент можно рассматривать как элемент интерфейса модуля, а фактический аргумент — это то, что фактически передается на место формального аргумента.

Переменные — это данные размещенные в регистре или ячейке памяти, которые могут в дальнейшем подвергаться изменению.

Константы — данные, значения которых не могут изменяться.

Сигнатура процедуры (функции) — это имя функции, тип возвращаемого значения и список аргументов с указанием порядка их следования и типов.

Семантика процедуры (функции) — это описание того, что данная функция делает. Семантика функции включает в себя описание того, что является результатом вычисления функции, как и от чего этот результат зависит. Обычно результат выполнения зависит только от значений аргументов функции, но в некоторых модулях есть понятие состояния. Тогда результат функции может зависеть от этого состояния, и, кроме того, результатом может стать изменение состояния. Логика этих зависимостей и изменений относится к семантике функции. Полным описанием семантики функций является исполняемый код функции или математическое определение функции.

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

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

· через регистры;

· через общую область памяти;

· через стек;

· с помощью директив extrn и public.

Передача аргументов через регистры – это наиболее простой в реализации способ передачи данных. Данные, переданные подобным способом, становятся доступными немедленно после передачи управления процедуре. Этот способ очень популярен при небольшом объеме передаваемых данных.

Ограничения на способ передачи аргументов через регистры:

· небольшое число доступных для пользователя регистров;

· нужно постоянно помнить о том, какая информация в каком регистре находится;

· ограничение размера передаваемых данных размерами регистра. Если размер данных превышает 8, 16 или 32 бита, то передачу данных посредством регистров произвести нельзя. В этом случае передавать нужно не сами данные, а указатели на них.

Передача аргументов через общую область памяти – предполагает, что вызывающая и вызываемая программы используют некоторую область памяти как общую. Для организации такой области памяти используется атрибут комбинирования сегментов. Наличие этого атрибута указывает компоновщику LINK, как нужно комбинировать сегменты, имеющие одно имя. Значение common означает, что все сегменты, имеющие одинаковое имя в объединяемых модулях, будут располагаться компоновщиком, начиная с одного адреса оперативной памяти. Это значит, что они будут просто перекрываться в памяти и, следовательно, совместно использовать выделенную память. Данные в сегментах common могут иметь одинаковые имена. Главное – структура общих сегментов. Она должна быть идентична во всех модулях использующих обмен данными через общую память.

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

Передача аргументов через стек

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

Стек обслуживается тремя регистрами: ESS, ESP и EBP. Микропроцессор автоматически работает с регистрами ESS и ESP в предположении, что они всегда указывают на дно и вершину стека соответственно. По этой причине их содержимое изменять не рекомендуется. Для осуществления произвольного доступа к данным в стеке архитектура микропроцессора имеет специальный регистр EBP (Base Point — указатель базы). Так же, как и для регистра ESP, использование EBP автоматически предполагает работу с сегментом стека. Перед использованием этого регистра для доступа к данным стека его содержимое необходимо правильно инициализировать, что предполагает формирование в нем адреса, который бы указывал непосредственно на переданные данные. Для этого в начало процедуры рекомендуется включить дополнительный фрагмент кода. Он имеет свое название — пролог процедуры. Код пролога состоит всего из двух команд. Первая команда push ebp сохраняет содержимое ebр в стеке с тем, чтобы исключить порчу находящегося в нем значения в вызываемой процедуре. Вторая команда пролога mov ebp,esp настраивает ebp на вершину стека. После этого мы можем не волноваться о том, что содержимое esp перестанет быть актуальным, и осуществлять прямой доступ к содержимому стека.

Конец процедуры также должен содержать действия, обеспечивающие корректный возврат из процедуры. Фрагмент кода, выполняющего такие действия, имеет свое название — эпилог процедуры. Код эпилога должен восстановить контекст программы в точке вызова процедуры из вызывающей программы. При этом, в частности, нужно откорректировать содержимое стека, убрав из него ставшие ненужными аргументы, передававшиеся в процедуру. Это можно сделать несколькими способами:

· используя последовательность из n команд pop xx. Лучше всего это делать в вызывающей программе сразу после возврата управления из процедуры;

· откорректировать регистр указателя стека esp на величину 4*n, например, командой add esp,NN, где NN=4*n (n — количество аргументов). Это также лучше делать после возврата управления вызывающей процедуре;

· используя машинную команду ret n в качестве последней исполняемой команды в процедуре, где n — количество байт, на которое нужно увеличить содержимое регистра esp после того, как со стека будут сняты составляющие адреса возврата. Этот способ аналогичен предыдущему, но выполняется автоматически микропроцессором.

Программа, содержащая вызов процедуры с передачей аргументов через стек:

.586

.model flat, stdcall

.stack 4096

.data

.code

proc_1 proc; начало процедуры

push ebp     ; пролог: сохранение EBP

mov ebp, esp ; пролог: инициализация EBP

mov eax, [ebp+8]; доступ к аргументу 4

mov ebx, [ebp+12]; доступ к аргументу 3

mov ecx, [ebp+16]; доступ к аргументу 2

pop ebp      ; эпилог: восстановление EBP

ret 12

proc_1 endp

main proc

push 2

push 3

push 4

call proc_1

ret

main endp

end main

Для доступа к аргументу «4» достаточно сместиться от содержимого ebр на 8 (4 байта хранят адрес возврата в вызывающую процедуру, и еще 4 байта хранят значение регистра ebр, помещенное в стек данной процедурой), для аргумента «3» — на 12 и т. д.

Пролог и эпилог прогцедуры можно также заменить командами поддержки языков высокого уровня:

· Команда enter подготавливает стек для обращения к аргументов, имеет 2 операнда:

1 – определяет количество байт в стеке, используемых для хранения локальных идентификаторов процедуры;

2 – определяет уровень вложенности процедуры.

· Команда leave подготавливает стек к возврату из процедуры, не имеет операндов.

proc_1 proc                

enter 0,0              

mov eax, [ebp+8]           

mov ebx, [ebp+12]

mov ecx, [ebp+16] 

leave

ret 12       

proc_1 endp

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

Наиболее простой способ передачи аргументов в процедуру — передача по значению. Этот способ предполагает, что передаются сами данные, то есть их значения. Вызываемая программа получает значение аргумента через регистр или через стек. При передаче переменных через регистр или стек на их размерность накладываются ограничения, связанные с размерностью используемых регистров или стека. При передаче аргументов по значению в вызываемой процедуре обрабатываются их копии. Поэтому значения переменных в вызывающей процедуре не изменяются.

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

Передача аргументов с помощью директив extern и public используется в случаях, если

· оба модуля используют сегмент(секцию) данных вызывающей программы;

· у каждого модуля есть свой собственный сегмент(секция) данных;

· модули используют атрибут комбинирования (объединения) сегментов public в директиве сегментации segment.

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

 



Поделиться:


Последнее изменение этой страницы: 2020-12-09; просмотров: 133; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.118.226.105 (0.012 с.)