КОМАНДЫ CALL И RET


При вызове процеду­ры необходимо удовлетворить следующие три требования:

— в отличие от команд переходов команда вызова проце­дуры должна запомнить адрес возврата (адрес следующей команды после команды вызова процедуры CALL) так, чтобы можно было осуществить возврат в нужное место вызываю­щей программы по команде RET;

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

— используемые процедурой регистры процессора необхо­димо запоминать (сохранять) до изменения их содержимого, а перед выходом из процедуры — восстанавливать.

Первое из приведенных требований удовлетворяется ис­пользованием стека для сохранения адреса возврата. Команда CALL не только осуществляет переход по адресу процедуры, но и включает в стек адрес возврата (рис. 4.2). Команда RET извлекает сохраненный командой CALL адрес возврата из стека и делает его новым текущим адресом команды (изменя­ет логический адрес в регистрах CS:IP). Предполагается, что если процедура обращалась к стеку, указатель стека возвра­щается в правильное положение перед выполнением команды возврата. Очевидно, при работе с процедурами необходимо внимательно следить за стеком. В противном случае возмож­ны возвраты к бессмысленным — командам, если во время воз­врата указатель стека SS:SP будет указывать не на сохранен­ные командой CALL значения CS:IP.

Программа Стек

Процедура PROC

Процедура PROC

а)SS:SP (во

clip_image002время вызова)

clip_image003СS:IP

clip_image004clip_image005б)SS:SP (до и

после вызова)

clip_image004[1]
Рис. 4.2. Сохранение адреса возврата из процедуры в стеке

Режимы адресации, которые кодируются в команде

CALL, такие же, что и для команд безусловного перехода JftViP (см. п. 3.2.2). Вызов может быть прямым или косвенным, внутрисегментным или межсегментным. Внутрисегментный вызов процедуры сохраняет в стеке только часть логическо­го адреса возврата, а именно, смещение следующей команды в текущем сегменте кода. Межсегментный вызов процедуры сохраняет в стеке полный логический адрес возврата. Если команда CALL является внутрисегментным (межсегментным) вызовом, то и команда RET (рис.4.3) должна быть внутрисег­ментным (межсегментным) возвратом. Это объясняется тем, что внутрисегментный вызов включает1 в стек только содер­жимое регистра IP, т.е. смещение в текущем сегменте кода следующей команды после команды вызова процедуры, а меж­сегментный вызов должен включить в стек как содержимое IP, так и содержимое CS (рис. 4.2). Соответственно возврат должен извлечь из стека одно или два слова.

clip_image006clip_image006[1]

1 1 0 F 0 1 1

RET NEAR (при F = 0 – внутрисегментный)

RET FAR (при F = 1 – межсегментный)

Рис. 4.3. Команда возврата из процедуры
Загрузка...