Sobre llamadas far y near de CALL RET

Sobre llamadas far y near de CALL RET

de Guillermo Daniel Toyos Marfurt -
Número de respuestas: 2

Hola. Me quedó la siguiente duda sobre las llamadas call/ret: Como hace la cpu para discernir sí una llamada es de tipo far o near? Es decir, sí yo llamo a una función que está en otro segmento, el ensamblador lo interpreta como una llamada FAR y pushea al stack tanto los valores del ip como del cs. Ahora bien, una vez dentro del procedimiento, cuando se ejecuta la instrucción RET como sabe la cpu que yo habia llamado el procedimiento desde otro segmento y tiene que popear tanto el cs como el ip para construir la dirección anterior?

En respuesta a Guillermo Daniel Toyos Marfurt

Re: Sobre llamadas far y near de CALL RET

de Gustavo Brown -

La CPU no tiene que discernir si la llamada es far o near. Hay 2 variantes de las instrucciones CALL, JMP y RET.

Una de ellas es NEAR y la otra FAR. Es decir, hay un código de operación para el CALL near y otro distinto para el CALL far. Lo mismo para los JMP y para los RET. 

Entonces la CPU o bien encuentra un CALL near o bien un CALL far y ya sabe lo que tiene que hacer. Cuando encuentra un RET va a ser un RET near o uno far. Y lo mismo con el JMP.

El ensamblador se encarga de codificar adecuadamente las instrucciones, puesto que él sí tiene la información relevante (dada por el programador). El hecho de que haya 2 códigos de operación para la misma instrucción se debe a que desde el punto de vista del programador no es necesario que esté indicando o deduciendo cada CALL, RET o JMP si es near o far, sino que esto puede ser deducido directamente por el ensamblador con la información provista por el programador en un solo lado (al definir las subrutinas).

Cuando uno programa un proc le puede decir si es near o far. Si no dice nada el ensamblador usualmente supone que es near.

Los ensambladores generalmente ensamblan en 2 pasadas. La primer pasada entre otras cosas "anota" cuales son las etiquetas que existen y de qué tipo son cada rutina (near o far).
Entonces cuando el ensamblador encuentra un CALL a una subrutina puede fijarse si esa subrutina es near o far y ensambla esa instrucción con el código de operación correspondiente. 

Cuando el ensamblador encuentra un RET se fija si está dentro de una rutina near o far. Si es near emite código máquina asociado a un RET near, y cuando es far emite código asociado al RET far.

Saludos,
  Gustavo