Если счетчик команд указывает на адрес следующей инструкции, которая будет выполняться, что делают указатели кадра?

Если счетчик команд указывает на адрес следующей инструкции, которая будет выполняться, что делают указатели кадра?

7
задан user133466 28 December 2009 в 00:14
поделиться

6 ответов

Это как более стабильная версия указателя стека

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

Однако указатель стека часто подстраивается для того, чтобы подталкивать аргументы к стеку для новых уровней вызова и хотя бы один раз при входе в метод для выделения собственных локальных переменных. Есть и другие, более непонятные причины для настройки указателя на стек.

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

Проще, если технически это ненужные накладные расходы, просто выделить регистр, указывающий на текущий кадр. На x86 это %ebp. При входе в функцию она может иметь фиксированное отношение к указателю стека.

Помимо отладки, это упрощает управление исключениями и может даже окупиться за счёт устранения или оптимизации некоторых настроек указателя стека.

Вы упомянули программный счётчик, так что стоит отметить, что указатель кадра, как правило, является полностью программной конструкцией, а не чем-то, что реализуется аппаратурой, за исключением того, что практически каждая машина может выполнять режим адресации регистр + смещение . Некоторые машины, такие как x86, действительно обеспечивают некоторую аппаратную поддержку в виде режимов адресации и макроинструкций для создания и восстановления кадров. Однако иногда обнаруживается, что основные инструкции выполняются быстрее, а макросопровождение заканчивается устареванием.

.
6
ответ дан 6 December 2019 в 15:23
поделиться

Это не совсем вопрос на Си, так как он полностью зависит от компилятора.

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

Вот пример, допустим, вы вызываете функцию, которая принимает один аргумент и возвращает сумму всех чисел от 1 до этого аргумента. Код на языке Си будет выглядеть так:

unsigned int x = sumOf (7);
: :
unsigned int sumOf (unsigned int n) {
    unsigned int total = 0;
    while (n > 0) {
        total += n;
        n--;
    }
    return total;
}

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

        mov  r1,7            ; fixed value
        push r1              ; push it for subroutine
        call sumOf           ; then call
retLoc: mov  [x],r1          ; move return value to variable
: :
sumOf:  mov  fp,sp           ; Set frame pointer to known location
        sub  sp,4            ; Allocate space for total.
: :

В этот момент (следуя за sub sp,4) у вас есть следующая область стека:

      +--------+
      | n(7)   |
      +--------+
      | retLoc |
      +--------+
fp -> | total  |
      +--------+
sp -> |        |
      +--------+

и вы можете увидеть, что передаваемые параметры можно найти, используя адреса 'над' указателем кадра и локальных переменных 'под' указателем кадра.

Функция может получить доступ к передаваемому значению (7), используя [fp+8], содержимому памяти на fp+8 (в данном примере каждая из этих ячеек равна четырем байтам). Она также может получить доступ к своей собственной локальной переменной (total) с помощью [fp-0], содержимое памяти с помощью fp-0. Я использовал номенклатуру fp-0, хотя вычитание нуля не имеет никакого эффекта, так как другие местные жители будут иметь соответствующие нижние адреса, такие как fp-4, fp-8 и так далее.

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

5
ответ дан 6 December 2019 в 15:23
поделиться

Хорошая дискуссия здесь, с примерами и прочим

Одним словом: ВП указывает на фиксированное место в кадре функции на стеке (и не изменяется во время выполнения функции), поэтому все передаваемые инструменты и локальные ("автоматические") переменные функции могут быть доступны по смещениям от ВП (в то время как ПВ может меняться во время выполнения функции, а ПК определенно меняется;-).

.
3
ответ дан 6 December 2019 в 15:23
поделиться

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

Это очень зависит от реализации (а скорее от машинной концепции, а не от языковой).

От комментария, который вы дали, до другого ответа:

Woh.... Указатель стека?... это синоним счетчика программ?

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

1
ответ дан 6 December 2019 в 15:23
поделиться

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

.
0
ответ дан 6 December 2019 в 15:23
поделиться

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

ссылочный текст

-1
ответ дан 6 December 2019 в 15:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: