AI and mainframe assembler

Generate a reentrant program


Here I wanted to see how the chatbots generated a basic reentrant program.

Prompt:
Generate a reentrant HLASM program. 
- Program name is RENTPGM 
- Use register equates from the YREGS macro for the registers 
- All changed fields should be placed in a work area mapped by a DSECT named "DSA" with the comment "Dynamic Save Area" 
- Obtain storage for the DSA work area that has the RENTPGM register save area at the start 
- Chain register save areas using the register save area at the start of the DSA 
- R13 should map to the start of the DSA work area 
- Display "Hello World" using a WTO macro
- Use the STCKE instruction to save the time of day in a field in the DSA
- Free the DSA work area before returning to the caller with return code zero 
- Create concise comments about what the code is doing. 

ChatGPT 4o generated this program:
RENTPGM   CSECT
RENTPGM   AMODE 31
RENTPGM   RMODE ANY
          BAKR  R14,0               Save caller's state
          USING *,R15              Establish base register

*-------- Load register equates
          YREGS                    Equate general registers R0-R15

*-------- Obtain 96 bytes for DSA (includes register save area)
          STORAGE OBTAIN,LENGTH=96,ADDR=R13

*-------- Establish addressability to the DSA
          USING DSA,R13            R13 points to the DSA work area

*-------- Save registers in the DSA
          ST    R14,DSA+4          Save return addr (R14)
          ST    R15,DSA+8          Save entry point addr (R15)
          ST    R12,DSA+12         Save base register

*-------- Chain register save areas
          LR    R1,R13
          ST    R1,8(,R13)         Forward chain to this DSA
          L     R2,0(,R13)         Backward chain from previous DSA
          ST    R2,0(,R13)
          ST    R13,8(,R2)         Complete backward chain

*-------- Display "Hello World"
          WTO   'Hello World',ROUTCDE=(11),DESC=1

*-------- Get time of day and store in DSA
          STCKE DSA_TOD            Store TOD clock into DSA_TOD field

*-------- Free storage and return
          STORAGE RELEASE,ADDR=R13,LENGTH=96

          SLR   R15,R15            Set return code to 0
          PR                       Return to caller

*-------- Dynamic Save Area DSECT
DSA       DSECT
DSA_BWD   DS    F                  Backward chain ptr
DSA_FWD   DS    F                  Forward chain ptr
DSA_R14   DS    F                  Saved R14
DSA_R15   DS    F                  Saved R15
DSA_R12   DS    F                  Saved R12
DSA_TOD   DS    D                  8-byte field for STCKE

          YREGS                    Ensure equates available outside CSECT

          END   RENTPGM

My comments:

 

ChatGPT 5 was released in August 2025 and I used the same prompt as with 4o and it generated this slightly better program:
* --------------------------------------------------------------------
*  RENTPGM — Reentrant sample using a dynamic save area (DSA)
* --------------------------------------------------------------------
RENTPGM   CSECT
RENTPGM   AMODE 31
RENTPGM   RMODE ANY
          USING *,R15                 * Base off entry for a bit

          YREGS                       * R0-R15 equates

* --- Standard prologue: save caller regs in caller’s save area
          STM   R14,R12,12(R13)       * Save R14-R12 in caller SA
          LR    R12,R15               * Establish R12 as our base

* --- Get a DSA (with save area at its start) and chain it
          LA    R1,DSALEN             * R1 = length to obtain
          GETMAIN R,LV=(R1),LOC=(ANY) * R1 -> new storage
          LR    R9,R1                 * R9 = new DSA addr (work reg)

          ST    R13,DSA_BACK(R9)      * Back ptr -> caller SA
          XC    DSA_FWD(4,R9),DSA_FWD(R9)  * Clear forward ptr
          ST    R9,0(R13)             * Caller SA forward -> new DSA
          LR    R13,R9                * R13 maps to start of DSA

* --- (Optional) save our regs in our own register save area
          STM   R14,R12,DSA_R14(R13)  * Save R14-R12 in DSA RSA

* --- Grab the time-of-day into the DSA
          STCKE DSA_TOD(R13)          * 16-byte extended TOD

* --- Say hello
          WTO   'Hello World'         * Simple WTO message

* --- Prepare RC=0 and clean up
          SR    R15,R15               * Return code = 0

* --- Unchain & free the DSA, restore caller context, and return
          L     R9,DSA_BACK(R13)      * R9 = previous SA
          SR    R0,R0                 * R0 = 0
          ST    R0,0(R9)              * Clear previous SA forward ptr
          FREEMAIN R,A=(R13),LV=DSALEN,LOC=(ANY)  * Free our DSA
          LR    R13,R9                * Restore R13 -> caller SA

          LM    R14,R12,12(R13)       * Restore R14-R12
          BR    R14                   * Return to caller

* --------------------------------------------------------------------
*  DSECT: DSA  — Dynamic Save Area
*  Note: Register save area is at the start (standard 18 fullwords)
* --------------------------------------------------------------------
DSA       DSECT                       * Dynamic Save Area
          DS    F                     * +0  FWD ptr
DSA_FWD   EQU   *-4
          DS    F                     * +4  BACK ptr
DSA_BACK  EQU   *-4

* --- Standard register save area layout (18 fullwords / 72 bytes)
DSA_R14   DS    F                     * +8  Save R14
DSA_R15   DS    F                     * +12 Save R15
DSA_R0    DS    F                     * +16 Save R0
DSA_R1    DS    F                     * +20 Save R1
DSA_R2    DS    F                     * +24 Save R2
DSA_R3    DS    F                     * +28 Save R3
DSA_R4    DS    F                     * +32 Save R4
DSA_R5    DS    F                     * +36 Save R5
DSA_R6    DS    F                     * +40 Save R6
DSA_R7    DS    F                     * +44 Save R7
DSA_R8    DS    F                     * +48 Save R8
DSA_R9    DS    F                     * +52 Save R9
DSA_R10   DS    F                     * +56 Save R10
DSA_R11   DS    F                     * +60 Save R11
DSA_R12   DS    F                     * +64 Save R12
          DS    F                     * +68 (padding/compat)

* --- Program work area fields (all changed fields live here)
*     (Dynamic Save Area)
          DS    0D                    * Align (defensive)
DSA_TOD   DS    16X                   * 16-byte STCKE timestamp

DSAEND    EQU   *
DSALEN    EQU   DSAEND-DSA            * Total bytes to GETMAIN/FREEMAIN

          END   RENTPGM

h3>My comments:
  • ChatGPT 5 is slightly better than 4o, see the striked out items below but it's still lacking.
  • It should have had established a good base register like R12
  • YREGS was generated twice so there would be an Assembly error
  • The length of the DSA area should be obtained from a equate like "DSALEN EQU *-DSA" rather than a hardcoded count on the STORAGE OBTAIN/RELEASE
  • This would be an assembly error: STCKE DSA_TOD(R13)
  • The Register Save Area in the DSA is not built correctly (missing the PLI word at offset 0).
  • DSA_TOD should have been 16 bytes not 8
  • There are probably more things wrong
 

Grok generated this program:
* Define register equates using YREGS macro
         YREGS
* Define Dynamic Save Area (DSA) DSECT
DSA      DSECT                Dynamic Save Area
SAVEAREA DS    18F            Register save area (72 bytes)
TOD      DS    CL16           Field to store time of day
DSA_LEN  EQU   *-DSA          Length of DSA
* Main program CSECT
RENTPGM  CSECT
* Obtain storage for DSA
         USING DSA,13         Map R13 to DSA
         STORAGE OBTAIN,LENGTH=DSA_LEN
         ST    15,8(,13)      Save address of DSA in caller's save area
         LR    13,15          Set R13 to point to DSA
* Chain save areas
         USING *,15           Set up addressing
         ST    14,4(,13)      Save return address in caller's save area
         LA    14,SAVEAREA    Point to current save area
         ST    14,8(,15)      Chain to previous save area
* Save time of day using STCKE
         LA    0,TOD          Point to TOD field in DSA
         STCKE 0              Store clock value in TOD field
* Display "Hello World" using WTO
         WTO   'Hello World'
* Free DSA storage
         STORAGE RELEASE,LENGTH=DSA_LEN,ADDR=(13)
* Return to caller with return code 0
         LA    15,0           Set return code to 0
         BR    14             Return to caller
         END   RENTPGM

My comments:

  • It didn't use the R0-R15 equates from YREGS as requested
  • It should have had established a good base register like R12
  • The address of storage from the STORAGE OBTAIN is in R1 not R15
  • STCKE 0 should have been STCKE TOD
  • STCKE 0 should result in a S0C4 updating location zero
  • It didn't use the address returned by the STORAGE OBTAIN
  • I stopped looking at this point
 

Gemini generated this program:
RENTPGM  CSECT
*---------------------------------------------------------------------*
* *
* RENTPGM - A sample reentrant program for z/OS.                    *
* *
* This program demonstrates the following concepts:                 *
* - Standard entry and exit linkage.                                *
* - Dynamic storage acquisition (GETMAIN) for a work area.          *
* - Save area chaining (forward and backward pointers).             *
* - Use of a DSECT to map the dynamic work area.                    *
* - Issuing a WTO macro to write a message to the system log.       *
* - Using the STCKE instruction to get the time-of-day clock value. *
* - Freeing the dynamic storage (FREEMAIN) before returning.        *
* - Returning a zero return code to the caller.                     *
* *
*---------------------------------------------------------------------*
         RENTPGM  AMODE 31            Set 31-bit addressing mode
         RENTPGM  RMODE ANY             Reside anywhere in storage
*
* Standard Entry Linkage
*
         STM   R14,R12,12(R13)     Save caller's registers
         BALR  R12,0               Establish base register
         USING *,R12               Tell assembler R12 is the base
*
* Obtain dynamic storage for the work area (DSA).
* The size is determined by the length of the DSA DSECT.
*
         GETMAIN RU,LV=DSALEN,SP=0   Get storage for DSA, Reentrant User
         ST    R1,8(,R13)          Store new DSA addr in caller's save area
         ST    R13,4(,R1)          Store old save area addr in new DSA
         LR    R13,R1              Set R13 to point to the new DSA
         USING DSA,R13             Map the DSA with R13
*
* Program Logic
*
* Display "Hello World" message using WTO macro.
* The WTO text and length are defined in the DSA.
*
         WTO   MF=(E,MSG)          Issue WTO using execute form
*
* Store the current Time-Of-Day clock value into the DSA.
* STCKE stores a 16-byte extended value.
*
         STCKE TODVAL              Store Time-Of-Day Clock Extended
*
* Standard Exit Linkage
*
EXIT     DS    0H
         L     R13,SAVEBACK        Restore caller's save area pointer
*
* Free the dynamic storage area obtained earlier.
*
         FREEMAIN RU,LV=DSALEN,A=(R13) Free the DSA storage
*
* Set return code to zero and return to the caller.
*
         SR    R15,R15             Set return code to 0
         L     R14,12(,R13)        Restore caller's R14
         LM    R0,R12,20(R13)      Restore caller's R0-R12
         BR    R14                 Branch back to caller
*
* Constants and Literals
*
         LTORG
*
* Register Equates
*
         YREGS
*
*---------------------------------------------------------------------*
* DSECT for the Dynamic Storage Area (DSA)                     *
*---------------------------------------------------------------------*
DSA      DSECT                     Dynamic Save Area
SAVEAREA DS    0F                  Start of standard 72-byte save area
SAVEBACK DS    A                   Backward pointer to caller's save area
SAVEFORW DS    A                   Forward pointer (unused in this pgm)
         DS    16F                 Rest of save area (R14-R12)
*
* Work area fields
*
TODVAL   DS    CL16                Field for STCKE value (128-bit clock)
*
* WTO Message definition (list form)
*
MSG      DS    0H                  WTO parameter list
MSGLEN   DS    AL2(L'MSGTEXT)      Length of the message text
MSGTEXT  DS    C'Hello World'      The message text itself
*
* Length of the entire DSA for GETMAIN/FREEMAIN
*
DSALEN   EQU   *-DSA               Length of the dynamic area
*
         END   RENTPGM

My comments:

  • The AMODE and RMODE statements should start in column 1
  • The SAVEAREA is wrong and should have the SAVPLI word at offset 0
  • "WTO MF=(E,MSG)" should have been "WTO ,TEXT=MSG" since the MSG area was defined as a TEXT= format.
  • MSGLEN and MSGTEXT in the DSA area was not initialized
 

Copilot generated this program:
RENTPGM  CSECT
         USING *,R15              * Establish base register
         BAKR  R14,0              * Branch and stack return address
         YREGS                    * Register equates macro

* Obtain storage for DSA work area
         STORAGE OBTAIN,LENGTH=DSALEN,ADDR=(R1)
         LR    R13,R1             * R13 -> DSA
         USING DSA,R13            * Map DSA to R13

* Save registers in DSA save area and chain
         ST    R14,DSASAVE+4      * Save caller's R14
         ST    R13,DSASAVE+8      * Save caller's R13 for backchain
         L     R1,0(,R13)         * Load previous DSA from original R13
         ST    R1,DSASAVE         * Backchain previous save area

* Save time of day using STCKE
         STCKE DSATOD             * Store TOD extended

* Issue WTO to say Hello World
         WTO   'Hello World'

* Free DSA work area
         LR    R1,R13
         STORAGE RELEASE,ADDR=(R1)

* Return to caller
         L     R13,DSASAVE+8      * Restore caller’s R13
         PR                      * Return (POP & R)

*------------------------------------------------------------------
DSA      DSECT                   * Dynamic Save Area
DSASAVE  DS    18F               * Register save area
DSATOD   DS    2D                * 16-byte TOD field
DSALEN   EQU   *-DSA             * Length of work area
*------------------------------------------------------------------

         END   RENTPGM

My comments:

  • I asked it to use register save areas and it used BAKR/PR instead
  • The STORAGE RELEASE should have a length operand
  • The entry and exit chaining it did was incorrect.
  • Nitpick: If it's going to use BAKR, it should put C'F1SA' in Offset 4 of the Register Save Area.
 

Claude generated this program:
RENTPGM  CSECT                     Program entry point
         AMODE 31                  31-bit addressing mode
         RMODE ANY                 Can reside anywhere in storage
*
* Register equates using YREGS macro
*
         YREGS                     Standard register equates
*
* Program entry - establish addressability and get work area
*
         SAVE  (14,12),,RENTPGM    Save caller's registers
         LR    R12,R15             Load base register
         USING RENTPGM,R12         Establish addressability
*
* Obtain storage for Dynamic Save Area (DSA)
*
         LA    R0,DSASIZE          Load size of DSA
         GETMAIN R,LV=(0)          Get dynamic storage
         ST    R13,4(R1)           Chain backward (caller's save area)
         ST    R1,8(R13)           Chain forward (our save area)
         LR    R13,R1              Point R13 to our DSA
         USING DSA,R13             Map DSA with R13
*
* Display Hello World message
*
         WTO   'Hello World'       Write to operator
*
* Store current time using STCKE instruction
*
         STCKE TODCLOCK            Store clock extended format
*
* Return to caller with RC=0
*
         LA    R15,0               Set return code to zero
         LR    R1,R13              Save DSA address
         L     R13,4(R13)          Restore caller's save area
         LA    R0,DSASIZE          Load DSA size for freemain
         FREEMAIN R,LV=(0),A=(1)  Free dynamic storage
         RETURN (14,12),RC=(15)    Return to caller
*
* Constants and literals
*
         LTORG                     Literal origin
*
* Dynamic Save Area (DSA) mapping
*
DSA      DSECT                     Dynamic Save Area
SAVEAREA DS    18F                 Standard register save area
TODCLOCK DS    2D                  Time of day clock (16 bytes)
DSASIZE  EQU   *-DSA               Size of DSA
*
         END   RENTPGM             End of program

My comments:

  • The AMODE and RMODE instructions are missing the program name and would get an assembly error.
  • R15 would be changed by FREEMAIN and was set to zero in the wrong place.
  • Nitpick: Ideally it would clear SAVNEXT in the caller's RSA before returning. To be fair, few programs do this.
  • Otherwise this is best looking code of this exercise.


My take on these results:

Same prompt, different results

You may get different results with the same prompt. As I've seen with creating images with chatbots, you can get different results on repeated requests. You will probably get different results if you use the same prompt I did.

This testing was performed in July 2025 unless noted differently.


Return to Dave's AI and mainframe assembler page .

Last Updated: 2025-08-10
This web page is © 2025+ by David Alcock. All Rights Reserved.