Sé un poco sobre la Asamblea. Permítanme presentarles primero los códigos y luego explicarles mi forma de pensar.
#This is the Assembly version. pushq %rbp movq %rsp, %rbp movl $2, -4(%rbp) movl $3, -8(%rbp) movl $5, %eax popq %rbp ret #This is the C version. int twothree() { int a = 2; int b = 3; return 2 + 3; }Muy bien, lo primero que me llama la atención es que no usamos las variables a y b como a + b. Entonces son innecesarios, sumamos directamente los números enteros. Sin embargo, si las computadoras pudieran entender eso, supongo que sería realmente aterrador. Entonces, mi pregunta es: ¿Cómo funcionó este código ensamblador sin ningún comando addl o similar? Movemos directamente el número entero inmediato (o constante) 5 a eax registrador.
Además, pregunta rápida. Entonces, ¿qué sucede con las variables a y b después de las dos últimas líneas? Su posición en la pila (o tal vez podemos llamar a los 'registradores' que usaron como lugar de memoria) ahora está libre ya que usamos malloc + free. ¿Es cierto o al menos lógico? popq %rbp es el comando para cerrar la pila, supongo.
No soy un experto en montaje como dije. Así que la mayoría de estos pensamientos son solo pensamientos. ¡Gracias!
El compilador vio que estabas sumando dos números 2 + 3 . Y el compilador calculó que 2+3=5 y puso 5 en el código ensamblador. Esto se llama "plegamiento constante".
Supongo que tiene la optimización desactivada en su compilador ya que no eliminó las variables inútiles a y b . Pero el plegado constante es muy fácil para el compilador (a diferencia de otros tipos de optimización) y útil, por lo que parece que el compilador lo hace incluso cuando no activas la optimización.
Como se dio cuenta, el código ensamblador no agrega 2 y 3 porque no hay un comando addl o similar. Simplemente return 5;
No hay comandos o códigos en la programación de ensamblaje. En cambio, el código ensamblador (incontable) comprende instrucciones y directivas.
¿Dónde ves un uso de malloc o free ? Estas son funciones para administrar la memoria dinámica que no es algo que use su programa. Si se usara alguna de estas funciones, tendría una call malloc o una instrucción de call free en el código en alguna parte. Las b a todas en almacenamiento automático , es decir, en la pila.
Ahora, lo que sucede en su código es que el compilador ha realizado plegamiento constante para emitir código como si escribiera
#This is the C version. int twothree() { int a = 2; int b = 3; return 5; }Esto es algo que hace el compilador independientemente de los indicadores de optimización. Entonces, de hecho, no se realiza ninguna adición en tiempo de ejecución. Ya se realizó durante el plegado constante en tiempo de compilación.
Además, pregunta rápida. Entonces, ¿qué sucede con las variables a y b después de las dos últimas líneas? Su posición en la pila (o tal vez podemos llamar a los 'registradores' que usaron como lugar de memoria) ahora está libre ya que usamos malloc + free. ¿Es cierto o al menos lógico? popq %rbp es el comando para cerrar la pila, supongo.
Las variables se almacenaron en la zona roja, una región de memoria de 128 bytes debajo del puntero de la pila que se puede usar libremente como borrador sin tener que asignarlo explícitamente. Por lo tanto, no se necesita ningún código para asignarles o liberarles almacenamiento.
Ahora, no existe tal cosa como "cerrar la pila". La pila es una región en la memoria. El puntero de pila rsp apunta a la parte superior de la pila, mientras que el puntero base rbp apunta a la parte inferior del marco de pila actual. A menudo verá código como
push %rbp mov %rsp, %rbp ... pop %rbppara establecer y derribar un marco de pila para la función al principio y al final. Lea un tutorial de montaje para obtener más detalles.