Les premiers pas
Pour se lancer en assembleur 370, la méthode la plus accessible consiste à utiliser le système Turnkey MVS de Volker Bandke. Cette distribution pratique intègre l'assembleur gratuit IFOX00 ainsi que de nombreux outils supplémentaires. Une fois que vous avez installé Hercules (un émulateur de mainframe IBM) et le système Turnkey - prenant en charge l'installation des deux - vous pouvez commencer à écrire, assembler et exécuter vos propres programmes en assembleur 370.
Bien que MVS38j (le système d'exploitation inclus dans Turnkey MVS) soit une excellente base, ce n'est pas la seule option. Il existe d'autres systèmes compatibles avec l'architecture S/370 dans le domaine public, comme VM, VSE, ou encore TSS. Cependant, l'approche via la distribution Turnkey est généralement la plus simple pour un débutant, notamment grâce à sa communauté active et sa documentation abondante.
Assemblage, liaison et exécution d'IEFBR14
En général, le premier programme présenté dans un tutoriel de programmation est le programme «Bonjour le monde». Nous avons déjà une introduction à y apporter.
Commençons par quelque chose de plus simple : un programme IEFBR14. Ce programme ne fait presque rien, mais il constitue un bon point de départ pour apprendre l'assembleur 370. Voici le code source de l'assembleur 370 pour IEFBR14 :
Si vous utilisez le système clef en main, vous pouvez saisir ces informations dans un fichier MVS et le soumettre à MVS à l'aide de la tâche ci-dessous. Cette tâche assemble, édite les liens et exécute notre programme assembleur 370 par lots sous MVS :
- //IEFBR14 JOB CLASS=A,MSGCLASS=A,RESTART=ASMF
- //*--------------------------------------------------------------------
- //IEHPROGM EXEC PGM=IEHPROGM
- //SYSPRINT DD SYSOUT=*
- //MVS3380 DD UNIT=3380,VOL=SER=MVS809,DISP=SHR
- //SYSIN DD *
- SCRATCH DSNAME=JMM.S370ASM.LOAD,VOL=3380=MVS809
- UNCATLG DSNAME=JMM.S370ASM.LOAD
- //*--------------------------------------------------------------------
- //ALLOC EXEC PGM=IEFBR14
- //LOAD DD DSN=JMM.S370ASM.LOAD,
- // UNIT=3380,VOL=SER=MVS809,
- // SPACE=(CYL,(20,0,15)),
- // DCB=(RECFM=U,BLKSIZE=32760),
- // DISP=(,CATLG)
- //*--------------------------------------------------------------------
- //ASMF EXEC PGM=IFOX00,REGION=2048K
- //SYSLIB DD DSN=SYS1.AMODGEN,DISP=SHR
- // DD DSN=SYS1.AMACLIB,DISP=SHR
- //SYSUT1 DD DISP=(NEW,DELETE),SPACE=(1700,(900,100)),UNIT=SYSDA
- //SYSUT2 DD DISP=(NEW,DELETE),SPACE=(1700,(600,100)),UNIT=SYSDA
- //SYSUT3 DD DISP=(NEW,DELETE),SPACE=(1700,(600,100)),UNIT=SYSDA
- //SYSPRINT DD SYSOUT=*
- //SYSPUNCH DD DSN=&&OBJ,UNIT=SYSDA,SPACE=(CYL,1),DISP=(,PASS)
- //SYSIN DD *
- IEFBR14 CSECT ,
- SLR 15,15
- BR 14
- END ,
- //*-------------------------------------------------------------------
- //LKED EXEC PGM=IEWL,
- // COND=(5,LT,ASMF),
- // PARM='LIST,MAP,XREF,LET,NCAL,RENT'
- //SYSPRINT DD SYSOUT=*
- //SYSLMOD DD DSN=JMM.S370ASM.LOAD,DISP=SHR
- //* SLIB DD DSN=SYS1.LINKLIB,DISP=SHR
- //SYSUT1 DD UNIT=SYSDA,SPACE=(TRK,(5,5))
- //SYSLIN DD DSN=&&OBJ,DISP=(OLD,DELETE)
- // DD *
- NAME IEFBR14(R)
- //*-------------------------------------------------------------------
- //IEFBR14 EXEC PGM=IEFBR14
- //STEPLIB DD DSN=JMM.S370ASM.LOAD,DISP=SHR
- //
Le résultat de l'exécution de cette tâche apparaît en bas de cette page.
Examinons chaque étape dans l'ordre et voyons ce que chacune d'elles fait. La première étape, IEHPROGM, supprime et décatalogue une bibliothèque si elle existe. Cette étape génère un code retour différent de zéro, que vous pouvez ignorer si la bibliothèque n'existe pas déjà. L'étape suivante, ALLOC, crée la bibliothèque à nouveau. L'étape d'assemblage, ASMF, lit le code source de l'assembleur 370 et produit un ensemble d'objets. L'étape d'édition de lien, LKED, lit l'ensemble d'objets et produit un module de chargement exécutable. L'étape finale, IEFBR14, exécute notre programme assembleur 370 à partir du module de chargement.
IEHPROGM et le programme IEFBR14 d'IBM sont des utilitaires standard ; nous n'en parlerons donc pas davantage.
Nous commençons à examiner ce travail MVS avec l'étape ASMF, exécutant l'assembleur 370 dont le nom du programme est IFOX00.
L'assembleur 370
Exécution d'IFOX00
Examinons brièvement les DDNAME d'IFOX00 :
- Le DDNAME de la bibliothèque SYSLIB est l'emplacement où l'assembleur trouve les macros référencées dans le code source. Notre programme IEFBR14 ne contient aucune référence de macro, mais si c'était le cas, c'est là qu'IFOX00 les chercherait. Nous aborderons les macros ultérieurement, mais pas pour tout de suite. Il suffit de dire qu'elles permettent de générer des instructions assembleur que l'assembleur traitera comme si elles étaient présentes dans votre fichier source.
- SYSUT1, SYSUT2 et SYSUT3 sont des fichiers de travail. Pour l'instant, disons simplement que vous en avez besoin et restons-en là.
- SYSPRINT est l'emplacement où IFOX00 place la liste de l'assembly.
- SYSPUNCH serait l'emplacement où IFOX00 placerait le deck d'objets, en supposant qu'il puisse en produire un.
- SYSIN indique à IFOX00 d'où vient le code source.
Lors de l'exécution de notre JCL, notre assembly reçoit un code de retour zéro de IFOX00, ce qui signifie que le code source a été assemblé correctement. Le message de sortie de notre tâche indique :
| IEF142I IEFBR14 ASMF - STEP WAS EXECUTED - COND CODE 0000 |
Formatage du code source de l'assembleur 370
L'assembleur MVS38j IFOX00, la commande VM «assemble» et la plupart des autres assembleurs 370 que vous rencontrerez ont des exigences assez standard concernant le formatage de votre programme source.
La norme de l'assembleur 370 stipule que les enregistrements source doivent avoir une longueur de 80 octets. Les ensembles de données du code source MVS peuvent être bloqués ou débloqués ; vous souhaiterez probablement les bloquer à l'aide d'attributs DCB tels que RECFM=FB,LRECL=80,BLKSIZE=3200.
Le code source de l'assembleur 370 est généralement en majuscules, bien que les commentaires puissent généralement être en majuscules et en minuscules. Si vous utilisez un assembleur plus moderne, tel que HLASM, la majeure partie du code source peut être en majuscules et en minuscules.
Les instructions source se présentent sous plusieurs formes : commentaires, instructions assembleur et instructions. Les commentaires contiennent un astérisque (*) dans la première colonne. Les colonnes sont généralement numérotées à partir de 1. Presque tout est possible pour les lignes de commentaires : elles sont libres.
Les instructions sont faciles à identifier : elles sont documentées dans les POP et le REFSUM. Tout le reste est une instruction assembleur, fournissant des instructions à l'assembleur.
Chaque instruction assembleur S/370 est divisée en plusieurs champs (relativement libres) : étiquette, code opération, opérande(s), commentaires, colonne de continuation et numéros de séquence.
- Les étiquettes sont facultatifs et, s'ils sont présents, doivent commencer dans la première colonne. Ils servent à définir des emplacements symboliques, comme un emplacement de branchement. En assembleur 370, les étiquettes peuvent avoir une longueur de un à huit octets. Pour l'instant, vous pouvez considérer IEFBR14 comme un étiquette, bien que nous le décrivions plus en détail ultérieurement.
- Les opcodes doivent être précédés et suivis d'un ou plusieurs espaces. Normalement, les opcodes commencent dans la colonne 10, mais il s'agit plus d'une convention que d'une obligation. Dans le programme IEFBR14, les opcodes sont SLR (instruction de soustraction de registre logique) et BR (instruction de branchement de registre).
- Les opérandes sont séparés de l'opcode par au moins un espace. Par convention, la plupart des opérandes commencent dans la colonne 16. Dans le programme IEFBR14, «15» et «14» sont des opérandes. Dans l'instruction SLR, notez qu'il y a plusieurs opérandes, chacun séparé par une virgule. Vous pouvez indiquer l'omission d'opérandes par une virgule (,), comme je l'ai fait dans le programme IEFBR14 pour les instructions CSECT et END.
- Les commentaires peuvent également apparaître sur une instruction ou une instruction assembleur, et doivent être séparés du dernier opérande par au moins un espace. La convention est moins standard ici, mais la plupart des cours d'introduction à l'assembleur indiquent de commencer les commentaires à la colonne 35. Attention toutefois à la longueur des commentaires, car si vous avez un caractère non vide dans la colonne 72, l'assembleur pensera que vous souhaitez que la ligne source suivante soit interprétée comme une ligne de continuation. La même syntaxe s'applique aux opérandes.
- Tout caractère non vide dans la colonne 72 indique à l'assembleur que l'instruction suivante est une ligne de continuation. Les continuations peuvent être continues, ce qui permet d'avoir plusieurs lignes avec des colonnes 72 non vides apparaissant consécutivement.
- Les colonnes 73 à 80 sont réservées aux «numéros de séquence». Ces numéros de séquence ont deux fonctions principales, dont l'une est obsolète. Premièrement, à l'époque où les programmes étaient perforés sur des cartes physiques, si vous laissiez tomber l'ensemble de cartes et le dispersiez, les numéros de séquence vous aidaient à le reconstituer dans le bon ordre. Deuxièmement, si vous insérez le code source du programme dans un jeu de données, les numéros de séquence servent de point de référence pour un utilitaire de mise à jour tel que IEBUPDTE. Les numéros de séquence sont facultatifs.
Si vous utilisez le système clef en main, nous croyons qu'IFOX00 intègre le usermod de Greg Price, permettant l'affichage de lignes source entièrement vides dans le fichier source. Sans le usermod de Greg Price ou un outil similaire, IFOX00 se plaindrait lorsqu'il verrait une ligne entièrement vide.
Sortie assembleur 370
Lorsque nous exécutons IFOX00, il produit la sortie ci-dessous. La sortie d'impression MVS est généralement plus large que celle affichée par la plupart des navigateurs Web ; il faut donc faire défiler la page vers la droite et la gauche pour la voir en entier. L'assembleur numérote ses pages de sortie à l'extrême droite.
|
EXTERNAL SYMBOL DICTIONARY PAGE 1 SYMBOL TYPE ID ADDR LENGTH LDID ASM 0201 02.32 04/26/76 IEFBR14 SD 0001 000000 000004 PAGE 2 LOC OBJECT CODE ADDR1 ADDR2 STMT SOURCE STATEMENT ASM 0201 02.32 04/26/76 000000 1 IEFBR14 CSECT , 000000 1FFF 2 SLR 15,15 000002 07FE 3 BR 14 4 END , ASSEMBLER DIAGNOSTICS AND STATISTICS PAGE 3 ASM 0201 02.32 04/26/76 NO STATEMENTS FLAGGED IN THIS ASSEMBLY HIGHEST SEVERITY WAS 0 OPTIONS FOR THIS ASSEMBLY ALIGN, ALOGIC, BUFSIZE(STD), DECK, ESD, FLAG(0), LINECOUNT(55), LIST, NOMCALL, YFLAG, WORKSIZE(2097152) NOMLOGIC, NONUMBER, NOOBJECT, NORENT, RLD, NOSTMT, NOLIBMAC, NOTERMINAL, NOTEST, XREF(SHORT) SYSPARM() WORK FILE BUFFER SIZE/NUMBER =19066/ 1 TOTAL RECORDS READ FROM SYSTEM INPUT 4 TOTAL RECORDS READ FROM SYSTEM LIBRARY 0 TOTAL RECORDS PUNCHED 3 TOTAL RECORDS PRINTED 22 |
Déchiffrer la sortie de l'assembleur
La majeure partie de cette section sur le déchiffrement de la sortie de l'assembleur est également traitée dans le Guide du langage assembleur 370.
Page 1, Dictionnaire des symboles externes
- La première chose que nous voyons est le Dictionnaire des symboles externes, étant une carte des «symboles externes» dans l'ensemble d'objets de sortie. Vous vous souvenez que nous avons appelé IEFBR14 une sorte d'étiquette ? Plus précisément, il s'agit d'un symbole externe. Externe dans le sens où le symbole est visible en dehors du fichier source. Si nous devions écrire un autre programme, nous pourrions appeler IEFBR14 en faisant référence au symbole externe. Lorsque nous transmettons l'ensemble d'objets IEFBR14 à l'éditeur de liens, nous produirons un module de chargement, et le symbole IEFBR14 y sera également visible.
- Il n'y a qu'un seul symbole externe dans notre programme, IEFBR14, dont le type est SD (Définition de Symbole). Il existe plusieurs autres types de symboles externes, tels que ER (Référence Externe), LD (Définition Locale), WX (Externe Faible), XD (Externe, issu d'une instruction DXD) et peut-être d'autres. L'intérêt de les mentionner est que l'Éditeur de Liens les prend en compte et qu'ils sont importants pour la construction de votre module de chargement.
- L'assembleur attribue à chaque symbole externe un numéro d'identification unique pour chaque assemblage. À moins de démanteler un éditeur de Liens ou un programme assembleur, ce numéro d'identification n'est généralement pas important.
- Le champ ADDR indique le décalage relatif au paquet d'objets où le symbole est défini. IEFBR14 commence à zéro, le premier élément du paquet d'objets.
- Le champ LENGTH indique la longueur en octets (hexadécimaux) du code contenu dans la «section». Dans le cas d'IEFBR14, la section est une CSECT (Control Section). Un autre type de section courant est la DSECT (Dummy Section). La différence entre les deux réside dans le fait qu'une CSECT consomme de l'espace d'entreposage, tandis qu'une DSECT décrit un entreposage situé ailleurs. Une DSECT ressemble beaucoup aux films de superposition utilisés sur les projecteurs de salle de classe : conceptuellement, on superpose la DSECT à un emplacement d'entreposage et on peut ensuite y faire référence grâce à ses étiquettes.
- Le champ LDID est vide car nous n'avons défini aucun LD. Les LD sont en fait des points d'entrée alternatifs dans votre programme, définis par l'instruction assembleur ENTRY, que nous n'avons pas encore abordée. Si nous avions défini un autre point d'entrée, le LDID ferait référence à l'ID de la CSECT dans laquelle il a été défini, et aurait un décalage (ADDR) correspondant à l'emplacement relatif au deck d'objets où le LD a été défini. Vous pouvez immédiatement oublier cette petite information pour le moment.
Page 2, la liste des programmes
- Comme IEFBR14 est si petit, il ne s'y passe pas grand-chose. Regardons les colonnes de cette page.
- LOC est l'emplacement des définitions d'entreposage, étant le rôle principal de l'assembleur. La tâche principale de l'assembleur est de produire un ensemble d'objets contenant suffisamment d'informations pour que l'éditeur de liaison puisse générer un module de chargement (contenant vos instructions/données et leur emplacement). Ce module de chargement contient suffisamment d'informations pour que le système d'exploitation stocke vos instructions afin qu'elles puissent être exécutées.
- Notez que l'instruction CSECT IEFBR14 commence à LOC 000000 (hex) et que l'instruction SLR 15,15 commence également à LOC 000000. L'instruction CSECT est une instruction assembleur et ne consomme pas d'espace de stockage dans votre programme. Notez également que le numéro STMT de l'instruction CSECT est 1. Chaque ligne de code source se voit attribuer un numéro STMT, y compris les lignes générées par les macros. Si nous rencontrions des erreurs d'assemblage, la section «ASSEMBLER DIAGNOSTICS AND STATISTICS» du listing (en sautant) ferait référence à ces numéros STMT. Dans un listing de programmes volumineux, cela permet de localiser plus facilement l'erreur. Pour notre programme de quatre lignes, STMT n'a pas beaucoup d'importance.
- Le CODE OBJET indique les valeurs hexadécimales que le processeur exécutera lors de l'exécution de votre programme, ou les données que vous définissez dans votre programme. Le code objet de l'instruction SLR 15,15 est X'1FFF' et celui de l'instruction BR 14 est X'07FE'. La liste ne permet pas de le savoir, mais les instructions S/370 ont toujours une longueur de 2, 4 ou 6 octets. Il se trouve que les deux instructions S/370 de notre programme font 2 octets.
- Les colonnes ADDR1 et ADDR2 ne contiennent aucune donnée, car nous n'avons fait référence à aucun emplacement de stockage dans notre programme. Si tel était le cas, ces champs contiendraient les décalages relatifs des emplacements de stockage. Nous aborderons bientôt le stockage, et je vous expliquerai la signification du terme «relatif» dans ce cas.
- L'instruction END n'a pas non plus généré de code objet, car il s'agit d'une instruction assembleur (et non d'une instruction). Son but est d'indiquer à l'éditeur de liaison le point d'entrée par défaut (symbole externe) du programme. Ce point d'entrée par défaut peut être remplacé par l'éditeur de liaison avec l'instruction ENTRY au moment de la liaison.
- Comme vous pouvez le constater ci-dessus, l'assembleur et l'éditeur de liaison travaillent en étroite collaboration pour produire votre module de chargement. Dans MVS, il existe d'autres moyens d'exécuter des programmes que les modules de chargement, mais je doute d'avoir quoi que ce soit à dire à ce sujet, si ce n'est pour mentionner l'existence d'un chargeur. Concernant le matériel S/370 lui-même, il existe également un processus appelé IPL (Initial Program Load) qui permet d'exécuter un programme; l'IPL sert à démarrer le système d'exploitation lui-même. Une fois que nous aurons acquis quelques notions de base sur l'assembleur, nous discuterons probablement davantage de l'IPL.
Page 3, DIAGNOSTICS ET STATISTIQUES ASSEMBLEUR
- Aucune instruction marquée dans cet assemblage est une bonne nouvelle. Si elle est signalée, l'assembleur est préoccupé par un élément de votre code source; il «marque» ces lignes source afin que vous sachiez qu'il faut les examiner pour détecter d'éventuels problèmes. Si l'assembleur est vraiment en colère contre vous, il ne construira pas correctement votre code objet ; dans certains cas, il ajoutera simplement des X'00 dans le paquet d'objets lorsque vous l'aurez vraiment embrouillé.
- Dans les architectures S/360, S/370, S/390 et z/Arch, X'00' n'est pas considéré comme une instruction exécutable ; votre programme s'arrêtera donc si vous tentez d'exécuter les X'00. Par conséquent, il est conseillé de toujours vérifier les codes de retour de l'assembleur pour vous assurer que votre programme a été construit comme prévu (ou espéré).
- Les codes de retour de l'assembleur commencent généralement à 4 et augmentent par incréments de 4. Plus le nombre est élevé, plus l'erreur est grave. Le code de retour 4 est considéré comme un avertissement et peut être ignoré ; tout le reste doit normalement être corrigé avant d'exécuter votre programme.
- Il y a d'autres informations sur cette page, mais je n'ai rien à dire à ce sujet pour le moment.
Nous examinons ensuite l'étape LKED, exécutant l'éditeur de liaison S/370 dont le nom de programme est IEWL. L'éditeur de liaison est parfois appelé LKED, abréviation de LinKage EDitor.
L'éditeur de liaison S/370
Exécution d'IEWL
Examinons brièvement les noms de domaine (DDNAME) d'IEWL.
- SYSPRINT est la liste des modifications de liaison.
- SYSLMOD est le module de chargement résultant, s'il a été généré.
- SYSUT1 est un fichier de travail.
- SYSLIN est l'entrée principale. Les paquets d'objets d'entrée et les instructions de contrôle peuvent être présents sur SYSLIN.
Sortie de l'éditeur de liaison S/370
|
F64-LEVEL LINKAGE EDITOR OPTIONS SPECIFIED LIST,MAP,XREF,LET,NCAL,RENT DEFAULT OPTION(S) USED - SIZE=(165888,55296) IEW0000 NAME IEFBR14(R) CROSS REFERENCE TABLE CONTROL SECTION ENTRY NAME ORIGIN LENGTH NAME LOCATION NAME LOCATION NAME LOCATION NAME LOCATION IEFBR14 00 4 ENTRY ADDRESS 00 TOTAL LENGTH 8 ****IEFBR14 NOW REPLACED IN DATA SET AUTHORIZATION CODE IS 0. **MODULE HAS BEEN MARKED REENTERABLE, AND REUSABLE. |
Décryptage de la sortie de l'éditeur de liaison
Examinons brièvement la sortie de l'éditeur de liaison. Nous ne pouvons pas expliquer l'éditeur de liaison MVS en détail, car il mériterait un tutoriel à lui seul. Vous remarquerez peut-être que le niveau F de l'assembleur correspond à celui de l'éditeur de liaison. C'est souvent le cas ; ils ont tendance à rester synchronisés, car ils sont très dépendants l'un de l'autre.
Si vous vous reportez au JCL MVS utilisé pour exécuter le programme IEWL, vous remarquerez que nous avons passé des valeurs PARM ; c'est là que l'éditeur de liaison récupère ses options. Les OPTIONS LKED étaient : LIST (afficher les instructions d'entrée de SYSLIN), MAP (produire une table de chargement de module), XREF (produire une référence croisée), LET (marquer le module comme exécutable même s'il contient des erreurs), NCAL (ne pas utiliser la fonction d'appel automatique pour résoudre les symboles non résolus) et RENT (marquer le module comme réentrant). Nous ne mentionnons que quelques-unes de ces options.
Si vous omettez NCAL, le DDNAME de la bibliothèque SYSLIB de l'étape LKED sera ouvert et la recherche de symboles externes pouvant être utilisés pour satisfaire aux exigences d'entrée SYSLIN de LKED sera effectuée. Tout d'abord, SYSLIN est l'emplacement où nous avons placé l'ensemble d'objets de sortie de l'assembleur ; LKED l'a lu comme entrée principale. Nous avons concaténé un jeu de données intégré (DD *) après le jeu d'objets et fourni une instruction NAME avec l'option replace (R). Cette instruction NAME spécifie le nom du module de chargement qui sera stocké dans le répertoire de la bibliothèque de chargement. L'option replace indique qu'il est possible de remplacer le module s'il existe déjà. Notez que les instructions de contrôle LKED ne peuvent pas commencer dans la colonne 1 (pour une raison obscure et probablement inutile), nous avons donc placé le NAME dans la colonne 2. L'éditeur de liens possède son propre manuel, et il serait utile d'en avoir un, ainsi que le manuel des messages LKED.
Il y a maintenant deux colonnes principales : CONTROL SECTION et ENTRY. Nous savons déjà ce que sont une CSECT ou un élément similaire, et un point d'entrée. Sous chacune de ces deux colonnes principales se trouvent des sous-colonnes (faute d'un meilleur terme).
La section de contrôle NAME est notre vieille amie la CSECT IEFBR14. Vient ensuite la colonne ORIGIN, représentant un autre décalage ; cette fois, il s'agit du décalage par rapport au début du module de chargement. LENGTH a la même signification que la longueur du dictionnaire de symboles externes de l'assembleur. Si la longueur d'une CSECT n'est pas divisible par 8, LKED arrondit la CSECT suivante à la limite de mot double supérieure.
Ce comportement de LKED est dû à certaines instructions S/370 nécessitant que certaines de leurs données soient alignées sur une limite de mot double (c'est-à-dire une adresse d'entreposage divisible par 8). Si LKED n'effectuait pas cet alignement de CSECT, lorsque l'assembleur produirait son paquet d'objets afin de placer une définition d'entreposage sur une limite de double mot, la zone de données pourrait ne pas se retrouver sur une limite de double mot dans le programme une fois chargée en entreposage. Vous constaterez donc de temps à autre un « espace mort » dans vos modules de chargement pour satisfaire à cette exigence. Par ailleurs, l'alignement de double mot est la raison pour laquelle le service MVS GETMAIN (allocation d'entreposage) fournit de l'entreposage sur une limite de double mot.
Après avoir lu toutes les entrées, LKED attribue l'adresse d'entrée (là encore un décalage relatif du module de chargement) au module de chargement. Notre instruction END ne spécifiait pas d'adresse de point d'entrée et nous n'avons pas fourni d'instruction ENTRY à LKED ; LKED utilise donc son point d'entrée par défaut, étant la première CSECT rencontrée dans l'entrée principale. Dans ce cas, il s'agit de la CSECT IEFBR14.
La longueur totale du module de chargement est de 8, comme l'exige l'alignement des CSECT (même s'il n'y en a qu'une seule).
****IEFBR14 NOW REPLACED IN DATASET signifie que LKED a respecté notre option (R) sur l'instruction NAME. LKED place le module de chargement de sortie sur le DDNAME SYSLMOD.
Le CODE D'AUTORISATION est un sujet un peu plus avancé. Nous nous contenterons de préciser que MVS fournit une fonction d'autorisation appelée APF (Authorized Program Facility), permettant à un programme d'agir comme une extension du système d'exploitation MVS. Ces programmes sont appelés «Programmes Autorisés» et sont marqués comme candidats à l'octroi de ces privilèges spéciaux en les liant à un code d'autorisation différent de zéro. MVS effectue des vérifications supplémentaires avant d'accorder ce privilège, notamment en vérifiant que le module de chargement provient d'une bibliothèque APF, ce que nous n'aborderons pas maintenant.
MODULE HAS BEEN MARKED... quelques trucs. Vous vous souvenez de notre option LOCATION ? Eh bien, réentrant implique réutilisable, et LKED le précise simplement.
Qu'est-ce qu'un programme réentrant ? C'est un programme pouvant être exécuté par plusieurs tâches sans nécessiter de copie physique supplémentaire. MVS en fait tout un plat, car les techniques de programmation réentrante permettent à MVS (et aux programmes utilisateur) de fournir leurs services avec moins de surcharge. La définition la plus simple (bien que peu précise) est que les programmes réentrants ne modifient pas leur propre stockage. Nous laisserons la définition de «tâche» pour un autre jour.
Sortie IEFBR14
Voilà la sortie de l'éditeur de liens. Où est donc la sortie IEFBR14 ? Il n'y en a pas. Notre programme IEFBR14 n'a ouvert aucun ensemble de données, n'a écrit aucune sortie... rien.
Si vous jetez un oeil à la sortie de la tâche ci-dessous, vous verrez :
| IEF142I IEFBR14 IEFBR14 - STEP WAS EXECUTED - COND CODE 0000 |
Cela signifie que notre programme IEFBR14 a généré un code de retour nul, ce qui signifie traditionnellement «tout s'est bien passé, aucune erreur».
Comment IEFBR14 a-t-il fourni ce code de retour à MVS ? Pour répondre à cette question, il nous faudra en savoir plus sur l'exécution du programme.
Sortie de la tâche MVS
L'exemple suivant présente l'intégralité de la sortie d'impression MVS générée par nos tâches d'assemblage, d'édition liée et d'exécution :
|
J E S 2 J O B L O G 05.11.01 JOB 12 $HASP373 IEFBR14 STARTED - INIT 1 - CLASS A - SYS BSP1 05.11.01 JOB 12 IEF403I IEFBR14 - STARTED - TIME=05.11.01 05.11.01 JOB 12 IEFBR14 ASMF IFOX00 RC= 0000 05.11.01 JOB 12 IEFBR14 LKED IEWL RC= 0000 05.11.02 JOB 12 IEFBR14 IEFBR14 IEFBR14 RC= 0000 05.11.02 JOB 12 IEF404I IEFBR14 - ENDED - TIME=05.11.02 05.11.02 JOB 12 $HASP395 IEFBR14 ENDED ------ JES2 JOB STATISTICS ------ 26 APR 76 JOB EXECUTION DATE 44 CARDS READ 181 SYSOUT PRINT RECORDS 0 SYSOUT PUNCH RECORDS 0.01 MINUTES EXECUTION TIME 1 //IEFBR14 JOB CLASS=A,MSGCLASS=A,RESTART=ASMF JOB 12 ***-------------------------------------------------------------------- 2 //IEHPROGM EXEC PGM=IEHPROGM 3 //SYSPRINT DD SYSOUT=* 4 //MVS3380 DD UNIT=3380,VOL=SER=MVS809,DISP=SHR 5 //SYSIN DD * ***-------------------------------------------------------------------- 6 //ALLOC EXEC PGM=IEFBR14 7 //LOAD DD DSN=JMM.S370ASM.LOAD, // UNIT=3380,VOL=SER=MVS809, // SPACE=(CYL,(20,0,15)), // DCB=(RECFM=U,BLKSIZE=32760), // DISP=(,CATLG) ***-------------------------------------------------------------------- 8 //ASMF EXEC PGM=IFOX00,REGION=2048K 9 //SYSLIB DD DSN=SYS1.AMODGEN,DISP=SHR 10 // DD DSN=SYS1.AMACLIB,DISP=SHR 11 //SYSUT1 DD DISP=(NEW,DELETE),SPACE=(1700,(900,100)),UNIT=SYSDA 12 //SYSUT2 DD DISP=(NEW,DELETE),SPACE=(1700,(600,100)),UNIT=SYSDA 13 //SYSUT3 DD DISP=(NEW,DELETE),SPACE=(1700,(600,100)),UNIT=SYSDA 14 //SYSPRINT DD SYSOUT=* 15 //SYSPUNCH DD DSN=&&OBJ,UNIT=SYSDA,SPACE=(CYL,1),DISP=(,PASS) 16 //SYSIN DD * ***------------------------------------------------------------------- 17 //LKED EXEC PGM=IEWL, // COND=(5,LT,ASMF), // PARM='LIST,MAP,XREF,LET,NCAL,RENT' 18 //SYSPRINT DD SYSOUT=* 19 //SYSLMOD DD DSN=JMM.S370ASM.LOAD,DISP=SHR *** SLIB DD DSN=SYS1.LINKLIB,DISP=SHR 20 //SYSUT1 DD UNIT=SYSDA,SPACE=(TRK,(5,5)) 21 //SYSLIN DD DSN=&&OBJ,DISP=(OLD,DELETE) 22 // DD * ***------------------------------------------------------------------- 23 //IEFBR14 EXEC PGM=IEFBR14 24 //STEPLIB DD DSN=JMM.S370ASM.LOAD,DISP=SHR // IEF236I ALLOC. FOR IEFBR14 ASMF IEF237I 248 ALLOCATED TO SYSLIB IEF237I 248 ALLOCATED TO IEF237I 149 ALLOCATED TO SYSUT1 IEF237I 14A ALLOCATED TO SYSUT2 IEF237I 190 ALLOCATED TO SYSUT3 IEF237I JES2 ALLOCATED TO SYSPRINT IEF237I 14B ALLOCATED TO SYSPUNCH IEF237I JES2 ALLOCATED TO SYSIN IEF142I IEFBR14 ASMF - STEP WAS EXECUTED - COND CODE 0000 IEF285I SYS1.AMODGEN KEPT *--------0 IEF285I VOL SER NOS= MVSDLB. IEF285I SYS1.AMACLIB KEPT *--------0 IEF285I VOL SER NOS= MVSDLB. IEF285I SYS76117.T051101.RA000.IEFBR14.R0000002 DELETED *--------8 IEF285I VOL SER NOS= SMP001. IEF285I SYS76117.T051101.RA000.IEFBR14.R0000003 DELETED *--------7 IEF285I VOL SER NOS= SMP002. IEF285I SYS76117.T051101.RA000.IEFBR14.R0000004 DELETED *--------7 IEF285I VOL SER NOS= WORK03. IEF285I JES2.JOB00012.SO0105 SYSOUT IEF285I SYS76117.T051101.RA000.IEFBR14.OBJ PASSED *--------3 IEF285I VOL SER NOS= SMP003. IEF285I JES2.JOB00012.SI0102 SYSIN IEF373I STEP /ASMF / START 76117.0511 IEF374I STEP /ASMF / STOP 76117.0511 CPU 0MIN 00.31SEC SRB 0MIN 00.01SEC VIRT 2048K SYS 208K ************************************************************************************************************************************ * 3. Jobstep of job: IEFBR14 Stepname: ASMF Program name: IFOX00 Executed on 26.04.76 from 05.11.01 to 05.11.01 * * elapsed time 00:00:00,50 CPU-Identifier: BSP1 Page-in: 0 * * CPU time 00:00:00,32 Virtual Storage used: 2048K Page-out: 0 * * corr. CPU: 00:00:00,32 CPU time has been corrected by 1 / 1,0 multiplier * * * * I/O Operation * * Number of records read via DD * or DD DATA: 4 * * 248.......0 248.......0 149.......8 14A.......7 190.......7 DMY.......0 14B.......3 DMY.......0 * * * * Charge for step (w/o SYSOUT): 0,53 * ************************************************************************************************************************************ IEF236I ALLOC. FOR IEFBR14 LKED IEF237I JES2 ALLOCATED TO SYSPRINT IEF237I 181 ALLOCATED TO SYSLMOD IEF237I 240 ALLOCATED TO SYS00031 IEF237I 149 ALLOCATED TO SYSUT1 IEF237I 14B ALLOCATED TO SYSLIN IEF237I JES2 ALLOCATED TO IEF142I IEFBR14 LKED - STEP WAS EXECUTED - COND CODE 0000 IEF285I JES2.JOB00012.SO0106 SYSOUT IEF285I JMM.S370ASM.LOAD KEPT *--------9 IEF285I VOL SER NOS= MVS809. IEF285I SYS1.UCAT.TSO KEPT *--------0 IEF285I VOL SER NOS= PUB000. IEF285I SYS76117.T051101.RA000.IEFBR14.R0000005 DELETED *--------0 IEF285I VOL SER NOS= SMP001. IEF285I SYS76117.T051101.RA000.IEFBR14.OBJ DELETED *--------4 IEF285I VOL SER NOS= SMP003. IEF285I JES2.JOB00012.SI0103 SYSIN IEF373I STEP /LKED / START 76117.0511 IEF374I STEP /LKED / STOP 76117.0511 CPU 0MIN 00.07SEC SRB 0MIN 00.01SEC VIRT 196K SYS 212K ************************************************************************************************************************************ * 4. Jobstep of job: IEFBR14 Stepname: LKED Program name: IEWL Executed on 26.04.76 from 05.11.01 to 05.11.01 * * elapsed time 00:00:00,18 CPU-Identifier: BSP1 Page-in: 0 * * CPU time 00:00:00,08 Virtual Storage used: 196K Page-out: 0 * * corr. CPU: 00:00:00,08 CPU time has been corrected by 1 / 1,0 multiplier * * * * I/O Operation * * Number of records read via DD * or DD DATA: 1 * * DMY.......0 181.......9 240.......0 149.......0 14B.......4 DMY.......0 * * * * Charge for step (w/o SYSOUT): 0,13 * ************************************************************************************************************************************ IEF236I ALLOC. FOR IEFBR14 IEFBR14 IEF237I 181 ALLOCATED TO STEPLIB IEF237I 240 ALLOCATED TO SYS00033 IEF142I IEFBR14 IEFBR14 - STEP WAS EXECUTED - COND CODE 0000 IEF285I JMM.S370ASM.LOAD KEPT *--------0 IEF285I VOL SER NOS= MVS809. IEF285I SYS1.UCAT.TSO KEPT *--------0 IEF285I VOL SER NOS= PUB000. IEF373I STEP /IEFBR14 / START 76117.0511 IEF374I STEP /IEFBR14 / STOP 76117.0511 CPU 0MIN 00.01SEC SRB 0MIN 00.00SEC VIRT 8K SYS 192K ************************************************************************************************************************************ * 5. Jobstep of job: IEFBR14 Stepname: IEFBR14 Program name: IEFBR14 Executed on 26.04.76 from 05.11.02 to 05.11.02 * * elapsed time 00:00:00,09 CPU-Identifier: BSP1 Page-in: 0 * * CPU time 00:00:00,01 Virtual Storage used: 8K Page-out: 0 * * corr. CPU: 00:00:00,01 CPU time has been corrected by 1 / 1,0 multiplier * * * * I/O Operation * * Number of records read via DD * or DD DATA: 0 * * 181.......0 240.......0 * * * * Charge for step (w/o SYSOUT): 0,01 * ************************************************************************************************************************************ IEF375I JOB /IEFBR14 / START 76117.0511 IEF376I JOB /IEFBR14 / STOP 76117.0511 CPU 0MIN 00.39SEC SRB 0MIN 00.02SEC EXTERNAL SYMBOL DICTIONARY PAGE 1 SYMBOL TYPE ID ADDR LENGTH LDID ASM 0201 05.11 04/26/76 IEFBR14 SD 0001 000000 000004 PAGE 2 LOC OBJECT CODE ADDR1 ADDR2 STMT SOURCE STATEMENT ASM 0201 05.11 04/26/76 000000 1 IEFBR14 CSECT , 000000 1FFF 2 SLR 15,15 000002 07FE 3 BR 14 4 END , ASSEMBLER DIAGNOSTICS AND STATISTICS PAGE 3 ASM 0201 05.11 04/26/76 NO STATEMENTS FLAGGED IN THIS ASSEMBLY HIGHEST SEVERITY WAS 0 OPTIONS FOR THIS ASSEMBLY ALIGN, ALOGIC, BUFSIZE(STD), DECK, ESD, FLAG(0), LINECOUNT(55), LIST, NOMCALL, YFLAG, WORKSIZE(2097152) NOMLOGIC, NONUMBER, NOOBJECT, NORENT, RLD, NOSTMT, NOLIBMAC, NOTERMINAL, NOTEST, XREF(SHORT) SYSPARM() WORK FILE BUFFER SIZE/NUMBER =19066/ 1 TOTAL RECORDS READ FROM SYSTEM INPUT 4 TOTAL RECORDS READ FROM SYSTEM LIBRARY 0 TOTAL RECORDS PUNCHED 3 TOTAL RECORDS PRINTED 22 F64-LEVEL LINKAGE EDITOR OPTIONS SPECIFIED LIST,MAP,XREF,LET,NCAL,RENT DEFAULT OPTION(S) USED - SIZE=(165888,55296) IEW0000 NAME IEFBR14(R) CROSS REFERENCE TABLE CONTROL SECTION ENTRY NAME ORIGIN LENGTH NAME LOCATION NAME LOCATION NAME LOCATION NAME LOCATION IEFBR14 00 4 ENTRY ADDRESS 00 TOTAL LENGTH 8 ****IEFBR14 NOW REPLACED IN DATA SET AUTHORIZATION CODE IS 0. **MODULE HAS BEEN MARKED REENTERABLE, AND REUSABLE. |