Какова цель регистра указателя кадра EBP? - PullRequest
83 голосов
/ 23 февраля 2009

Я новичок в ассемблере и заметил, что код x86, генерируемый компиляторами, обычно сохраняет указатель кадра даже в режиме выпуска / оптимизации, когда он может использовать регистр EBP для чего-то другого.

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

Ответы [ 5 ]

91 голосов
/ 23 февраля 2009

Указатель кадра - это ссылочный указатель, позволяющий отладчику узнать, где находится локальная переменная или аргумент с одним постоянным смещением. Хотя значение ESP изменяется в ходе выполнения, EBP остается тем же самым, что позволяет достичь одной и той же переменной с одним и тем же смещением (например, первый параметр всегда будет иметь значение EBP + 8, тогда как смещения ESP могут значительно измениться, поскольку вы будете нажимать / появляются вещи)

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

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

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

28 голосов
/ 25 февраля 2009

Просто добавляю два моих цента к уже хорошим ответам.

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

Идея, что это предотвращает использование совершенно хорошего регистра в оптимизации, поднимает вопрос: когда и где на самом деле стоит оптимизация?

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

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

Я знаю, что вы не спрашивали об этом, но по моему опыту, 99% проблем с производительностью не имеют ничего общего с оптимизацией компилятора. Они имеют все, что связано с чрезмерным дизайном.

8 голосов
/ 23 февраля 2009

Конечно, это зависит от компилятора. Я видел оптимизированный код, генерируемый компиляторами x86, которые свободно используют регистр EBP в качестве регистра общего назначения. (Хотя я не помню, с каким компилятором я это заметил.)

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

4 голосов
/ 24 февраля 2009

Однако в x86 очень мало регистров

Это верно только в том смысле, что коды операций могут адресовать только 8 регистров. Сам процессор на самом деле будет иметь гораздо больше регистров и использует переименование регистров, конвейерную обработку, умозрительное выполнение и другие модные слова процессора, чтобы обойти это ограничение. В Википедии есть хороший вводный абзац о том, что процессор x86 может сделать, чтобы преодолеть ограничение регистра: http://en.wikipedia.org/wiki/X86#Current_implementations.

1 голос
/ 23 февраля 2009

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

Сколько вы экономите на чистом регистре? Стоит ли это того?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...