Страница 48 из 56
PUBLIC _min
_min PROC near
.
.
.
- 393,394 -
_min ENDP
Это верно в предположении, конечно, что функция min будет
near-функцией. Если это far-функция, то вы должны заменить far на
near. Заметим, что min снабжено знаком подчеркивания для того,
чтобы компоновщик Турбо Си мог корректно установить связи.
Передача параметров
-----------------------------------------------------------------
Ваша первая задача - выбрать используемое в подпрограмме
соглашение по передаче параметров; учитывая приведенные ранее со-
ображения о трудностях использования Паскаль-соглашения, будем
избегать его и использовать Си-метод. Это означает, что когда
вызвана функция min, стек выглядит следующим образом:
SP + 04: v2
SP + 02: v1
SP: адрес возврата
Если вы хотите получить параметры, не изменяя содержания
стека, то для зтого необходимо сохранить базовый указатель (BP),
затем занести стековый указатель (SP) в базовый и использовать
его в качестве указателя на стек для извлечения из него необходи-
мых вам величин. Заметим, что после занесения BP в стек относи-
тельные смещения параметров возрастут на 2, т.к. в стек будут до-
бавлены 2 байта.
- 395,396 -
Управление возвращаемыми величинами
----------------------------------------------------------------
Ваша функция возвращает целую величину; куда вы ее помести-
те? Для 16-битных (2-байтных) величин (char, shot, int, enum,
near-указатели) вы используете регистр AX; для 32-битных (4-байт-
ных), включающих far- и huge-указатели - регистр DX для старшего
слова (или для адреса сегмента у указателей) и регистр AX для
младшего слова.
Величины float, double и long double возвращаются в регистре
top-of-stack (TOS) процессора 8087/80287, ST(0); если использует-
ся эмулятор 8087/80287, то величина возвращается в TOS регистр
эмулятора.
Величины структур возвращаются путем занесения их в стати-
ческую ячейку памяти и передачей указателя на эту ячейку (в АХ
для моделей с малыми данными, в DX:АХ для моделей с большими дан-
ными).
Вызывающая функция должна затем скопировать эту величину в
любом месте, где она необходима. Структуры длиной в 1 и 2 байта
возвращаются в АХ (подобно любой обычной целой), а 4-байтные
структуры в АХ и DX.
В примере с min вы имеете дело с 16-битной величиной, поэто-
му можете поместить ответ в АХ.
Ваша программа выглядит теперь так:
PUBLIC _min
_min PROC near
push bp ; Сохранить bp в стеке
mov bp,sp ; Загрузить sp в bp
mov ax,[bp+4] ; Переместить v1 в ax
cmp ax,[bp+6] ; Cравнить v1 и v2
jle exit ; если v1 > v2
mov ax,[bp+6] ; Загрузить в ax v2
exit: pop bp ; Восстановить bp
v2
mov ax,[bp+4] ; Загрузить в ax v2
exit: pop bp ; Восстановить bp
ret 4 ; Очистка стека и возврат
MIN ENDP
И последний пример, демонстрирующий, почему вам может потре-
боваться использовать Си-соглашение по передаче параметров. Пред-
положим, вы переопределили min следующим образом:
int extern min (int count, int v1, int v2, ...);
Теперь min может получать любое количество целых чисел и бу-
дет возвращать минимальное из них. Однако, т.к. min не имеет воз-
можности автоматически узнавать, сколько значений ей передано, то
первым ее параметром будет величина count, указывающая, сколько
величин следуют за ней.
Например, вы можете записать это так:
i = min (5, j, limit, indx, lcount, 0);
предполагая, что i, j, limit, indx и lcount - целые (или совмес-
тимого с int типа). Стек при входе будет выглядеть так:
SP + 08: (и т.д.)
SP + 06: v2
SP + 04: v1
SP + 02: count (счетчик)
SP: адрес возврата (смещение)
Теперь модифицированная версия min имеет вид:
- 401,402 -