Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur l'Assembleur !

Modérateur : mazertoc

Variables locales sur des pics mid-range
JJE
Passioné
Passioné
Messages : 399
Âge : 83
Enregistré en : novembre 2017
Localisation : Picardie

#1 Message par JJE » ven. 12 avr. 2019 12:16

Bonjour à tous,
Je vais probablement enfoncer une porte ouverte pour beaucoup, mais tant pis, ça m'a distrait des affres de l'I2C :-D
J'ai souvenir d'avoir lu des choses là dessus chez notre maître BigOnOff, mais je n'ai pas réussi à retrouver la (les) page(s). J'ai aussi le souvenir, peut-être mauvais qu'il était resté très discret. J'ai donc eu envie d'écrire ces quelques lignes.
Rappelons qu'une variable locale à un sous-programme est une variable dont on ne s'intéresse pas à la valeur qu'elle a en entrée du sous-programme et dont on ne préoccupe pas de ce qui lui arrivera après la sortie du sous-programme. Il est clair que l'espace qu'elle occupe en zone mémoire peut être utilisée partout où on n'utilise pas le sous-programme, permettant ainsi de gagner un peu d'espace mémoire.
Je pense que beaucoup font comme moi, quand ils écrivent un sous-programme, s'ils ont besoin d'une variable, par exemple un compteur ou un flag, ils se précipitent dans leur CBLOCK et ajoutent la ligne ad-hoc. Dans la majorité des cas, ça marche et c'est sans dommage, mais le jour où on est en manque (de mémoire bien sûr), ce peut être galère de récupérer un ou plusieurs octets.
Le code ci-dessous décrit une méthode simple pour ne pas avoir ces soucis, je crois qu'en l'appliquant systématiquement on serait gagnant pour pas cher.
Peut être n'est-il pas inutile de rappeler que
► Afficher le texte

Revenons à nos moutons. Le programme ci-dessous définit 4 sous-programmes exploitant chacun 2 variables locales, les deux premiers, sont au plus bas niveau (pas de call) le troisième appelle le premier et le quatrième les deux premiers. Cas d'école :-D
► Afficher le texte

Voyons comment sont organisées les variables.
Déclarons d'abord où elles seront installées :

Code : Tout sélectionner

Locales EQU 0x20

Cette ligne permettra de les déplacer en ne modifiant que la valeur de cette étiquette.
Celles du sous-programme ssp1 :

Code : Tout sélectionner


    
; variables locales à SSP1
    CBLOCK  Locales
    V_SSP1  
:   0
    SSP1V1  
:   2 
    SSP1V2  
:   6
    VFIN_SSP1  
: 0
    endc

J'ai ajouté deux lignes, la première n'est pas franchement utile mais permettrait de gérer tout l'espace comme une structure.
La dernière sera utilisée plus loin dans les sous-programmes appelant ssp1.
Les variables locales de ssp2 sont traitées de la même manière. Notons que rien n'interdit d'avoir deux CBLOCK à la même adresse puisque leur seul rôle est de définir la valeur que l'assembleur va donner à la première étiquette du bloc.
Plus intéressante est la description des variables locales de ssp3, rappelons qu'il appelle ssp1 et donc que son espace de variables locales ne doit pas empiéter sur celui de ssp1. c'est le rôle de :

Code : Tout sélectionner


     
; variables locales à SSP3
    
; appelle SSP1
Offset  set VFIN_SSP1
    CBLOCK    Offset

Offset est une variable d'assemblage. Elle ne va générer aucune étiquette dans notre programme mais peut être utilisée dans le code source pour notifier une valeur calculée par l'assembleur. On va donc mettre les variables de ssp3 après celles de ssp1, donc elles ne les chevaucheront pas.
C'est le même chose pour ssp4, en un peu plus compliqué puisque ssp4 appelle les deux sous-programmes ssp1 et ssp2

Code : Tout sélectionner

   
    
; variables locales à SSP4
    
; appelle SSP1 et SSP2
Offset  set VFIN_SSP1
    if   VFIN_SSP2
>Offset
Offset  set VFIN_SSP2
    endif   
; VFIN_SSP2>Offset
    CBLOCK  Offset
    V_SSP4  
:   0
    SSP4V1  
:   2 
    SSP4V2  
:   1
    VFIN_SSP4  
:   0
    endc

Ici, la première adresse disponible est la plus grande de celle disponible pour ssp1 et ssp2. C'est ce que calcule les 4 premières lignes.
Pour finir

Code : Tout sélectionner


Offset  set VFIN_SSP1
    if   VFIN_SSP2
>VFIN_SSP1
Offset  set VFIN_SSP2
    endif   
; VFIN_SSP2>Offset
    if   VFIN_SSP3
>Offset
Offset  set VFIN_SSP3
    endif   
; VFIN_SSP3>Offset
    if   VFIN_SSP4
>Offset
Offset  set VFIN_SSP4
    endif   
; VFIN_SSP4>VFIN_SSP1
    
    if  
(Locales & 0x180)!= ((Offset-1) & 0x180)
        messg   " "
        messg   "Les variables locales franchissent une frontière de bloc"
        messg   " "
    endif ;(Locales & 0x1800)!= ((Locales +Offset-1) & 0x1800)
    
    CBLOCK  Offset
    
: variables globales du programme
    endc

prépare la déclaration du bloc des variables globales.
Noter le test, bien sûr optionnel mais conseillé qui préviendra, à l'assemblage que l'espace des variables locales chevauche une frontière de banque ce qui n'est pas très prudent :oops:
Je suis persuadé, certes sans avoir vraiment mis en oeuvre, que cette méthode facilite bien la gestion des variables locales, à condition de construire ce bloc de code au moment où on crée un sous-programme exploitant des variables locales et au moment où on les définit.
Je conseille cependant de lire ou relire la page 97 de Part2 R4 de BigOnOff
Cordialement

JJE

C'est pas parcequ'on n'a rien à dire qu'il faut fermer sa G....e

Retourner vers « Langage ASM »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 50 invités