Сохранение регистров
Каждая подпрограмма должна либо сохранять значения всех регистров процессора (кроме тех, которые используются для возврата результатов), либо, в крайнем случае, в описании подпрограммы должно быть четко указано, какие регистры она портит. Для сохранения регистров используется стек. Команды push служат для помещения регистров в стек, а pop – для их восстановления перед возвратом из подпрограммы. Сохранение регистров должно выполняться после загрузки BP (см. предыдущий параграф).
Локальные переменные
Переменные, размещенные в сегменте данных, являются статическими (аналогично переменным с классом static в Си). Конечно, их можно рассматривать как локальные переменные подпрограмм, обеспечив локализацию области действия с помощью директивы locals (см. ниже). Однако такое статическое распределение памяти под локальные переменные не соответствует понятию локальных переменных в блочных языках типа Pascal или C, поскольку время существования таких переменных – время существования программы. Для того чтобы решить данную проблему, т.е. обеспечить динамическое распределение памяти под локальные переменные, следует выделять для них память в стеке (как это делается в Pascal или C).
Предположим, что в подпрограмме должно быть две локальные переменные длиной в слово. Чтобы обеспечить выделение памяти, для них перед командами сохранения регистров следует добавить команду:
sub SP, 4
которая резервирует в стеке два слова.
После выполнения этой команды стек будет выглядеть следующим образом:
1-я лок.пер. | Ü SP |
2-я лок.пер. | |
BP | сохраненное значение BP |
IP | адрес возврата |
2-й параметр | параметр, занесенный в стек вторым |
1-й параметр | параметр, занесенный в стек первым |
. . . |
И, если определить структуру:
__locvars struc
__var1 dw ?
__var2 dw ?
__locvars ends,
то доступ к локальным переменным можно осуществить с помощью команд:
mov AX, __var1[BP-4];загрузить в AX значение 1-й локальной переменной
mov BX, __var2[BP-4];загрузить в BX значение 2-й локальной переменной
Чистка стека от локальных переменных должна выполняться после восстановления сохраненных регистров, это можно сделать с помощью команды:
add SP, 4
или
mov SP, BP
Директивы описания сегментов и модели памяти