es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Por qué GCC genera una forma extraña de mover el puntero de pila

He observado que el compilador C++ de GCC genera el siguiente código ensamblador:

sub    $0xffffffffffffff80,%rsp

Esto es equivalente a:

add    $0x80,%rsp

es decir, se eliminan 128 bytes de la pila.

¿Por qué GCC genera la primera variante “sub” en lugar de la variante “add”? La variante “add” me parece mucho más natural que aprovechar que hay un desbordamiento.

Esto solo ocurrió una vez en una base de código bastante grande. No tengo un ejemplo mínimo de código C++ para reproducir esto. Estoy usando GCC 7.5.0.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Explicación

    La razón por la cual GCC genera sub $0xffffffffffffff80,%rsp en lugar de add $0x80,%rsp se debe a una convención seguida por la arquitectura x86 en cuanto a cómo se organiza la pila.

    En x86, la pila crece hacia abajo, lo que significa que los valores empujados a la pila se encuentran en direcciones de memoria más bajas que los valores anteriores. Cuando se sacan valores de la pila, las direcciones de memoria aumentan. El puntero de pila apunta al último valor empujado a la pila.

    Por lo tanto, al asignar espacio en la pila para variables locales o argumentos de función, GCC utiliza sub para disminuir el puntero de pila, y al desasignar, utiliza add para aumentarlo.

    En el caso específico de sub $0xffffffffffffff80,%rsp, esto resta 128 bytes del puntero de pila. La razón por la cual la resta se realiza con 0xffffffffffffff80 en lugar de 0x80 se debe a que x86 utiliza la representación en complemento a dos para los números negativos, y el bit alto indica que el número es negativo. Entonces, 0xffffffffffffff80 es -128 en complemento a dos, lo cual es equivalente a restar 128.

    En resumen, aunque la variante add puede parecer más natural, utilizar sub es necesario para seguir la convención de la pila x86 de asignar con sub y desasignar con add.

Comments are closed.