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