2010-04-09 3 views
4

При передаче параметров функции в стеке процессора,Попутных параметров в стеке

Вы кладете параметры на то JSR помещает адрес возврата в стеке. Так это означает, что в вашей функции вы должны взять на себя верхний элемент стека (адрес возврата) , прежде чем принимать другие выключен)

Возвращаемое значение сохраняется в соответствии с соглашением в регистре D0.

например, является следующий правильный путь идти о нем:

... 
|Let’s do some addition with a function, 
MOVE.L #4, -(SP) 
MOVE.L #5, -(SP) 
JSR add 
     |the result of the addition (4+5) is in D0 (9) 
... 

add: 
    MOVE.L (SP)+, A1  |store the return address 
          |in a register 
    MOVE.L (SP)+, D0  |get 1st parameter, put in D0 
    MOVE.L (SP)+, D2  |get 2nd parameter, put in D2 

    ADD.L  D2, D0  |add them, 
          |storing the result in D0 
    MOVE.L A1, -(SP)  |put the address back on the 
          |Stack 
    RTS      |return 

ответ

6

No.

Вызываемых (целевая функция), как правило, не несет ответственности за удаление своих собственных аргументов. Вызывающий их положил туда, и тот, кто лучше знает, как их удалить.

И на 68000, это легко прочитать, используя относительное смещение в стек, нет необходимости физически удалять (вызывать) аргументы из стека. Это связано с проблемой того, что нужно «удвоить буфер» обратного адреса довольно хорошо.

Таким образом, ваш код должен что-то вроде этого прочитать:

MOVE.L #4, -(SP) 
    MOVE.L #5, -(SP) 
    JSR add 
    ADDQ.L #8, SP   |remove the arguments from the stack, both at once. 

... 

add: 
    MOVE.L 4(SP), D0  |get 1st parameter, put in D0 
    ADD.L 8(SP), D0  |add the 2nd parameter 
    RTS      |return 
8

Вы не «снять» параметры из стека, в том смысле, что вы не совать их. Обычно вы назначаете регистр кадров для указания вершины стека в точке входа в процедуру и получаете доступ к параметрам с постоянными известными смещениями из указателя кадра. Тогда ваш индекс просто «пропускает» обратный адрес, который, как вы знаете, есть.

E.g. в какой-то гипотетической сборке, когда вы находитесь в процедуре. Предположим, что стек растет вниз:

... 
argument2 
argument1 
ret addr  <---- stack pointer 

Так что доступ argument1 по смещению sp+4 (предполагая, что 32-бит), argument2 по смещению sp+8 и т.д. Так как эти соглашения о вызовах, как известно, эти сдвиги жестко закодированы в коде и эффективны для вычисления.

Указатель фрейма очень полезен, так как вы также подталкиваете локальные переменные к стеку, и вы не хотите, чтобы индексирование параметров изменялось в разных местах, поэтому указатель кадра обеспечивает стабильный якорь на протяжении всего выполнения процедуры.

3

Нет, вам не нужно выставлять параметры из стека, чтобы посмотреть на них; обычной процедурой является использование реестра «указатель кадра», как говорит @eli. Фактически, у 68k даже есть инструкция (LINK), которая предназначена для того, чтобы облегчить это: это одна команда, которая (a) сохраняет предыдущий указатель кадра, (b) копирует текущий указатель стека указателю кадра и (c) уменьшается указатель стека на указанное количество, чтобы оставить место для локальных переменных.

Вот example of C code and the corresponding 68000 assembler.

Смежные вопросы