ZapMan a écrit :Bon, j'ai fait le test et il semble que les adresses que ton code contrôle ne soit pas bricolées, ni à l'intérieur de wait() ni à l'intérieur de wait2(). Pour faire des tests intensifs, j'ai modifié ta formule magique comme suit :
Code : Tout sélectionner
; *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
!MOV eax, dword[esi+20]
!MOV dword[v_adresse1], eax
!MOV dword[v_adresse3], esi
; -------- ICI ---------
If adresse<>adresse1 Or adresse2<>adresse3
MessageRequester("", "Adresse Retour début : "+ Str(adresse)+Chr(10)+"Adresse Retour fin : "+Str(adresse1)+Chr(10)+"esi avant : "+Str(adresse2)+Chr(10)+"esi après : "+Str(adresse3), 16)
EndIf
; *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
et le message ne se déclenche jamais.
Pourtant, j'obtiens toujours des valeurs régulièrement différentes entre WaitAnswer$ et IN dans ma procédure Wait2() (voir posts précédents) et j'obtiens toujours un magnifique plantage de temps à autre (même pas précédé de l'alarme ci-dessus).
J'y perds mon latin.

Je ne vois pas ce que c'est IN et WAIT2, IN est un paramètre de la procedure WAIT2 ? Tu passe en fait WaitAnswer$ dans la procedure WAIT2 ?
ZapMan a écrit :
- Comment expliquer autrement que par un problème de pile le "Ouch !!" de ma procédure Wait2() ?? Note bien que si je fait carrément
et que je compare ensuite WaitAnswer$ (c'est une variable globale) avec le résultat retourné, je continue à avoir des différences. C'est quand même fort, Non ?
Tu utilises plusieurs Thread qui sont susceptibles d'accéder en écriture à WaitAnswer$?
Si oui il y a peut-être un problème (voir la doc PB sur les Thread) sur l'utilisation du même buffer avec plusieurs Thread
ZapMan a écrit :
- L'adresse de retour et l'adresse de la variable retournée sont-elles stockées à deux endroits complètement différents de la pile (ce qui pourrait expliquer que l'une soit abimée et pas l'autre) ?
- Comment comparer l'adresse de la variable de retour de ProcedureReturn (dans Wait()) et juste aprés (dans Wait2()) ?
L'adresse de retour est stockée sur la pile et PB utilise une buffer pour les variables de type chaîne dont il passe l"adresse sur la pile avant d'empiler les parametres.
Je pense que l'adresse de retour peut être modifiée sans que l'adresse du buffer le soit. Sans tracer le code c'est difficile de dire ce qui cloche
Voilà le fonctionnement de PB pour les Procedure PB (ce n'est pas toujours vrai pour les procedures utilisateur qui peuvent passer les paramètres par eax, mais je ne sais pas si PB utilise le passage par eax pour certaines commandes, mais ça ne change rien pour l'adresse de retour)
Un exemple avec une Procedure à 3 paramètres qui retourne une string
Chaque paramètre quel que soit son type (long, byte, word, etc) sera empilé sous la forme d'un mot de 32 bit soit un long
Pour la valeur retournée dans le cas d'une string, eax n'est pas utilisé et PB travaille directement avec son buffer.
Les paramètres vont être empilés dans l'ordre inverse en commençant par Param3 pour finir par param1 puis l'adresse de retour de la procédure va se retrouver sur la pile sous la forme d'un mot de 32 bit (appel court)
Ensuite on arrive dans la Procedure PB, et PB va sauvegarder les registres suivants sur la pile et dans l'odre
ebx, ecx, ebp, esi et edi
maintenant, le pointeur de pile esp pointe sur le dernier élément de la pile , donc sur la valeur sauvegardée de edi
PB attribue au registre esi, la valeur de esp car PB utilise esp pour accéder aux variables locales
Esi lui ne change pas et ne doit pas changer.
Voici comment est la pile jusqu'à ce moment là
Code : Tout sélectionner
PB_Strigbase ; c'est le pointeur du buffer de chaine passé sur la pile
Param3
Param2
Param1
Adresse de retour : esi +20
ebx ; valeur du registre sauvegardée : esi +16
ecx ; valeur du registre sauvegardée : esi +12
ebp ; valeur du registre sauvegardée : esi +8
esi ; valeur du registre sauvegardée : esi +4
edi ; valeur du registre sauvegardée : esi +0
le registre esi pointe sur le dernier élément de la pile soit sur la valeur sauvegardée de edi
Pour remonter sur la pile on ajoute 4 pour chaque paramètre et on a esi+20 pour l'adresse de retour, mais n'ajoute pas 20 directement à esi car esi ne doit pas changer
d'ou on accède à cette valeur comme ça et on utilise soit eax soit edx car PB ne stocke rien temporairement dans ces 2 registres
et il faut sauvegarder cette valeur dans une variable globale
On ajoute v_devant le nom de variable pour y accéder en asm (pour PB) et si c'est un pointeur on y met p_
pour la variable globale
adresse, on y accède avec
v_adresse
pour l'accès en asm, il faut strictement conserver la casse
on stocke comme ceci
J'espère que ça t'aidera