Программа z/OS Assembler странно зацикливается, если атрибуты выходного файла изменились

ОК - Я уверен, что делаю что-то глупое, но я этого не вижу.

У меня есть небольшой образец программы на ассемблере, который я собираюсь предоставить коллеге, который хочет изучить ассемблер, но в нем есть странная ошибка, которую мне нужно сначала исправить. .

Когда выходной файл (DDNAME SYSUT2) является временным 80-байтовым файлом, он работает нормально. Измените SYSUT2 на SYSOUT=*, и он зациклится на «Закрывающемся файле» WTO.

Итак, вот программа:

//C.SYSLIB   DD  DISP=SHR,DSN=SYS1.MACLIB                               
//           DD  DISP=SHR,DSN=SYS1.MODGEN                               
//           DD  DISP=SHR,DSN=SYS1.ASM.SASMMAC2                         
//*          DD  DISP=SHR,DSN=JOCS065.STEVE.SOURCE                      
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  4 Line(s) not Displayed 
         TITLE  'TEST PROGRAM'                                          
SYMBOLIC CSECT                                                          
         ASMDREG                      .Register equates                 
         SAVE  (14,12),,'SYMBOLIC PARM SUB &SYSDATE &SYSTIME'           
                                                                        
         LR    R12,R15                .R12 -> entry point               
         USING SYMBOLIC,R12           .Establish addressability         
* Get the parm passed                                                   
         L     R1,0(R1)               .R1 -> parm                       
         LTR   R1,R1                  .Is there one?                    
         BZ    RETURN                 .No - return                      
* We have a parm                                                        
         LH    R2,0(R1)               .R2 = PARM LENGTH                 
         LTR   R2,R2                  .parm length = 0?                 
         BZ    RETURN                 . Yes - return                    
* And the parm has length                                               
         BCTR  R2,0                   .Decrement length for move        
         EX    R2,SETOUT              .Move parm to output              
* Open output file and write parm to output                             
         LA    R4,FILE1            .R4 -> DCB for output file.          
         USING IHADCB,R4           .Establish addressability            
         OPEN  (FILE1,OUTPUT)      .Open log file                       
         TM    DCBOFLGS,DCBOFOPN   .Open successful ?                   
         BZ    BADOPEN             .No - go to error routine            
         WTO   'SIMSG001 OPEN successful.'                              
         DROP  R4                                                       
         WTO   'SIMSG003 writing to file'                               
         PUT   FILE1,OUTREC           .PUT output record                
         WTO   'SIMSG004 Closing file...'                               
         CLOSE (FILE1)                .close files                      
         WTO   'SIMSG005 Returning to caller...'                        
         B     RETURN                 .Return                           
                                                                        
* EXecute instructions                                                  
SETOUT   MVC   OUTREC(0),2(R1)                                          
*****************************************************************       
*                    PROGRAM TERMINATION                                
*****************************************************************       
RETURN   DS    0H                                                       
         WTO   'SIMSG006 RESTORING REGISTERS AND RETURNING'             
         XR    R15,R15                .Clear R15 (RC=0)                 
         RETURN (14,12),RC=(15)       .Restore caller's regs and return 
                                                                        
BADOPEN  DS    0H                                                       
         WTO   'SIMSG002 OPEN failed.'                                  
         B     RETURN                                                   
*****************************************************************       
*                       STORAGE AREAS                                   
*****************************************************************       
OUTREC   DC    80C' '                 .OUTPUT CARD IMAGE                
*****************************************************************       
*                    MACROS AND LITERALS                                
*****************************************************************       
         PRINT NOGEN                                                    
FILE1    DCB   RECFM=F,LRECL=80,BLKSIZE=80,                            X
               DSORG=PS,DDNAME=SYSUT2,MACRF=PM                          
         DCBD                                                           
         PRINT GEN                                                      
*                                                                       
         LTORG                         LITERAL STORAGE                  
         END                                                            
//L.SYSLMOD  DD DISP=SHR,DSN=<your.load.library>(SYMBOLIC)               
//L.SYSPRINT DD SYSOUT=*                                                
//L.SYSIN    DD DUMMY                                                   

и JCL для его выполнения:

//JOBLIB   DD   DISP=SHR,DSN=<your.load.library>          
//*                                                      
//STEP     EXEC PGM=SYMBOLIC,PARM='THIS IS MY PARAMETER'                                
//SYSUT2 DD SYSOUT=*     

                            

