Команда MARK

Команда MARK - это единственная команда во всех известных мне архитектурах, которая предназначена исключительно для исполнения в стеке (как трамплин), а не в составе базового исполняемого кода:

Ассемблерный кодСодержимое стека и R5 при входе в процедуру

    MOV R5,(-SP)        ; push old value of R5

      ...               ; code to push n parameters

    MOV #(MARK n),R5    ; put mark on stack
    JSR R5,PROC         ; call proc.
RET:
      ...

PROC:

      ...               ; code for body of procedure

    JMP (SP)            ; jump to mark instruction on stack
R5 = RET
Стек (растет вниз):
old value of R5
n parameters
#(MARK n)

Или, если предполагается использовать стандартную процедуру, возвращающуюся по R5:

Ассемблерный кодСодержимое стека и R5 при входе в процедуру

    MOV R5,-(SP)	; push old value of R5

      ...               ; code to push n parameters

    MOV #(MARK n),-(SP) ; put mark on stack
    MOV SP,R5           ; point R5 to the MARK instruction
    JSR PC,PROC         ; call proc.
RET:
      ...

PROC:

      ...               ; code for body of procedure

    RTS R5
R5 = SP+2 (адрес команды MARK в стеке)
Стек (растет вниз):
old value of R5
n parameters
#(MARK n)
RET

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

Обратите внимание, что команда MARK может использоваться только в сочетании с регистром R5 - это ещё одна её особенность. Тем самым в PDP-11 (БК-0010) аппаратно предопределены функции не двух регистров, как это обычно считается (R7 = PC, R6 = SP), а трёх (R5 = регистр возврата). К сожалению, т.к. команда MARK была реализована только на старших моделях PDP-11, известные мне Си-компиляторы для PDP-11 её не используют.

Вот как выглядит формальное определение команды MARK:

MARK N:
          SP = PC + (2 * N)
          PC = R5
          R5 = M[SP++]


© Leonid A. Broukhis, 2003