LINUX.ORG.RU

Адрес возврата


0

0

Господа, объясните мне плз. такую конструкцию, с которой начинается вход в подпрограмму (ну никак я ее понять не могу :( ):

pushl %ebp
mov %esp, %ebp

Мне не совсем понятен ее смысл :(. если не затруднит, то хотелось бы по-подробнее услышать ответ. заранее спасибо.

anonymous

foo:
EBP -> a
       b
       c
ESP ->

После твоего кода:

           a
           b
           c
           EBP
EBP=ESP -> 

это подготовка стека к вызову подпрограммы EBP используется для адресации параметров подпрограммы.

Begemoth ★★★★★
()

здесь в стеке сохраняют текущее же состояние стека при этом формируют область для временных переменных которые как известно хранятся в стеке когда происходит выход из функции старое значение вершины стека берут из ebp а старое значение ebp берут из стека. все это делает обычно инструкция leave. короче это делают для того чтобы сохранить состояние стек до вызова процедуры и при этом освободить регистр esp для личных нужд.

http://www.linuxfocus.org/Russian/March2001/article183.shtml

x86 ★★
()

func_begin: /* начало функции (в esp адрес возврата) */
pushl %ebp /* сохранить старое значение ebp,
             (значение в esp уменьшилось на 4) */
mov %esp, %ebp /* запомнить начало кадра стека в ebp (для локальных
                  переменных). адресация локальных переменных
                  будет вестись относительно
                  значения в ebp, адресация параметров функции
                  - значение в ebp плюс 8 */

subl $8, %esp  /* выделить в стеке 8 байт для локальных переменных
                  (или столько, сколько будет нужно)*/

...
/* делаем свои черные делишки */
...

mov %ebp, %esp /* или заменяем эту и следующую строку на leave */
pop %ebp
ret /* домой */

PS
Как говорят китайцы когда сделаешь - поймешь. Попробуй написать свою
реализацию для setjmp/longjmp

kosmonavt
()
Ответ на: комментарий от kosmonavt

Да, и ещё никто не сказал о том, что сия конструкция - всего лишь распространённое соглашение о вызове процедуры, и используется главным образом в отладочных целях для лёгкости восстановления стека вызовов.

Регистр же ebp столь же равноправен, как и остальные, и в enduser программе лучше его использовать в более благодарных целях. Для этого, например, в gcc, есть ключ --fomit-frame-pointer.

jek_
()
Ответ на: комментарий от jek_

да но помоему адресация через esp в процессоре оптимизированна и выполняется быстрее а --fomit-frame-pointer убирает этот код если в функции НЕ используется стек. типа Don't keep the frame pointer in a register for functions that don't need one.

x86 ★★
()
Ответ на: комментарий от x86

Всем, спасибо, господа! Вроде бы разобрался с этим вопросом.

anonymous
()
Ответ на: комментарий от x86

> через esp в процессоре

В смысле - через ebp? Может это и так, я, признаться, не знаю. Но всё же целый свободный регистр - это же целых 14% от их общего числа! В некоторых случаях использование ebp в других целях гораздо целесообразнее.

> --fomit-frame-pointer убирает этот код если в функции НЕ используется стек.

Хм, ну это должна быть ОЧЕНЬ простая функция, без параметров и с очень малым числом локальных переменных. Но я проверил, --fomit-frame-pointer действительно убирает пролог вне зависимости от числа параметров и локалов.

jek_
()
Ответ на: комментарий от x86

> вместо leave делает свои преобразования с esp

Ну конечно, надо же стек очистить от мусора (локалов то бишь).

jek_
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.