Отправьте это и циклы заданий, и вы должны отменить это. Вы получаете «THIS IS MY PARAMETER», записанный в SYSUT2, но WTO показывает:

+SIMSG001 OPEN successful.                 
+SIMSG003 writing to file                  
+SIMSG004 Closing file...                  
+SIMSG005 Returning to caller...           
+SIMSG006 RESTORING REGISTERS AND RETURNING
+SIMSG004 Closing file...                  
+SIMSG005 Returning to caller...           
+SIMSG006 RESTORING REGISTERS AND RETURNING
+SIMSG004 Closing file...                  
+SIMSG005 Returning to caller...           
+SIMSG006 RESTORING REGISTERS AND RETURNING
+SIMSG004 Closing file...                  
+SIMSG005 Returning to caller...           
+SIMSG006 RESTORING REGISTERS AND RETURNING
+SIMSG004 Closing file...                  
+SIMSG005 Returning to caller...           
+SIMSG006 RESTORING REGISTERS AND RETURNING

навсегда.

Измените SYSUT2 на:

//SYSUT2 DD DISP=(MOD,PASS),                             
//          DSN=&AMSCNTL,                                
//          UNIT=SYSDA,                                  
//          SPACE=(TRK,1) 

работает (я знаю, что у меня был еще один шаг, чтобы сгенерировать временный файл в Sysout).

Таким образом, наличие FILE1 (SYSUT2) в качестве SYSOUT вызывает повреждение, так что кажется, что R14 восстанавливается только для того, чтобы указывать на WTO для SIMSG004.

Это старая программа, так что она должна работать. Я мало занимался ассемблером за последние 4 года, но у меня есть некоторый код, использующий стек компоновки и относительную адресацию, но я хочу сначала придерживаться некоторого простого кода базового смещения для обучения этого коллеги.

Любая идея, где это идет не так?


person Steve Ives    schedule 23.03.2021    source источник
comment
Извините, программа просто копирует все, что находится в PARM, в SYSUT2.   -  person Steve Ives    schedule 23.03.2021
comment
Не могли бы вы принять один из ответов?   -  person phunsoft    schedule 09.04.2021
comment
@phunsoft Извините за это - отвлекся на работе, так как это был небольшой сайд-проект.   -  person Steve Ives    schedule 27.04.2021


Ответы (2)


Вы не устанавливаете новую область сохранения регистров после сохранения регистров. Таким образом, R13 по-прежнему указывает на ту же область, и следующий регистр сохранения перезапишется и уничтожит начальный адрес возврата (и многое другое).

Макрос PUT будет вызывать другой код для реальных наборов данных и для наборов данных SYSOUT (JESx). Разница должна быть здесь: если процедура PUT для sysout store регистрируется по адресу в R13, адрес возврата (R14) в области сохранения теперь будет инструкцией после PUT. Таким образом, петля.

Для нереентерабельного кода это должно выглядеть так при входе:

         ...
         LR    R12,R15                     .R12 -> entry point               
         USING SYMBOLIC,R12                .Establish addressability      

* Establish addressability to new save area and chain the save areas
         ST    R13,SAVEAREA+4               Set backward chain pointer
         LR    R15,R13
         LA    R13,SAVEAREA                 Let R13 point to new SA
         ST    R13,8(,R15)                  Set forward chain pointer

И перед перенастройкой вернуть адресуемость SA вызывающего абонента:

RETURN   DS    0H
         ...

* Establish addressability to caller's SA
         L     R13,4(,R13)

         XR    R15,R15                .Clear R15 (RC=0)                 
         RETURN (14,12),RC=(15)       .Restore caller's regs and return 

Наконец, вам нужно определить собственную область сохранения:

         ...
*****************************************************************       
OUTREC   DC    80C' '                 .OUTPUT CARD IMAGE                
*****************************************************************    
         ...
SAVEAREA DS    18F
         ...
