2012-06-24 21 views
8

Estoy jugando con gcc -S para entender cómo funciona la memoria y la pila. Durante estas obras, encontré varias cosas poco claras para mí. ¿Podrías por favor ayudarme a entender las razones?¿Por qué gcc lo hace al crear código ensamblador?

  1. Cuando la función que llama establece argumentos para una llamada que utiliza un mov a esp lugar push. ¿Cuál es la ventaja de no usar push?

  2. La función que funciona con sus argumentos ubicados en la pila los señala como ebp + (N + offset) (donde N es un tamaño reservado para la dirección de retorno). Espero ver esp - offset que es más comprensible. ¿Cuál es la razón para usar ebp como punto fundamental en todas partes? Sé que estos son iguales, ¿pero de todos modos?

  3. ¿Para qué sirve esta magia al principio de main? ¿Por qué esp debe inicializarse de esta manera solamente?

    and esp,0xfffffff0 
    

Gracias,

+3

Esto podría ser 3 preguntas separadas. De todos modos, la respuesta al 3er punto es la alineación de la pila. – Mysticial

Respuesta

7

Voy a suponer que usted está trabajando en un entorno de 32 bits ya que en un entorno de 64 bits argumentos se pasan en registros.

Pregunta 1

Tal vez usted está pasando un argumento de coma flotante aquí. No puede insertarlos directamente, ya que la instrucción push en un tiempo de ejecución de 32 bits empuja 4 bytes a la vez, por lo que tendría que dividir el valor. A veces es más fácil restar 8 de esp y mover el quadword de 8 bytes al [esp].

Pregunta 2

ebp se utiliza con frecuencia para indexar los parámetros y los locales en los marcos de pila de código de 32 bits. Esto permite que los desplazamientos dentro de los marcos sean fijos incluso cuando se mueve el puntero de la pila. Por ejemplo, consideremos

void f(int x) { 
    int a; 
    g(x, 5); 
} 

Ahora bien, si sólo se tuvo acceso a los contenidos de los marcos de pila con esp, entonces es a en [esp], la dirección de retorno sería en [esp+4] y x estaría en [esp+8]. Ahora generemos código para llamar al g. Primero debemos presionar 5 y presionar x. ¡Pero después de presionar 5, el desplazamiento de x de esp ha cambiado! Es por eso que se usa ebp. Normalmente, al ingresar a las funciones, presionamos el antiguo valor de ebp para guardarlo, luego copie esp en ebp. Ahora se puede usar ebp para acceder al contenido del marco de la pila. No se moverá cuando estemos en el medio de pasar argumentos.

Pregunta 3

Esta instrucción and ceros desde los últimos 4 bits de esp, alineándolo con un límite de 16 bytes. Como la pila crece hacia abajo, esto es agradable y seguro.

+1

Q3: Cierra los últimos 4 bits – hirschhornsalz

+0

Oh, gracias, @drhirsch. Escribiendo sin pensar Terrible. ¡Muchas gracias! Editado –

Cuestiones relacionadas