Using Debug (continued) [ HP COBOL II/XL Programmer's Guide ] MPE/iX 5.0 Documentation
HP COBOL II/XL Programmer's Guide
Using Debug (continued)
Example Maps for Nested and Concatenated Programs
This compiler listing is for two concatenated programs, MAIN-P and
CONCAT-P. The first program, MAIN-P, contains a nested program, NESTED-P.
The compiler appends the maps to the end of the listing of all three
programs. First the symbol maps and cross reference appear, followed by
the verb maps.
Note that the nested program NESTED-P is compiled with $CONTROL DYNAMIC.
Because of this, the symbol map shows the address for the data item local
to this program to be relative to the stack pointer (SP).
PAGE 0001 HP31500A.01.00 [85] (C) HEWLETT-PACKARD CO. 1987
00001 INFO=$CONTROL MAP,verbs
00002 001000 IDENTIFICATION DIVISION.
00003 001100 PROGRAM-ID. MAIN-P.
00004 001200 DATA DIVISION.
00005 001300 WORKING-STORAGE SECTION.
00006 001400 1 DUMMY-N GLOBAL PIC 99 VALUE 88.
00007 001500 PROCEDURE DIVISION.
00008 001600 BEGIN.
00009 001700 CALL "NESTED-P".
00010 001800
00011 001810$control dynamic
00013 001900 IDENTIFICATION DIVISION.
00014 002000 PROGRAM-ID. NESTED-P.
00015 002100 DATA DIVISION.
00016 002200 WORKING-STORAGE SECTION.
00017 002300 01 LOCAL-DATA PIC X(15).
00018 002400 PROCEDURE DIVISION.
00019 002500 BEGIN.
00020 002600 MOVE "END IN NESTED-P" TO LOCAL-DATA.
00021 002700 ADD 1 TO DUMMY-N.
00022 002800 CALL "CONCAT-P".
00024 002900 END PROGRAM NESTED-P.
00025 003000 END PROGRAM MAIN-P.
00026 003100
00027 003200 IDENTIFICATION DIVISION.
00028 003300 PROGRAM-ID. CONCAT-P.
00029 003400 DATA DIVISION.
00030 003500 WORKING-STORAGE SECTION.
00031 003600 01 LOCAL-DATA PIC X(15).
00032 003700 PROCEDURE DIVISION.
00033 003800 BEGIN.
00034 003900 MOVE "END IN CONCAT-P" TO LOCAL-DATA.
00036 004000 END PROGRAM CONCAT-P.
PAGE 0002/COBTEXT MAIN-P SYMBOL TABLE MAP
LINE# LVL SOURCE NAME BASE OFFSET SIZE USAGE CATEGORY R O J BZ
WORKING-STORAGE SECTION
00006 01 DUMMY-N DP+ 28 2 DISP N
PAGE 0003/COBTEXT MAIN-P SYMBOL TABLE MAP
LINE# LVL SOURCE NAME BASE OFFSET SIZE USAGE CATEGORY R O J BZ
STORAGE LAYOUT (#ENTRYS)
FIRST TIME FLAG, etc. DP+ 8 4
RUN TIME $ . , DP+ 14 4
SORT/MERGE PLABEL DP+ 18 4
TALLY DP+ 24 4
USER STORAGE DP+ 24 6
PAGE 0004/COBTEXT NESTED-P SYMBOL TABLE MAP
LINE# LVL SOURCE NAME BASE OFFSET SIZE USAGE CATEGORY R O J BZ
WORKING-STORAGE SECTION
00017 01 LOCAL-DATA SP -40 F DISP AN
PAGE 0005/COBTEXT NESTED-P SYMBOL TABLE MAP
LINE# LVL SOURCE NAME BASE OFFSET SIZE USAGE CATEGORY R O J BZ
STORAGE LAYOUT (#ENTRYS)
FIRST TIME FLAG, etc. SP -60 4
RUN TIME $ . , SP -54 4
SORT/MERGE PLABEL SP -50 4
TALLY SP -44 4
USER STORAGE SP -44 13
Literal pool ~ S$ CODE 0 14
PAGE 0006/COBTEXT CONCAT-P SYMBOL TABLE MAP
LINE# LVL SOURCE NAME BASE OFFSET SIZE USAGE CATEGORY R O J BZ
WORKING-STORAGE SECTION
00031 01 LOCAL-DATA OWN 20 F DISP AN
PAGE 0007/COBTEXT CONCAT-P SYMBOL TABLE MAP
LINE# LVL SOURCE NAME BASE OFFSET SIZE USAGE CATEGORY R O J BZ
STORAGE LAYOUT (#ENTRYS)
FIRST TIME FLAG, etc. OWN 0 4
RUN TIME $ . , OWN C 4
SORT/MERGE PLABEL OWN 10 4
TALLY OWN 1C 4
USER STORAGE OWN 1C 13
Literal pool ~ S$ CODE 0 10
PAGE 0008/COBTEXT CONCAT-P STATEMENT OFFSETS
Entry = main_p
STMT OFFSET STMT OFFSET STMT OFFSET STMT OFFSET ...
8 1C 9 1C
PAGE 0009/COBTEXT CONCAT-P STATEMENT OFFSETS
Entry = main_p$003$nested_p
STMT OFFSET STMT OFFSET STMT OFFSET STMT OFFSET ...
19 60 20 60 21 88 22 E8
PAGE 0010/COBTEXT CONCAT-P STATEMENT OFFSETS
Entry = concat_p
STMT OFFSET STMT OFFSET STMT OFFSET STMT OFFSET ...
33 48 34 48
0 ERRORS, 0 QUESTIONABLE, 0 WARNINGS
DATA AREA IS 84 BYTES.
CPU TIME = 0:00:01. WALL TIME = 0:00:02.
Subprogram Parameters
Memory contains two copies of each set of subprogram parameters. The two
copies allow multiple entry points.
Parameters are stored in dynamically allocated memory and referenced
through the stack pointer (SP, register 30) or the previous stack pointer
(PSP).
You can access one copy only if you are at a breakpoint at the entry
point of the subprogram. The first four parameters are in registers:
Table 7-6. Registers 23 through 26
---------------------------------------------------------------------------------------------
| | |
| Register | Parameter |
| | |
---------------------------------------------------------------------------------------------
| | |
| R26 | Parameter one. |
| | |
---------------------------------------------------------------------------------------------
| | |
| R25 | Parameter two. |
| | |
---------------------------------------------------------------------------------------------
| | |
| R24 | Parameter three. |
| | |
---------------------------------------------------------------------------------------------
| | |
| R23 | Parameter four. |
| | |
---------------------------------------------------------------------------------------------
The rest of the parameters are stored in memory, beginning with SP-34 and
working backward. The fifth parameter is in SP-34, the sixth parameter
is in SP-38, and so on. Offsets are hexadecimal.[REV BEG] The above SP
becomes PSP for data references after the entry point.[REV END]
The location of the other copy appears in the map. Data is not moved
there until the first executable subprogram statement executes. You must
access this copy if you are past the subprogram entry point but have not
exited the subprogram. All parameters are stored in memory, beginning
with PSP-24 and working backward. Each parameter is stored in four
bytes.
Register Meanings
The following registers have the following meanings, independent of
COBOL:
Table 7-7. Registers 0, 1, and 2
---------------------------------------------------------------------------------------------
| | |
| Register | Meaning |
| | |
---------------------------------------------------------------------------------------------
| | |
| R0 | Always zero. |
| | |
---------------------------------------------------------------------------------------------
| | |
| R1 | Scratch register. |
| | |
---------------------------------------------------------------------------------------------
| | |
| R2 | Last return address. |
| | |
---------------------------------------------------------------------------------------------
The following registers are always present:
Table 7-8. Registers 27, 30, and 31
---------------------------------------------
| | |
| Register | Contents |
| | |
---------------------------------------------
| | |
| R27 | DP, the data pointer. |
| | |
---------------------------------------------
| | |
| R30 | SP, the stack pointer. |
| | |
---------------------------------------------
| | |
| R31 | Millicode return address. |
| | Millicode is special utility |
| | code for COBOL and other |
| | languages. |
| | |
---------------------------------------------
Calculating Addresses of Data Items
The first step in displaying or changing the value of a data item is to
find its address:
1. Obtain symbol table and link maps for your program.
2. On the symbol table map, find the base and offset of the data item
that you want to display or change. The base is DP, SP, EXT, OWN,
or P nn, where nn is the parameter number.
3. If the base is DP (the address of the DATA DIVISION of the main
program), then the address of the data item is DP+offset. (DP is
different in each XL module.)
4. If the base is SP (the address of the Working Storage of a DYNAMIC
subprogram or the temporary cells of the main program), then the
address of the data item is SP-offset, which is only valid[REV
BEG] when you are in the subprogram.[REV END]
5. If the base is EXT (the address of the program's external
variables), find the data item in the link map. Add the address
that the link map shows for the data item to the offset from the
symbol table map. This is the actual address of the data item
(DP+link_addr+map_offset). (DP is different in each XL module.)
6. If the base is OWN (the address of the Working Storage of an
ANSISUB or SUBPROGRAM subprogram), then the address of the data
item is address_of_OWN+offset. You must find address_of_OWN in
the link map. It is the SYM VALUE of M$n$ program_name (where n
is a number), which is DP plus a number. (DP is different in each
XL module.)
7. If the base is P nn, where nn is the parameter number (the address
of the LINKAGE SECTION), find the address of PARAMETER POINTERS
under STORAGE LAYOUT in the symbol table map. It is a negative
offset from SP, -mm. The address of the first parameter is SP-mm.
The address of parameter nn is:
[(SP-mm) + 4 * nn] + offset
(The bracketed value is called the indirection operator.)
8. You can obtain data addresses at run time in Debug, using the
PROCLIST command (see the MPE XL System Debug Reference Manual).
NOTE The formulas for the first and nnth parameters are valid only if
you are at or after the first statement of the program. If you are
at a breakpoint at the entry point to the subprogram, its
parameters have not yet been copied out of the registers.
The following format of the PROCLIST command gives you starting offsets
of all data areas associated with all programs in your program file. The
global area of the outermost program (main) is shown as M$1, as $dp$, and
as $global$. The COBOL EXTERNAL item EXT-GRADE is downshifted and the
hyphen ("-") replaced with an underscore ("_"). EXTERNAL items have
named storage associated with them at run time.
The OWN data areas associated with a nested program follow the format
M.nested_program_name, where each nested_program_name follows the format
for internal names that is explained in Chapter 3 .
Example.
$3 ($36) nmdebug > proclist,,dataany
571.40000008 $global$
571.40000008 $dp$
571.40000080 ext_grade
571.40000008 M$1
571.40000038 M.main$003$valid_grade
571.40000060 M.main$004$display_bell
NOTE The above display has been edited for conciseness. You can ignore
other addresses that appear on your screen.
The above addresses are the values known at link time. The value
of $dp$, 571.40000008, must be subtracted from all values and then
added to DP. For example, the address of ext_grade is DP+80-8.
For commands that display and change data item values, refer to the MPE
XL System Debug Reference Manual.
Calculating Code Addresses
You must calculate code addresses in order to set breakpoints in Debug
(refer to the MPE XL System Debug Reference Manual for breakpoint
syntax).
To calculate the code address of a specific statement:
1. In the verb map, find the offset for the statement.
2. If the portion of the verb map that lists the offset for the
statement does not have "Chunk = name" in its heading, then the
statement offset is:
program_offset + statement_offset
3. If the portion of the verb map that lists the offset for the
statement has "Chunk = name" in its heading, find the chunk name
in the link map. Its SYM VALUE is the chunk address. The
statement offset is:
chunk_offset + statement_offset
To find the offset of a program or chunk, do one of the following:
* Obtain a link map, using the LISTPROG command (see the Link Editor
manual). Program and chunk names are listed with their offsets.
* Use the PROCLIST command in Debug. This allows you to obtain the
offsets at run time. See the MPE XL System Debug Reference
Manual.
Example.
Given a program MAIN that contains one chunk and two nested programs,
VALID-GRADE and DISPLAY-BELL, here is one way to get the starting
addresses of a main program and any program it contains. Nested program
names are qualified with the name of the outermost program that contains
them, so if you supply the main program name appended and prepended with
wild card characters, and use the parameter any, you get the following:
$1 ($33) nmdebug > proclist @main@,,any
528.535b main [1]
528.5400 main$001$ [2]
528.542b main.valid_grade [3]
528.55e3 main.display_bell [4]
The first, third, and fourth items are program names and their offsets.
The second item is a chunk name and its offset.
NOTE The above display has been edited for conciseness. You can ignore
other addresses that appear on your screen.
MPE/iX 5.0 Documentation