Pregunta

He escrito un programa de "peligrosa" en C ++ que salta hacia atrás y hacia adelante de un marco de pila a otra. El objetivo es ser el salto desde el nivel más bajo de una pila de llamadas a una persona que llama, hacer algo, y luego saltar hacia abajo de nuevo, cada vez que salta todas las llamadas entre medio.

I hacer esto cambiando manualmente el (%ebp ajuste) dirección de base de la chimenea y saltar a una dirección de etiqueta. Es totalmente funciona, con gcc e ICC tanto, sin ningún tipo de daños en la pila en absoluto. El día que esto funcionó fue un día fresco.

Ahora estoy tomando el mismo programa y re-escrito en C, y no funciona. Específicamente, no funciona con gcc v4.0.1 (Mac OS). Una vez que salto al nuevo marco de pila (con el puntero base de la chimenea ajustado correctamente), las siguientes instrucciones se ejecutan, siendo justo antes de una llamada a fprintf. La última instrucción que aparece aquí se estrella, NULL eliminación de referencias:

lea    0x18b8(%ebx), %eax
mov    (%eax), %eax
mov    (%eax), %eax

He hecho algunas depuración, y he descubierto que al establecer el registro %ebx manualmente cuando cambio de marcos de pila (usando un valor observé antes de salir de la función en el primer lugar), que corregir el error. He leído que este registro con ofertas de "código independiente de posición" en gcc.

¿Cuál es la posición de código independiente? ¿De qué manera la posición de trabajo de código independiente? A lo que es este registro de puntero?

¿Fue útil?

Solución

PIC es el código que se trasladó dinámicamente cuando se carga. El código que es no-PIC tiene direcciones de salto y de establecimiento de llamada en tiempo de enlace. PIC tiene una tabla que hace referencia a todos los lugares donde existan esos valores, como un .dll.

Cuando se carga la imagen, el cargador se actualizará dinámicamente esos valores. Referencia Otros esquemas de un valor de datos que define una "base" y la dirección de destino es decidido por la realización de cálculos sobre la base. La base normalmente se establece por el cargador de nuevo.

Por último, otros esquemas de utilizar varios trampolines que llaman a las compensaciones relativas conocidas. Los desplazamientos relativos contienen código y / o datos que se actualizan mediante un cargador.

Existen diferentes razones por las que se eligen diferentes esquemas. Algunos son rápidos cuando se ejecuta, pero más lento para cargar. Algunos son rápidos en cargar, pero tienen menos rendimiento de ejecución.

Otros consejos

EBX apunta a la tabla global de compensación. Ver esta referencia sobre el PIC i386. El enlace se explica qué es un PIC cómo se utiliza EBX.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top