Пример передачи параметров через стек

Пусть процедура заполняет нулями массив A[0..n-1] , основная программа обращается к ней для обнуления массивов X[0..99] и Y[0..49]. Через стек в ПП передается имя массива и его размер, размер можно передавать по значению, а имя массива нужно передавать по ссылке, т.к. этот параметр является и входным и выходным.

zero_1 proc

push BP ; входные

mov BP, SP ; действия

push BX ; сохранение значений

push CX ; регистров

mov CX, [BP + 4] ; CX = n считывание из стека

mov BX, [BP + 6] ; BX = A параметров

m1: mov byte ptr [BX], 0 ; цикл обнуления

inc BX ; массива

loop m1 ; A[0..n-1]

; восстановление регистров и выходные действия

pop CX

pop BX

pop BP

Ret 4

zero_1 endp

Фрагмент основной программы:

X DB 100 dup (?)

Y DB 50 dup (?)

------------------------

lea AX, X ; загрузка параметров:

push AX ; адреса массива X

mov AX, 100 ; и его размера

push AX ; в стек

call zero_1 ; обращение к ПП

lea AX, Y ; загрузка параметров для массива Y

puah AX ;

mov AX, 50 ;

push AX ;

call zero_1 ; обращение к ПП

---------------------------

Использование локальных параметров.

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

Лучший способ – разместить локальные параметры в стеке на время работы ПП, а перед выходом из ПП их удалить. Для этого после входных действий в процедуре нужно уменьшить значение указателя на вершину стека SP на количество байтов, необходимых для хранения локальных величин и затем записывать их в стек и извлекать их можно с помощью выражений вида: [BP – n], где n определяет смещение локального параметра относительно значения BP, а к фактическим параметрам – [BP + k], где k определяет положение фактического параметра.

Пример передачи параметров через стек - student2.ru Например, если предполагается, что ПП будет использовать 3 локальные параметра размером в слово, то стек графически можно представить так: SP Lz

BP - 4 Ly

BP - 2 Lx

BP BPct

BP + 2 av

BP + 4 ak

-------

a1

---------

SS

При выходе из процедуры перед выполнением завершающих действий нужно возвратить регистру SP его значение.

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

PP proc

push BP ; сохранить старое значение BP

mov BP, SP ; (SP) в BP

sub SP, k1 ; отвести в стеке k1 байтов под лок пар - ы

push AX ; сохранить в стеке регистры,

-------------- ; используемые в ПП

<тело процедуры>

------------- ; восстановить регистры

pop AX ;

mov SP, BP ; восстановить SP, т.е. освободить место

pop BP ; в стеке от локальных параметров восстановить BP ret k2 ;очистка стека от фактических параметров и возврат в вызывающую программу

PP endp ; конец ПП

Подсчет количества различных символов в заданной строке.

Строка задана как массив символов. Начальный адрес ее передадим в ПП через регистр BX, длину строки через CX, а результат - через AX. Создадим процедуру, в которой выделяется 256 – ый локальный массив L по количеству возможных символов. K-ому элементу этого массива будем присваивать единицу, если символ, цифровой код которого равен K, в заданной строке существует. Затем подсчитаем количество единиц в этом массиве. Вначале весь массив обнуляется. К первому элементу этого массива можно обратиться так: L1 = [BP – 256]к K – омуLk = [BP – 256 + k].Работая со строками, эту задачу можно решить проще.

Count_s proc ;

; входные действия

Push BP

Mov BP, SP

Sub SP, 256

Push BX

Push CX

Push SI

; Обнуление локального массива

mov AX, CX ; сохранение длины исходной строки

mov CX, 256 ; возможное количество символов

mov SI, 0 ; индекс элемента массива

m1: mov byte ptr [BP – 256 + SI], 0 ;

inc SI

loop m1

; просмотр заданной строки и запись 1 в локальный массив

mov CX, AX ; длину строки в CX

mov AX, 0

m2: mov AL, [BX] ; код очередного символа в AL

mov SI, AX ; пересылаем его в SI

mov byte ptr [BP – 256 + SI], 1 ; пересылаем 1 в к –й элемент массива

inc BX

loop m2 ;

; подсчет количества 1 в локальном массиве

mov AX, 0 ; результат будет в AX

mov CX, 256 ; количество повторений цикла

mov SI, 0 ; индекс массива в SI

m3: cmp byte ptr [BP – 256 + SI], 1

jne m4

inc AX

m4: inc SI

loop m3

; выходные действия

pop SI ; восстановление

pop CX ; регистров

pop BX ;

mov SP, BP ; освобождение стека от локальных параметров

pop BP ; восстановить старое BP

ret

const_s endp

15) Команды пересылки безусловной и условной, команды загрузки адреса

К командам пересылки относят команду обмена значений операндов.

XCHG OP1, OP2; r«r Ú r«m

MOV AX, 10h;

MOV BX, 20h;

XCHG AX, BX; (AX) = 20h, (BX) = 10h

Для перестановки значений байтов внутри регистра используют BSWOP.

(EAX) = 12345678h

BSWOP EAX; (EAX) = 78563412h

Команды конвертирования:

CBW ; безадресная команда, (AL) ® AX. Конвертирует байт в слово

CWD ;( AX) ® DX:AX, конвертирует слово в двойное слово

CWE ; ( AX) ® EAX (для i386 и выше) из 16 в 32 разряда

CDF ; (EAX) ® EDX:EAX (для i386 и выше) из 32 в 64 разряда

Наши рекомендации