while subrutinas programas maquina lenguaje explicados ensamblador ejemplos assembler assembly x86 call function-calls

assembly - subrutinas - programas en lenguaje ensamblador explicados



¿Cómo funcionan las llamadas a procedimiento en ensamblador? (4)

No creo que el valor de retorno esté almacenado en el registro AX

Acabo de empezar a jugar con ASM y no estoy seguro de si mi comprensión de las llamadas al procedimiento es correcta.

decir que en algún punto del código hay una llamada al procedimiento

call dword ptr[123]

y el procedimiento consiste en solo un comando, ret:

ret 0004

¿Cuál sería el efecto de esta llamada a procedimiento, y dónde se almacenaría el valor de retorno? Leí en alguna parte que un valor de retorno de 2 bytes se almacenaría en AX, pero cuando reemplace el procedimiento, llame por

mov AX, 0004

(junto con los NOP necesarios) el programa se bloquea.


Todo depende de la convención de llamadas que se use. No voy a repetir el artículo de Wikipedia aquí, solo lea la definición.

En la convención de llamadas de C , por ejemplo, el valor de retorno estaría en EAX / AX / AL. Su única instrucción no tiene una: es una función vacía que toma alrededor de 4 bytes de parámetros (posiblemente un único int) que no hace nada. Como es deber del destinatario limpiar la pila en esta convención de llamadas, ignorar hacer eso y reemplazar la llamada con un ''mov ax'' no funciona.

También sospecho que puede estar jugando con el ensamblaje de 32 bits mientras lee un documento de 16 bits. No es un gran problema, pero debes ser consciente de las diferencias.


en el ensamblador x86, el parámetro para la instrucción ret significa:

RET immediate

Regrese al procedimiento de llamada y pop bytes inmediatos de la pila.

(citas de las arquitecturas Intel® 64 e IA-32, Manuales del desarrollador de software Vol 2B )

Entonces cuando escribes:

ret 0004

Le está diciendo a la CPU que regrese a la instrucción inmediatamente después de la call y que saque 4 bytes de la pila. Esto es genial si presionó 4 bytes en la pila antes de la llamada.

push eax call dword ptr[123]

Tenga en cuenta que esto no tiene nada que ver con el valor de retorno. De hecho, un procedimiento en Assembly no tiene forma de especificar que un valor sea un valor de retorno . Todo esto se hace por convención. La mayoría de los compiladores de los que tengo conocimiento utilizarán EAX para mantener el valor de retorno, pero esto es cierto solo porque la función de llamada esperará el resultado allí.

Entonces su código de llamada sería:

call dword ptr [123] mov dword ptr [result], eax

y su función que devuelve el valor 4 sería:

mov eax, 4 ret


// possibly there are arguments pushed here ... call dword ptr[123] // push next OP code offset in the stack and jump to procedure // procedure ... ret 0004 // pop offset, set EIP to that offset and decrease ESP by 4

también disminuimos el ESP si hubiésemos insertado argumentos en la pila antes de llamar al procedimiento.


Si hay argumentos insertados, su programa se bloquea porque no los muestra. El desplazamiento de retorno para el procedimiento actual será incorrecto ya que obtendrá un valor de uno de los argumentos empujados como el desplazamiento.