Использование стека для передачи параметров в процедуру 


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



ЗНАЕТЕ ЛИ ВЫ?

Использование стека для передачи параметров в процедуру



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

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

Ранее уже упоминалось, что для работы со стеком в процессоре предусмотрены три регистра: SS, SP и BP. Процессор автоматически работает с регистрами SS и SP в предположении, что они всегда указывают на вершину стека. По этой причине их содержимое изменять не рекомендуется.

Для произвольного доступа к данным в стеке используется регистр BP. Для корректной работы с использованием этого регистра содержимое стека должно быть правильно проинициализировано, что предполагает формирование в нём адреса, который бы непосредственно указывал на переданные данные. Для этого в начала процедуры необходимо включить дополнительный фрагмент кода – пролог процедуры. Конец процедуры также должен быть оформлен особым образом для обеспечения корректного возврата из процедуры. Фрагмент кода, выполняющий эти действия, называется эпилогом процедуры. При этом нужно откорректировать содержимое стека, убрав из него ставшие ненужными аргументы, переданные и использованные в процедуре.

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

Рассмотрим пример программы, в которой осуществляется вызов процедуры с передачей параметров в неё через стек.

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

Для доступа к последнему аргументу достаточно сместиться от содержимого BP на 4 (2 первых байта занимает адрес возврата, 2 следующих – искомое значение), к предпоследнему аргументу – на 6 и так далее (для процедур ближнего вызова).

Код эпилога процедуры восстанавливает состояние программы до момента входа в процедуру.

s_s segment stack "stack"

 dw 12 dup(?)

s_s ends

d_s segment

 aa dw 10

d_s ends

c_s segment

 assume ss:s_s,ds:d_s,cs:c_s

begin:

 mov ax,d_s

 mov ds,ax

  push aa;запись в стек аргумента

 call pr1;вызов процедуры

  pop ax;очищаем стек, забирая аргумент в регистр ax

.mov ah, 4ch

 int 21h;завершение работы программы

 

pr1 proc near

 ;начало пролога

  push bp

  mov bp, sp

 ;конец пролога

  mov ax,[ bp +4];доступ к аргументу по адресу aa для процедуры

         ;в регистре ax будет значение 10

 add ax,158h

 mov dx,ax

 ;начало эпилога

mov sp, bp;восстановление значения регистра sp

  pop bp;восстановление значения старого bp

     ;до входа в процедуру

  ret  ;возврат в вызывающую подпрограмму

 ;конец эпилога

pr1 endp

 

c_s ends

end begin

Изменение состояния стека к моменту доступа к параметрам, передаваемым в процедуру, представлено на рисунке 15. В соответствии с приведённой программой, сначала в стек помещается параметр (значение по адресу aa), затем адрес возврата (при вызове процедуры) и, наконец, содержимое регистра bp. Тогда sp указывает на вершину стека, где хранится исходное значение регистра bp. После этого содержимое регистров sp и bp становится одинаковым (mov bp, sp), и они оба указывают на вершину стека. Таким образом, параметр процедуры располагается ниже вершины стека на 4 байта, под адресом возврата и старым значением bp, каждый из которых занимает по два байта. Для доступа к ячейке стека с требуемым параметром от ячейки, на которую указывает bp, опуститься ниже на 4 байта, пропустив старое значение bp и адрес возврата, т.е. к текущему содержимому регистра bp прибавить 4 байта.

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

 
 
 
 
Стек пуст
 
bpстарое  
ipадрес_возв  
10  
 
bpстарое    
ipадрес_возв  
10
SP
push aa call pr1 push bp
SP
SS
SS
SS
SP BP
mov ax,[bp+4]
+4

Рис. 15. Изменение состояние стека к моменту доступа

к параметрам процедуры

При передаче параметров через стек по значению на их размер накладываются ограничения, связанные с размерностью стека. Кроме того, в этом случае в вызываемой процедуре обрабатываются копии параметров. Таким образом, в рассмотренном примере значение по адресу aa в сегменте данных не изменится, то есть останется равным 10 независимо от выполняемых над этим значением действий в процедуре.

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

 



Поделиться:


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

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