tutorial registers lenguaje language instruction ensamblador assembly x86

assembly - registers - ret, retn, retf-cómo usarlos



lenguaje ensamblador x86 (3)

En la retne mnemónica N, N es el tamaño de los parámetros en la pila. En este caso, es 4 * 4 = 16 (10 h) para 4 DWORD.
Pero esto solo se aplica a las convenciones de llamadas cuando el destinatario es responsable de la limpieza de la pila. En el caso de la convención cdecl, el ret debe estar sin ningún número, ya que el que llama es responsable de la limpieza de la pila.

Tengo el siguiente código de asm:

; int __stdcall wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd) _wWinMain@16 proc near var_8= dword ptr -8 var_4= dword ptr -4 hInstance= dword ptr 8 hPrevInstance= dword ptr 0Ch lpCmdLine= dword ptr 10h nShowCmd= dword ptr 14h push ebp mov ebp, esp sub esp, 8 mov [ebp+var_4], 5 mov eax, [ebp+var_4] add eax, 1 mov [ebp+var_8], eax xor eax, eax mov esp, ebp pop ebp retn 10h

Según lo que leí, tienes 3 tipos de instrucción de retorno: ret, retn y retf, es decir, return, return near y return far. Permiten un argumento opcional nBytes, que supongo que es el número de bytes que se mostrarán a partir de las variables definidas. ¿Cuándo debo usar retn o retf en lugar de ret? ¿Cómo puedo calcular el parámetro opcional, nBytes?


En realidad, solo hay dos rendimientos diferentes, retn (casi retorno) y retf (retorno lejano). Cuando solo usa ret, el ensamblador o compilador es lo suficientemente inteligente como para elegir cuál es necesario. Un retorno cercano es un salto dentro del segmento de código existente, un retorno lejano es un salto a un segmento de código diferente. En Windows, solo tiene un segmento de código único, y por lo tanto, ret debe ser solo una referencia para retn. Las instrucciones separadas retn y retf son un retroceso a los viejos tiempos cuando los modelos de memoria segmentados eran comunes. Casi todos los sistemas x86 de 32 bits que se ejecutan en la actualidad utilizan un modelo de memoria plano, no segmentado.

Ret sin argumento saca la dirección de retorno de la pila y salta hacia ella. Algunas convenciones de llamadas (como __stdcall) especifican que la función de llamada limpia la pila. En este caso, llaman a ret con número de bytes para sacar esos parámetros de la pila. Los 16 bytes son los parámetros de la función winmain.


En realidad, son dos tipos: retn y retf . El tercero es codificado por el ensamblador en uno de los dos primeros.

La diferencia es que retn (return near) mostrará el puntero de instrucción (IP) solamente. Mientras que retf (return far) mostrará el puntero de instrucción (IP) y el segmento de código (CS).