assembly - registers - El significado de RET en montaje
lenguaje ensamblador x86 (5)
Como dijo alex, significa VOLVER. En el ensamblaje x86, cuando el compilador llega a esta línea (al final de una subrutina, por ejemplo), saca el último valor de la pila, que se supone que es la dirección de retorno, y lo asignó al registro de IP. Puedes entenderlo mejor escribiendo un simple código de ensamblador y compilándolo con Turbo Debugger. Hay una GUI para ensamblador si eres nuevo en eso. Puedes encontrar la GUI here .
Cuando está desplegando y presionando valores desde y hacia la pila cuando está en una subrutina, debe almacenar la dirección de retorno, ya que al final de la subrutización debe volver a colocarla en la pila antes de la línea de return
.
¡Buena suerte!
Soy muy nuevo en el ensamblaje y no entiendo lo que significa exactamente cuando, al final de un proceso, escribe un número con la instrucción ret
.
Me gusta esto:
Function Proc
push ax cx
.
...body...
.
pop cx ax
ret 2
Function endp
¿Entiendo que tiene algo que ver con dónde debe volver el puntero de la pila al final de la función?
Por favor, realmente me ayudaría si pudiera explicarlo fácilmente.
Digamos que tengo un procedimiento para agregar dos palabras y dejar la suma en EAX
. Las palabras son argumentos que quiero pasar al procedimiento en la pila. es decir:
push word1
push word2
call addtwob
El procedimiento se vería algo así como:
addtwob proc
push ebp
mov ebp,esp
mov eax, [ebp+6]
add eax, [ebp+8]
pop ebp
ret 4
Endp
[ebp+6]
y [ebp+8]
direccionan word2
y word1
en la pila. ret 4
simplemente regresa como de costumbre pero luego agrega 4 al puntero de la pila ( esp
) para que no tenga que pop word2
pop word1
de la pila después de regresar de la llamada, por lo tanto, limpia / equilibra la pila sin necesidad de sacar la anterior empuja
Parece que estás preguntando por un retorno cercano con un operando para x86_64 . El algoritmo que sigue el hardware cuando el procesador encuentra cerca de RET en el manual de referencia del conjunto de instrucciones de Intel es el siguiente;
(* Near return *)
IF instruction = near return
THEN;
IF OperandSize = 32
THEN
IF top 4 bytes of stack not within stack limits
THEN #SS(0); FI; //throw protected mode exception
EIP ← Pop();
ELSE
IF OperandSize = 64
THEN
IF top 8 bytes of stack not within stack limits
THEN #SS(0); FI; //throw protected mode exception
RIP ← Pop();
ELSE (* OperandSize = 16 *)
IF top 2 bytes of stack not within stack limits
THEN #SS(0); FI; //throw protected mode exception
tempEIP ← Pop();
tempEIP ← tempEIP AND 0000FFFFH;
IF tempEIP not within code segment limits
THEN #GP(0); FI; //throw protected mode exception
EIP ← tempEIP;
FI;
FI;
IF instruction has immediate operand
THEN (* Release parameters from stack *)
IF StackAddressSize = 32
THEN
ESP ← ESP + SRC;
ELSE
IF StackAddressSize = 64
THEN
RSP ← RSP + SRC;
ELSE (* StackAddressSize = 16 *)
SP ← SP + SRC;
FI;
FI;
FI;
FI;
De acuerdo con este algoritmo, siempre que se encuentre un retorno cercano, la dirección de retorno se verifica si está dentro de los límites SS. La parte superior de la pila aparece en RIP o EIP según el tamaño del operando si la dirección de retorno es válida.
Si el tamaño del operando es de 16 bits, una ubicación temporal retiene la dirección de retorno que aparece en AND con el valor 0x0000FFFF y se carga en el EIP después de verificar los límites de CS.
Cuando su pregunta pregunta qué sucede si hay un operando para el código de operación de la instrucción RET cercana. Depende del tamaño de la dirección de la pila. De acuerdo con ese tamaño, RSP ESP o SP se incrementa con el operando y después de que se completa la ejecución de la instrucción RET cercana en el hardware.
Sí, pero la ret 2
también elimina 2 bytes de parámetros de la pila. Presumiblemente, su función fue llamada como:
push some_parameter
call Function
En este punto, una función cdecl
- una función de "limpiador de llamadas" (generalmente utilizada por C) - requeriría add sp, 2
para "limpiar la pila", eliminando el parámetro. Tal función terminaría en un ret
llano.
Una función stdcall
, que es lo que tienes, es una función de "limpieza de la persona que llama" (utilizada por las API de Windows, por ejemplo) no requiere add sp, 2
; se realizó con la ret 2
.
Si no lo sabe, la call
pone la dirección de retorno en la pila (y la retorna fuera), por lo que no puede hacer pop
para obtener el parámetro dentro de su función.
Significa VOLVER, como un return
en lenguajes de alto nivel.
En la mayoría de las máquinas, sacará el valor anterior del contador del programa antes de ingresar la subrutina de la pila y lo copiará en el registro de la PC.
Para x86, el argumento es el número de parámetros en la pila. Esto se aplica solo si la convención utilizada es hacer que la subrutina se encargue de restablecer la pila.