Я написал «опасную» программу на C ++, которая переходит от одного стекового кадра к другому. Цель состоит в том, чтобы перепрыгнуть с самого низкого уровня стека вызовов на вызывающего, сделать что-то, а затем снова спрыгнуть вниз, каждый раз пропуская все вызовы между ними.
Я делаю это вручную, изменяя базовый адрес стека (настройка %ebp
) и переходя на адрес метки. Он полностью работает, как с gcc, так и с icc, без какого-либо повреждения стека. День, когда это сработало, был классным.
Сейчас я беру ту же программу и переписываю ее на C, и она не работает. В частности, он не работает с gcc v4.0.1 (Mac OS). Как только я перехожу к новому фрейму стека (с правильно установленным указателем стека), выполняются следующие инструкции перед вызовом fprintf
. Последняя инструкция, указанная здесь, вылетает, разыменовывая NULL:
lea 0x18b8(%ebx), %eax
mov (%eax), %eax
mov (%eax), %eax
Я провел некоторую отладку и выяснил, что, установив регистр %ebx
вручную, когда я переключаю кадры стека (используя значение, которое я наблюдал, прежде чем покинуть функцию в первую очередь), я исправляю ошибку , Я читал, что этот регистр имеет дело с "позиционно-независимым кодом" в gcc.
Что такое независимый от позиции код? Как работает независимый от позиции код? На что указывает этот регистр?