Compilador que usa variables locales sin ajustar RSP

3 minutos de lectura

avatar de usuario
Pablo Ogilvie

En cuestión Compiladores: comprender el código ensamblador generado a partir de pequeños programas, el compilador usa dos variables locales sin ajustar el puntero de la pila.

no ajustar RSP para el uso de variables locales parece no interrumpir seguro por lo que el compilador parece depender de que el hardware cambie automáticamente a una pila del sistema cuando se produzcan interrupciones. De lo contrario, la primera interrupción que se presente empujaría el puntero de instrucción a la pila y sobrescribiría la variable local.

El código de esa pregunta es:

#include <stdio.h>

int main()
{
    for(int i=0;i<10;i++){
        int k=0;
    }
}

El código ensamblador generado por ese compilador es:

00000000004004d6 <main>:
  4004d6:       55                      push   rbp
  4004d7:       48 89 e5                mov    rbp,rsp
  4004da:       c7 45 f8 00 00 00 00    mov    DWORD PTR [rbp-0x8],0x0
  4004e1:       eb 0b                   jmp    4004ee <main+0x18>
  4004e3:       c7 45 fc 00 00 00 00    mov    DWORD PTR [rbp-0x4],0x0
  4004ea:       83 45 f8 01             add    DWORD PTR [rbp-0x8],0x1
  4004ee:       83 7d f8 09             cmp    DWORD PTR [rbp-0x8],0x9
  4004f2:       7e ef                   jle    4004e3 <main+0xd>
  4004f4:       b8 00 00 00 00          mov    eax,0x0
  4004f9:       5d                      pop    rbp
  4004fa:       c3                      ret    

Las variables locales son i en [rbp-0x8] y k en [rbp-0x4].

¿Alguien puede arrojar luz sobre este problema de interrupción? ¿El hardware realmente cambia a una pila de sistema? ¿Cómo? ¿Estoy equivocado en mi entendimiento?

  • Tal vez esto podría ser de su interés: stackoverflow.com/questions/28759227/…

    – Apoya a Ucrania

    25 de marzo de 2017 a las 7:26

  • Tenga en cuenta que las interrupciones HW no utilizan la pila de usuario. pilas de kernel hipocresía use una zona roja porque HW golpea de forma asíncrona. La pila de usuario solo se usa de forma asincrónica por cosas impulsadas por software: señal controladores y GDB llamando a una función para print foo().

    – Peter Cordes

    10 mayo 2020 a las 10:50

  • Gracias por tu respuesta. Lo explica todo. Entonces, ante una interrupción, el hardware empuja el puntero de instrucción 128 bytes hacia abajo en la pila y, por lo tanto, no sobrescribe las variables locales. Si la función requiere más de 128 bytes para almacenamiento local, debe ajustar el puntero de pila.

    –Paul Ogilvie

    25 de marzo de 2017 a las 8:34

  • @Paul: el kernel usa una pila separada, por lo que una interrupción privilegiada no tocará la pila del código de usuario.

    – Bo Person

    25 de marzo de 2017 a las 9:21

  • @Paul: no soy un experto en System V, pero creo que el sistema operativo no le permitirá instalar un controlador de interrupciones en el código de nivel de usuario. Así que nunca sucede.

    – Bo Person

    25 de marzo de 2017 a las 15:54

  • El código del kernel usa un ABI diferente donde no hay una zona roja. El ajuste de la pila en 128 bytes entra en juego durante el procesamiento de la señal. Cuando una señal “interrumpe” un proceso, el kernel ajusta el puntero de pila 128 bytes hacia abajo antes de ejecutar el controlador de señal.

    – Ross Ridge

    25 de marzo de 2017 a las 17:22

  • Modifiqué la respuesta para proporcionar la entrada Wiki actualizada (recientemente modifiqué el artículo Wiki). El anterior sugirió incorrectamente que la zona roja comienza debajo de la ubicación donde se almacena la dirección de retorno. Esto es inexacto: son los 128 bytes directamente debajo del valor actual de RSP . RSP puede o no estar apuntando a la dirección del remitente.

    -Michael Petch

    15 de abril de 2017 a las 19:14

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad