× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.


  • Subject: Printing NMI...or, How high can a satellite fly?
  • From: David McKenzie <davemck@xxxxxxxxxx>
  • Date: Sun, 28 Nov 1999 16:18:46 -0800

Are you guys getting tired of OMI yet?  (Don't let the spin-doctors in
Rochester fool you--it's _Old_ MI, not Original MI :-)

Do you yearn to see some NMI?  Do you remember wistfully the
GENOPT(*LIST) parm on CRTRPGPGM that we all used back in our youth to
learn MI?

Well, here's a little trick that will print out an NMI listing when you
compile an ILE C module with CRTCMOD.  GENOPT(*LIST) isn't actually
gone--you just have to twist a few bits to make it work.  Unfortunately,
I haven't been able to get this to work with CRTRPGMOD--it gets a
"pointer not set" error.  YARTER (yet another reason to eschew RPG :-)

 I'm including a file containing the source for a simple C pgm and the
two listings generated, for those of you who don't have ILE C.  The
listings don't look much like source code (too verbose).  I think
they're more in the nature of a dis-assembly from NMI object code.

(In the following, I heartily invite Bruce or anyone else to jump in and
correct anything I've got wrong :-)

As far as I can tell, what happens when you compile a module is that the
compilers generate _object_ W-code (in binary form, as opposed to
human-readable source), which they pass to a pgm called QWXCRTMD, which
translates to object NMI and calls the translator (which is in SLIC) to
create the PowerPC machine code.  This is in contrast to the OPM
compilers.  They generated _source_ MI and passed it to the MI
"assembler", QPRROOTP.  That's why we can have the QPRCRTPG API--it's
just a front-end to the same sourcecode "assembler" that the compilers
use.  However, it appears that a sourcecode assembler for NMI doesn't
exist on the system.  To have one, we'd have to pay IBM the $1M or write
it ourselves.  Anyone want to dust off YACC or Bison?

Some Caveats for what follows:

1.  This method involves changing storage with SST.  If you screw up you
could cause "unpredictable results" machine-wide!  The experts on this
mailing list will be comfortable with this, having done similar stuff
thousands of times.  The beginners (those for whom Phil Hall's tutorials
were intended) should probably content themselves with perusing the
listings I've included :-)  Caveat pgmr!

2.  This is for V4R4--the offsets may be different for other releases.

If you're still game, here's the method for getting the NMI listings:

 1.  strdbg qsys/qtexcrts updprod(*yes)
 2.  addbkp '/1'
 3.  Compile a C module (in the same job) with crtcmod, specifying
dbgview(*all)
 4.  When the breakpoint occurs, use STRSST Display/Alter/Dump in
another job to dump the process (job) that you're compiling in.  Use
"dump in hexadecimal (logical blocks)"
 5.  In the process dump listing, scan for QWXCRTMD.  There'll be
several ISF's for QWXCRTMD--go down to the one for ENTRY MAIN  (Notice
that the one just above it is for "TRANSLATE_WCODE" :-)
 6.  Get the ISF address (3 lines above the ENTRY MAIN line).  E.g. "ISF
ADDRESS  DF70773E39  FF69C0"
 7.  Scan for the offset part of the ISF address (e.g. FF69C0).  You'll
find several hits.  Continue to the one that's  followed by the
registers GPR 0 thru GPR 31.
 8.  Find GPR 24, e.g. "GPR 24 EDDB0C91DC 0051B0"
 9.  Add hex 1E8 to that address.  E.g. EDDB0C91DC 0051B0 + 1E8 =
EDDB0C91DC 005398
10.  Use STRSST Display/Alter/Dump to display storage at that calculated
starting address.
11.  Notice that if the address ends in "8" as it does in this example,
that address refers to the 3rd of the 4 columns of hex data.  In this
example, the data at that address is "DC093BD6 7F002248" (in the 3rd &
4th columns).
12.  Go to that address by keying "p" over the first digit of data ("D"
in this case) and pressing F10.  SST will display the data at DC093BD67F
002248.  Again, since the address ends in 8, the data at that address is
in the 3rd column.
13.  The data should be 00000000.  Key a 1 in the last digit, e.g.
0000001.  Press F11 to alter the data.  The heading of the screen will
change to "Alter Storage" and the bottom line will say "The data has
been altered..."  Press F11 again to change back to "Display Storage".
14.  Press F9 to go back to the previous address.
15.  Add 8 to the calculated address from step 9.  Find the data at that
address.  In other words, the next 8 bytes after the data in step 11.
In this case, it starts on the second line (at offset 53A0) and is
"DC093BD6 7F007010"
16.  Again, go to that address by keying "p" over the first digit (the
"D") and pressing F10.  In this example, the data at that address is
"20AA4AF0"
17.  Change the leftmost bit of the first byte to 1.  E.g. change '20'
to 'A0'  (20=00100000, A0=10100000)  Press F11 twice to alter the data
and get back to "Display Storage"
18.  Go back to the compile job and press Enter on the breakpoint to
continue.  If you get further breakpoints, just press Enter.
19.  When the compile finishes, you should have the two extra listings,
QCBNDLST & QCNMILST.
20.  enddbg.

BTW, when you are at the breakpoint in step 4, if you dump QTEMP by
"dmpobj qtemp *lib" you will see 4 space objects named WBODY, WHEADER,
WINIT & WSTRING.  I'm guessing these contain the W-code.  You can use
SST to dump them by address.

This method uses debug on the pgm QTEXCRTS (which is an OPM pgm) as a
means of stopping the job after QWXCRTMD has been called but before it
checks whether to print the NMI listing.  Ideally, we would have put
QWXCRTMD itself in debug, but I don't know how to add a breakpoint to an
ILE pgm that doesn't have debug data.  Does anybody know of a way?

Of course, IBM must have provided a better way of switching on these
listings, but I currently don't know what it is.  However, I've found
some clues:

1.  The 00000000 we changed to 00000001 in step 13 seems to be a switch
that is related to DST Debug mode, which is described in the Licensed
Internal Code Diagnostic Aids (Vol 1) manual.

2.  The CRTCMOD cmd has 3 hidden parms which you can see using RTVCMDSRC
from http://www.news400.com/sharewarefiles/rtvcmd.zip

They are defined as type(*zeroelem), which makes them pass empty lists
to the CPP.  They are called:

SERVICEFE - Service front-end?
SERVICEC3 - Service Cube-3?
SERVICEWC - Service W-Code?

But I haven't found what values the CPP is expecting from these parms,
if they were defined as something other than *zeroelem :-(

Nmilist.zip


As an Amazon Associate we earn from qualifying purchases.

This thread ...


Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.