Hercules Diagnostic Tools


PREVIOUS
CONTENTS
NEXT

Now that we have the breakpoint and virtual storage display facilities at our disposal, let's use our IEFBR14 program to learn about another Hercules diagnostic tool: instruction stepping.


Instruction stepping


Sometimes when you're debugging your programs, it is helpful to be able to see exactly what instructions are being executed and what effects those instructions have on the GPRs and storage.

While it is possible to repetitively set breakpoints at every instruction, this quickly gets to be tiresome. That's where instruction stepping comes in.

Instruction stepping allows you to tell Hercules to start tracing every instruction executed, and display the PSW, GPRs, and CRs before each instruction is executed.


s+              # begin instruction stepping
s-              # turn off instruction stepping

Note the CPU is stopped following each instruction, so you will
have to issue the Hercules "start" command to progress to the
next instruction.

Having to enter the "start" command before executing the instruction on which the CPU has stopped gives you a perfect opportunity to stop and think, display virtual (or real) storage, or modify the Hercules environment in some other manner.


Instruction stepping through IEFBR14


If you haven't already done so, add the "PAGE IEFBR14" statement to the linkage editor step. Additionally, add PARM='HELLO WORLD' to the IEFBR14 step.

Your jobstream should look like:


//IEFBR14  JOB CLASS=A,MSGCLASS=A
//*--------------------------------------------------------------------
//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 *
 PAGE IEFBR14
 NAME IEFBR14(R)
//*-------------------------------------------------------------------
//IEFBR14  EXEC PGM=IEFBR14,PARM='HELLO WORLD'
//STEPLIB   DD DSN=JMM.S370ASM.LOAD,DISP=SHR
//

Since we now know the virtual address at which our batch program will be loaded, we first set a breakpoint on the first instruction:


b a5000
HHCPN040I Setting breakpoint at 00000000000A5000

OK, run the IEFBR14 job shown above. Hercules should now display:


PSW=078D0000 000A5000 INST=1FFF         SLR   15,15
GR00=009EE078	GR01=000A4FE8	GR02=00000040	GR03=009E1634
GR04=009E1610	GR05=009EC8A8	GR06=009C3018	GR07=FD000000
GR08=009EC108	GR09=809EC2B8	GR10=00000000	GR11=009EE080
GR12=40EB7B9A	GR13=000A4FA0	GR14=00019DC0	GR15=000A5000
CR00=C080EC40	CR01=0FB93C00	CR02=FFFFFFFF	CR03=00000000
CR04=00000000	CR05=00000000	CR06=00000000	CR07=00000000
CR08=00000000	CR09=00000000	CR10=00000000	CR11=00000000
CR12=00000000	CR13=00000000	CR14=EFC00000	CR15=00FDD368

As you might recall, the "SLR 15,15" instruction will set GPR15 to X'00000000'.

Note the displayed contents of GPR15 (labeled GR15 above): 000A5000, which is our program's entry point address.

To execute the "SLR 15,15" instruction and stop the CPU on the next instruction, enter the "start" command. Hercules will display:


start
PSW=078D2000 000A5002 INST=07FE         BCR   15,14
GR00=009ECE58	GR01=000A4FE8	GR02=00000040	GR03=009E1634
GR04=009E1610	GR05=009EC8A8	GR06=009C3018	GR07=FD000000
GR08=009EC108	GR09=809EC2B8	GR10=00000000	GR11=009ECA90
GR12=40EB7B9A	GR13=000A4FA0	GR14=00019DC0	GR15=00000000
CR00=C080EC40	CR01=0FB93C00	CR02=FFFFFFFF	CR03=00000000
CR04=00000000	CR05=00000000	CR06=00000000	CR07=00000000
CR08=00000000	CR09=00000000	CR10=00000000	CR11=00000000
CR12=00000000	CR13=00000000	CR14=EFC00000	CR15=00FDD368

Note GPR15 now contains X'00000000', indicating that the "SLR 15,15" instruction has been executed.

We are now stopped on the "BR 14" instruction (displayed by Hercules as "BCR 15,14" based on how the S/370 actually views the "BR 14" instruction). Enter the "start" command, and observe that the next instruction (on which the CPU stops before executing) is indeed located at the address pointed to by GPR14: X'00019DC0' in the example shown, although it may be different on your system.


start
PSW=078D2000 00019DC0 INST=0A03         SVC   3
GR00=009ECE58	GR01=000A4FE8	GR02=00000040	GR03=009E1634
GR04=009E1610	GR05=009EC8A8	GR06=009C3018	GR07=FD000000
GR08=009EC108	GR09=809EC2B8	GR10=00000000	GR11=009ECA90
GR12=40EB7B9A	GR13=000A4FA0	GR14=00019DC0	GR15=00000000
CR00=C080EC40	CR01=0FB93C00	CR02=FFFFFFFF	CR03=00000000
CR04=00000000	CR05=00000000	CR06=00000000	CR07=00000000
CR08=00000000	CR09=00000000	CR10=00000000	CR11=00000000
CR12=00000000	CR13=00000000	CR14=EFC00000	CR15=00FDD368

Before we let the CPU execute the "SVC 3" instruction, let's quickly see how the OS PARM string MVS passed our program ("HELLO WORLD") looks in storage.

Recall that when our program receives control GPR1 contains the address of a fullword (four bytes). This fullword contains the address of a halfword (two bytes) which contains the length of the PARM string. Immediately following the halfword is the PARM string itself, if there is one.

Note the address contained in R1, X'000A4FE8' above (although it may be different on your system). Display the fullword at that address with these Hercules commands:


v a4fe8
V:000A4FE8 (primary) R:00B94FE8
V:000A4FE8:K:8E=800A4FEE 0000000B C8C5D3D3 D640E6D6  ç±×î....HELLO WO
v a4fee
V:000A4FEE (primary) R:00B94FEE
V:000A4FEE:K:8E=000B C8C5D3D3 D640E6D6 D9D3C400 0000 ..HELLO WORLD...

I have mildly trimmed the output to reduce clutter and highlight the storage of interest. Note the second display shows the halfword length (X'000B') followed by the "HELLO WORLD" string.

Meanwhile, back at the CPU, we have left the IEFBR14 program. While we could continue to instruction step through MVS itself if we so chose, let's not. To turn off instruction stepping and resume normal S/370 instruction execution, enter:


s-
HHCPN133I Instruction stepping is now off
start

Following this sequence of commands, the S/370 CPU is executing MVS as it normally does.

Having examined the IEFBR14 program in careful detail using the breakpoint, storage display, and instruction stepping facilities of Hercules it should be apparent that these techniques can be applied to any instructions in which we are interested.

As we learn additional S/370 instructions don't be afraid to use this technique to help you understand some aspect of an instruction.

Always keep in mind that Hercules instruction stepping displays the PSW, GPRs, and CRs before the instruction is executed.



PREVIOUS
CONTENTS
NEXT