Call far

Résolu
cs_parki Messages postés 75 Date d'inscription mardi 29 juillet 2008 Statut Membre Dernière intervention 25 mars 2019 - 10 déc. 2013 à 16:57
cs_parki Messages postés 75 Date d'inscription mardi 29 juillet 2008 Statut Membre Dernière intervention 25 mars 2019 - 13 déc. 2013 à 15:39
Bonjour,

En 16 bits , est il possible d'appeler un prog situé dans un autre segment de code puis de revenir dans le segment de code initial ?

ex:

mov ax,cs ;ici cs vaut une certaine valeur
mov ds,ax

call "NEWcs:offset" ;NEWcs:offset est l'endroit où se trouve mon sous prog se terminant par un ret

blabla ;poursuite du prog principal

Car lorsque le processeur rencontre call "NEWcs:offset" ,cs prend la valeur NEWcs,le sous prog se déroule
puis lors du ret on a le pop ip habituel qui renvoie bien l'offset de l'instruction suivant le call (blabla)
mais la valeur de cs reste celle du segment où se trouve le sous prog et pas celui du prog original avant le call,donc ça plante
J'ai essayé de faire push cs avant le call puis pop cs dans le sous prog avant le ret mais à priori pop cs n'est plus valable au dela des 8088.

J'y arrive en faisant des jmp mais c'est pas pratique du tout.

je travaille sous virtualbox pour l'émulation 16 bits .
Merci pour vos conseils.

--

2 réponses

cs_parki Messages postés 75 Date d'inscription mardi 29 juillet 2008 Statut Membre Dernière intervention 25 mars 2019
12 déc. 2013 à 09:53
il faut utiliser retf

--
0
Bonjours,

Je constate que vous avez progressé, je vous transmets tout de même une réponse.

Il existe deux types de CALL 'near' et 'far' le premier permet d'appeler une procédure située dans le même segment de code alors que le second permet de faire faire appel à une procédure située dans un autre segment. De même il existe deux types de RET ( near ) et RETF ( far )
Ceci fonctionne quelque soit le mode 16 ou 32... bien que cet type d'appel sert aussi pour un Task-Switch et un Call-Gate, mais je crois que c'est une autre histoire !

Je ne connais pas virtualbox, mais voici un exemple en MASM Microsoft sous MSDOS.
( à ma conaissance MASM32 ne gere pas les segments, il n'y a qu'un seul '.code' , quant à NASM c'est encore plus ridicule )

code_1 SEGMENT ...

EXTRN intrasegment:FAR
EXTRN procedureexterne:FAR

intersegment PROC NEAR
blablabla
RET ; l'appel devra etre un call near
intersegment ENDP

procedureinterne :
blablabla
RETF ; devra etre appelée par un call far.

debut :
CALL intersegment ; appel dans le meme segment
; seul EIP est empilé
; code op = E8
CALL intrasegment ; appel dans un autre segment que CS en cours
; CS et EIP empilés
; code op = 9A
CALL procedureexterne ; " " " "
; CS et EIP empilés
; code op = 9A
CALL FAR PTR procedureinterne ; appel FAR mais dans le meme segment
; CS et EIP empilés mais inutilement
blablabla

code_1 ENDS debut

;
; code_2 : definition d'une procédure FAR
;
code_2 SEGMENT ...

intrasegment PROC FAR
blablabla
RET ; l'assembleur traduira par un RETF
intrasegment ENDP

PUBLIC intrasegment

code_2 ENDS

;
; code_3 : definition d'une procédure par son etiquette seulement.
;
code_3 SEGMENT ...

procedureexterne :
blablabla
RETF ; un RET far

PUBLIC procedureeexterne

code_3 ENDS


J'avais prévu un .ZIP contenant un exemple sous MSDOS, mais je ne sais pas comment vous le faire parvenir, si vous avez la réponse merci d'avance.
Cordialement.
0
cs_parki Messages postés 75 Date d'inscription mardi 29 juillet 2008 Statut Membre Dernière intervention 25 mars 2019
13 déc. 2013 à 15:39
Bonjour PYRHON,

Merci pour ta réponse détaillée, je vais potasser tout ça...
Et effectivement, je n'ai pas trouvé le moyen de faire parvenir une pièce jointe à un membre. (à priori on ne peut faire qu'un mail privé simple)

Bonne prog.


--
0
Rejoignez-nous