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:
- 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
- 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
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.
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.