CALL |
Appel un sous-programme |
---|---|
GWBASIC |
Syntaxe
CALL nomdevariable[(listedarguments)] |
Paramètres
Nom | Description |
---|---|
nomdevariable | Ce paramètre permet d'indiquer la variable contenant l'adresse d'appel du sous-programme |
listedarguments | Ce paramètre permet d'indiquer les paramètres d'appel du sous-programme |
Description
Cette commande appel une procédure, lequel est écrit en langage machine.
Algorithme
MODULE CALL(adresse, paramètres...) SI adresse est invalide ALORS Afficher une erreur "Adresse non valide" RETOURNE FIN SI SI des paramètres sont fournis ALORS Préparer les paramètres pour la routine appelée (par exemple, stocker dans des registres ou en mémoire) FIN SI Transférer le contrôle à l'adresse spécifiée Exécuter les instructions de la procédure ou de la routine externe Lorsque la procédure se termine: Reprendre l'exécution du programme principal |
Remarques
- Lorsque la commande «CALL», elle effectue le même traitement qu'on ferait pour un programme compilé, c'est à dire qu'elle empile chacun des paramètres dans la pile du microprocesseur, elle utilise 2 octets par paramètre pour indiquer leur emplacement, ainsi, elle empile dans la pile du microprocesseur l'adresse de segment (registre CS du microprocesseur) et l'adresse de déplacement pour pouvoir faire un retour immédiatement après cette commande. Ensuite, le contrôle est transférer à l'emplacement spécifié par le déplacement et le segment indiqué par l'instruction DEF SEG.
- Le sous-programme en langage machine appelé par cette commande doit connaître d'avance le type de données transmit, car la commande ne fournit aucun moyen de le savoir.
- Cette instruction n'est pas développé pour appeler des sous-programme ou des procédures en GWBASIC, il faut plutôt utiliser la commande GOSUB pour ce genre d'opération.
- L'instruction «CALL» est recommandée pour l'interfaçage des programmes en langage assembleur avec GW-BASIC. Bien que la fonction USR puisse également être utilisée, «CALL» est compatible avec davantage de langages, produit un code source plus lisible et peut transmettre plusieurs arguments.
- L'appel de l'instruction «CALL» provoque les événements suivants :
- Chaque emplacement de paramètre dans la variable est poussé sur la pile. L'emplacement du paramètre est un déplacement de 2 octets dans le segment de données de GW-BASIC.
- Le segment de code d'adresse de retour (CS) et le déplacement sont poussés sur la pile.
- Le contrôle est transféré à la routine utilisateur par l'adresse de segment donnée dans la dernière instruction DEF SEG et le déplacement donné dans le nom de la variable.
- La routine utilisateur a maintenant le contrôle. Les paramètres peuvent être référencés en déplaçant le pointeur de pile (SP) vers le pointeur de base (BP) et en ajoutant un déplacement positif à BP.
- La routine appelée peut détruire le contenu de n'importe quel registre.
- Le programme appelé doit savoir combien de paramètres ont été passés. Les paramètres sont référencés en ajoutant un déplacement positif à BP, en supposant que la routine appelée a déplacé le pointeur de pile actuel dans BP (c'est-à-dire MOV BP,SP).
- Le programme appelé doit connaître le type de variable pour les paramètres numériques passés.
- La routine appelée doit faire un RET n, où n est le nombre de paramètres dans la variable multiplié par 2. Ceci est nécessaire pour ajuster la pile au point au début de la séquence d'appel.
- Les valeurs sont renvoyées à GW-BASIC en incluant dans la liste d'arguments le nom de la variable qui doit recevoir le résultat.
- Si l'argument est une chaîne de caractères, le paramètre de déplacement pointe sur trois octets appelés le descripteur de chaîne de caractères. L'octet 0 du descripteur de chaîne de caractères contient la longueur de la chaîne (0 à 255). Les octets 1 et 2, respectivement, sont les huit bits inférieurs et supérieurs de l'adresse de début de chaîne de caractères dans l'espace de chaîne de caractères.
- Si l'argument est un littéral de chaîne de caractères dans le programme, le descripteur de chaîne de caractères pointe vers le texte du programme. Veillez à ne pas modifier ou détruire un programme de cette manière. Pour éviter des résultats imprévisibles, ajoutez +"" au littéral de chaîne dans le programme, comme dans ce qui suit :
- 20 A$="BASIC"+""
- Les chaînes de caractères peuvent être modifiées par les routines utilisateur, mais leur longueur ne doit pas être modifiée. GW-BASIC ne peut pas effacer correctement les chaînes de caractères si leurs longueurs sont modifiées par des routines externes.
- Pour plus d'informations sur l'instruction CALL et la fonction USR, consultez la page Sous-programmes de langage d'assemblage (code machine).
Cela force le littéral de chaîne à être copié dans l'espace de chaîne. Maintenant, la chaîne peut être modifiée sans affecter le programme.
Exemples
Dans l'exemple suivant, la ligne 100 définit le segment sur l'hexadécimal 2000. ARCH est défini sur zéro afin que l'appel à ARCH exécute le sous-programme à l'emplacement 2000:0 :
- 100 DEF SEG=&H2000
- 110 ARCH=0
- 120 CALL ARCH(A, B$, C)
- .
- .
- .
Dans cette exemple, la séquence suivante du langage d'assembleur 8086 illustre l'accès aux paramètres passés et entreposés dans la variable C :
- PUSH BP
- MOV BP, SP ; Obtient la position actuelle de la pile dans BP.
- MOV BX, 8[BP] ; Obtient l'adresse du descripteur B$.
- MOV CL, [BX] ; Obtient la longueur de B$ en CL.
- MOV DX, 1[BX] ; Obtient l'adresse du texte B$ dans DX.
- .
- .
- .
- MOV SI, 10[BP] ; Obtient l'adresse de A dans SI.
- MOV DI, 6[BP] ; Obtient le pointeur vers C dans DI.
- MOVSW ; Entrepose la variable A dans C.
- RET 6 ; Restaure la pile et les retours.
MOVSW ne copie que deux octets. Ceci est suffisant si les variables A et C sont entières. Quatre octets doivent être copiés s'ils sont en simple précision ; huit octets, s'ils sont en double précision.
Dans cet exemple, la ligne 100 définit le segment sur 2000 hexadécimal. La valeur de la variable ACC est ajoutée à l'adresse en tant que mot bas après que la valeur DEF SEG est décalée de quatre bits vers la gauche (c'est une fonction du microprocesseur, pas de GW-BASIC) . Ici, ACC est défini sur &H7FA, de sorte que l'appel à ACC exécute le sous-programme à l'hexadécimal d'emplacement 2000:7FA (hexadécimal d'adresse absolue 207FA) :
- 100 DEF SEG=&H2000
- 110 ACC=&H7FA
- 120 CALL ACC(A, B$, C)
- .
- .
- .