Consideraciones para escribir código de prólogo y epílogo

 

Para obtener la documentación más reciente de Visual Studio 2017 RC, consulte Documentación de Visual Studio 2017 RC.

Antes de escribir sus propias secuencias de código de prólogo y epílogo, es importante que comprenda cómo se diseña el marco de pila. También es útil saber utilizar el símbolo __LOCAL_SIZE.

En este ejemplo se muestra el código de prólogo estándar que puede aparecer en una función de 32 bits:

push        ebp                ; Save ebp  
mov         ebp, esp           ; Set stack frame pointer  
sub         esp, localbytes    ; Allocate space for locals  
push        <registers>        ; Save registers  

La variable localbytes representa el número de bytes necesarios en la pila para las variables locales y la variable <registers> es un marcador de posición que representa la lista de registros que se guarden en la pila. Después de insertar los registros, puede colocar cualquier otro dato adecuado en la pila. A continuación, se muestra el código de epílogo correspondiente:

pop         <registers>   ; Restore registers  
mov         esp, ebp      ; Restore stack pointer  
pop         ebp           ; Restore ebp  
ret                       ; Return from function  

La pila siempre va de mayor a menor (de las direcciones de memoria superiores a las inferiores). El puntero base (ebp) señala al valor insertado de ebp. El área de valores locales comienza en ebp-4. Para tener acceso a las variables locales, calcule un desplazamiento de ebp restando el valor apropiado a ebp.

El compilador proporciona un símbolo, __LOCAL_SIZE, para su uso en el bloque de ensamblador alineado del código del prólogo de la función. Este símbolo se utiliza para asignar espacio para variables locales del marco de pila en código de prólogo personalizado.

El compilador determina el valor de __LOCAL_SIZE. Su valor es el número total de bytes de todas las variables locales definidas por el usuario y las variables temporales generadas por el compilador. __LOCAL_SIZE se puede utilizar como operando inmediato; no se puede utilizar en una expresión. No debe cambiar o volver a definir el valor de este símbolo. Por ejemplo:

mov        eax, __LOCAL_SIZE           ;Immediate operand--Okay  
mov        eax, [ebp - __LOCAL_SIZE]   ;Error  

El ejemplo siguiente de una función naked que contiene secuencias personalizadas de prólogo y de epílogo utiliza el símbolo __LOCAL_SIZE en la secuencia de prólogo:

// the__local_size_symbol.cpp  
// processor: x86  
__declspec ( naked ) int main() {  
   int i;  
   int j;  
  
   __asm {      /* prolog */  
      push   ebp  
      mov      ebp, esp  
      sub      esp, __LOCAL_SIZE  
      }  
  
   /* Function body */  
   __asm {   /* epilog */  
      mov      esp, ebp  
      pop      ebp  
      ret  
      }  
}  

FIN de Específicos de Microsoft

Llamadas de función naked

Mostrar: