[Назад] [Далее]

8.1.2. Конвенция С

Этот способ передачи параметров используется в первую очередь в языках С и C++, а также в PROLOG и других. Параметры помещаются в стек в обратном порядке, и, в противоположность PASCAL-конвенции, удаление параметров из стека выполняет вызывающая процедура. Запись

    some_proc(a,b,c,d,e)

превращается в

    push     e
    push     d
    push     с
    push     b
    push     a
    call     some_proc
    add      sp,10    ; освободить стек

Вызванная таким образом процедура может инициализироваться так: some_proc proc push bp mov bp,sp ; создать стековый кадр a equ [bp+4] ; определения для простого доступа к параметрам b equ [bp+6] с equ [bp+8] d equ [bp+10] e equ [bp+12] ; текст процедуры, использующей параметры a, b, с, d, e pop bp ret some_proc endp

Ассемблеры поддерживают и такой формат вызова при помощи усложненной формы директивы proc с указанием языка С:

some_proc   proc       С,а:word,b:word,с:word,d:word,e:word

; текст процедуры, использующей параметры a, b, с, d, e.
; Так как BP применяется как указатель стекового кадра,
; его использовать нельзя!

            ret
some_proc   endp

Мы не пользовались до сих пор этими формами записи процедур в ассемблере потому, что они скрывают от нас тот факт, что регистр ВР используется для хранения параметров и его ни в коем случае нельзя изменять, и, в случае PASCAL, что команда ret на самом деле — команда ret N.

Преимущество по сравнению с PASCAL-конвенцией заключается в том, что освобождение стека от параметров в С возлагается на вызывающую процедуру, что позволяет лучше оптимизировать код программы. Например, если мы должны вызвать несколько функций, принимающих одни и те же параметры подряд, можно не заполнять стек каждый раз заново:

    push     param2
    push     param1
    call     proc1
    call     proc2
    add      sp,4

эквивалентно

    proc1(param1,param2);
    proc2(param1,param2);

и это — одна из причин, почему компиляторы с языка С создают более компактный и быстрый код по сравнению с компиляторами с других языков.


п»ї
"target=_blank><\/a>") //-->