![]() |
![]() |
![]() |
|||||||
![]() |
![]() |
||||||||
![]() |
![]() |
||||||||
![]() |
![]() |
||||||||
![]() |
![]() |
||||||||
![]() |
|||||||||
Параметры |
|||||||||
|
|||||||||
Как известно, при компиляции каждого оператора языка компилятор генерирует некоторый машинный (иначе - ассемблерный) код. Это относится и к вызову и возврату из процедур/функций. Для более подробного и наглядного представления о механизмах передачи параметров приведем примерный код, генерируемый компилятором, и иллюстрации к ним. При передаче параметра по значению генерируемый код следующий (1).
;Для процедуры
proc proc1 near; метаимя, ;реально не создается
mov bp, sp ; получаем
call check_stack ; проверка
pop bp ; восстанавливаем... ret 2 ; возврат с удалением
. . . ;Для ее вызова
Стоит отметить, что в случае наличия локальных переменных кода больше - создание стекового фрейма производится либо одной командой, либо вызовом системной процедуры.
![]() Передача параметров по значению. Результат очевиден: параметр является невозвращаемым, однако при этом является полноценной локальной переменной и может свободно использоваться. Стоит также заметить, что доступ к нему ничуть не медленнее, чем к локальным переменным. При передаче параметров по ссылке ситуация несколько другая. Передается адрес, и генерируемый код примерно следующий.
;для процедуры
proc proc1 near
mov bp, sp xor ax, ax call check_stack ; проверка cтека les di,[bp+4] ; читает из стека указатель
pop bp ret 4 ; возврат с удалением параметров . . .
push ds push di call proc1 ![]() Передача параметров по ссылке Результат в данном случае таков. Обращение к параметру, переданному по ссылке получается (квази)косвенным: сначала вычисляется адрес адреса параметра - BP+4 (он известен заранее), затем он (адрес параметра) читается, и только затем по нему производится обращение. Как следствие все чтения и/или записи производятся по адресу фактического параметра - в области данных вызывающего процесса. Следует еще раз отметить, что любой параметр, переданный по ссылке занимает в стеке размер полного адреса (в реальном режиме - 4 байта), а доступ к нему несколько дольше. (1)Наверх Код, представляемый
на обозрение, является несколько адаптированной
версией того, что показывает Turbo Debugger.
Компиляция проводилась без исползования
инструкций 286-го процессора.
Адаптация заключалась в замене адресов
на их символьные обозначения, и, естественно,
создании комментариев. |
|||||||||
|