person phunsoft    schedule 23.03.2021
comment
Итак, мне нужно предоставить область для любой вызываемой процедуры для хранения моих регистров? Может быть, NEWSAVE DC 18F в моих хранилищах с LA R13,NEWSAVE в начале? Макросы SAVE и RESTORE этого не обеспечивают? - person Steve Ives; 23.03.2021
comment
Нашел это: ibm.com /support/knowledgecenter/SSLTBW_2.1.0/. Раньше я использовал некоторые макросы, написанные кем-то другим, который делал все это, поэтому никогда не кодировал сохранение/восстановление собственного регистра. - person Steve Ives; 23.03.2021
comment
Я предлагаю прочитать z/OS MVSProgramming: Assembler Services Guide, глава о компоновке. [ibm.com/ support/knowledgecenter/SSLTBW_2.1.0/ Здесь есть все подробности для нереентерабельного кода, реентерабельного кода и т. д. - person phunsoft; 23.03.2021
comment
Макросы SAVE и RESTORE этого не обеспечивают? Нет, не предоставляют. - person phunsoft; 23.03.2021

Тот же ответ, что и у @phunsoft, но с большим количеством причин. WTO и OPEN выполняют SVC, поэтому область сохранения не требуется; CLOSE тоже. Однако PUT это branch and set register. Вам нужно выделить 72-байтовый SAVEAREA или GETMAIN, один или как вы хотите его получить. Если вы поместите его в существующий CSECT, он не будет повторно введен, но это на другой день. Это означает, что когда вы возвращаетесь, он пытается перезагрузить SAVEAREA, который вы не выделили, и возвращается сразу после PUT, из которого исходит ваш цикл.

В моей системе это

.PUT output record
 000000A6 4110 C1D0               000001D0     78+         LA    1,FILE1                           LOAD PARAMETER REG 1   02-IHBINNRA
 000000AA 4100 C180               00000180     79+         LA    0,OUTREC                          LOAD PARAMETER REG 0   02-IHBINNRA
 000000AE 1FFF                                 80+         SLR   15,15               CLEAR REGISTER FOR ICM      @L1A 01-PUT
 000000B0 BFF7 1031               00000031     81+         ICM   15,7,49(1)      LOAD PUT ROUTINE ADDRESS        @L1C 01-PUT
 000000B4 0DEF                                 82+         BASR  14,15               LINK TO PUT ROUTINE         @L3C 01-PUT

Таким образом, PUT сохраняется в исходной области сохранения, и когда выдается return, вы возвращаетесь назад после возврата PUT.

Хорошо, так что я не могу с собой поделать. Это лучший пролог

             TITLE  'TEST PROGRAM'                                          
    SYMBOLIC CSECT                                                          
             ASMDREG                      .Register equates                 
             SAVE  (14,12),,'SYMBOLIC PARM SUB &SYSDATE &SYSTIME'           
                                                                            
             LR    R12,R15                .R12 -> entry point               
             USING SYMBOLIC,R12           .Establish addressability  

Добавьте их в пролог

             GETMAIN LV=72
             ST     R13,4(R1)
             LR     R13,R1

Затем, в эпилоге

             LR     R2,R13
             FREEMAIN LV=72,LA=(R2)                 
             L      R13,4(R13)
             LM     R14,R12,12(R13)
             LA     R15,0                    
             BR     R14   

SR против XR против LA, но дебаты заняли гораздо больше времени, чем любой из тактов.

Итак, вот ПОЧЕМУ вам нужна SAVEAREA. Но поскольку это 24-битная ассемблерная программа OG, вам не о чем беспокоиться. Раньше было достаточно 16MB. Похоже, что JES2 перехватывает SYSOUT и творит чудеса, но вышеизложенное будет работать независимо от ваших предпочтений DD.

Я ожидаю, что JES не доверяет никому правильно делать SAVEAREA, что я бы и сделал.

person Hogstrom    schedule 24.03.2021
comment
IHMO, освобождение динамически полученного хранилища перед выходом — это не вариант, а должен. Невыполнение этого требования приводит к утечке памяти. Неважно, насколько вероятно, что он вас укусит, не делать этого — плохая практика программирования. Поэтому, чтобы другие читали ваш пост, я предлагаю вам добавить FREEMAIN к вашему примеру. - person phunsoft; 25.03.2021
comment
Пристыдил меня в этом @phunsoft Добавил FREEMAIN :) - person Hogstrom; 25.03.2021
comment
Мои извинения. Без обид! - person phunsoft; 26.03.2021
comment
@phunsoft извинений не требуется. Это был правильный звонок. Я был ленив. Спасибо - person Hogstrom; 26.03.2021