Hay 2 versiones de las instrucciones CALL y RET, una hace el llamado FAR y la otra NEAR.
Cuando uno programa en assembler no precisa llamarlas distintas a las instrucciones porque el ensamblador se encarga de determinar cual versión utilizar.
- Si estoy en un procedimiento FAR, el RET es FAR
- Sino el RET ese NEAR
- Si estoy llamando a un procedimiento definido como FAR, el CALL es FAR
- Sino, el CALL es NEAR
Un procedimiento es FAR cuando se puede llamar desde otro segmento de código. Por lo tanto al llamar a dicho procedimiento la version FAR del CALL lo que hace es guardar en el stack el valor actual de CS e IP y saltar a la dirección segmentada indicada en la instrucción (que apunta al procedimiento a llamar).
En este caso, el procedimiento al hacer RET debe volver al llamador, por lo que debe quitar del stack no solo el IP del llamador sino tambien el valor del CS del llamador
Al escribir el programa, el programador indica para cada procedimiento si es FAR o NEAR (por defecto queda NEAR).
Para indicar que el procedimiento es FAR:
miProc PROC FAR
....
miProc ENDP
Luego en este caso si alguien llama a miProc el ensamblador sabe que debe colocar la version del CALL que es FAR, y también sabe que dentro de miProc si aparece un RET éste debe ser FAR.
Saludos,
Gustavo