我会尽力回答这个问题。如果您唯一的编码暴露是 x86 或 ARM,那么您将遇到很大的困难。是的,这些芯片卖得很多,但这并不意味着它们很好,只是足够便宜,人们不介意扔掉它们。
大部分信息都可以在“The Minimum You Need to Know to Be an OpenVMS Application Developer”中找到。你会发现它是Dr. Dobb's recommended reading list for all developers 上为数不多的标题之一。是的,我写的。它也是 HP OpenVMS 工程组向希望学习该平台的开发人员推荐的一本书。
我在那个平台上的 COBOL 主要发生在 1980 年代,当时它是 VAX/VMS。然后它变成了 OpenVMS;阿尔法/OpenVMS;安腾/OpenVMS;很快就会成为 x86/OpenVMS。在具有真实操作系统的真实计算机上,部分具有意义。每个部分都创建了一个 PSECT。在链接器术语中是 Program SECtion 的缩写。根据该部分的内容,设置了各种负载属性。每个 PSECT 将被加载到一个或多个 512 字节内存页中。内存页被设计成与磁盘块的大小完全相同。 VMS 代表虚拟内存系统。 IBM 有几个自己的操作系统,它们在底层是不同的,但它们也是真正的虚拟内存系统。这不是“覆盖链接”。这是一个 x86 术语,是由于严重的架构缺陷而出现的。从 286 天开始阅读紧凑型、小型、中型和大型“内存模型”。还阅读了 EMS 和 XMS 内存分页。 Oiy 太有趣了!
这是该书中的众多程序之一。
IDENTIFICATION DIVISION.
程序 ID。 COB_ZILL_DUE_REPORT_SUB。
作者。罗兰休斯。
写日期。 2005-02-08。
日期编译。今天。
环境部。
输入-输出部分。
文件控制。
SELECT DRAW-STATS
ASSIGN TO 'DRAWING_STATS'
ORGANIZATION IS INDEXED
ACCESS MODE IS SEQUENTIAL
RECORD KEY IS ELM_NO IN DSTATS-REC
LOCK MODE IS AUTOMATIC
FILE STATUS IS D-STAT.
SELECT MEGA-STATS
ASSIGN TO 'MEGA_STATS'
ORGANIZATION IS INDEXED
ACCESS MODE IS SEQUENTIAL
RECORD KEY IS ELM_NO IN MSTATS-REC
LOCK MODE IS AUTOMATIC
FILE STATUS IS M-STAT.
SELECT SORT-FILE ASSIGN TO 'TMP.SRT'.
SELECT SORTED-FILE ASSIGN TO DISK.
SELECT RPT-FILE ASSIGN TO 'ZILL_DUE.RPT'.
数据划分。
文件部分。
FD 抽签统计
是全球性的
标签记录是标准的。
COPY 'CDD_RECORDS.ZILLIONARE_STATS_RECORD' FROM DICTIONARY
REPLACING ZILLIONARE_STATS_RECORD BY DSTATS-REC.
FD MEGA-STATS
是全球性的
标签记录是标准的。
COPY 'CDD_RECORDS.ZILLIONARE_STATS_RECORD' FROM DICTIONARY
REPLACING ZILLIONARE_STATS_RECORD BY MSTATS-REC.
FD RPT-文件
省略了标签记录。
01 RPT-DTL PIC X(80).
SD 排序文件。
COPY 'CDD_RECORDS.ZILLIONARE_STATS_RECORD' FROM DICTIONARY
REPLACING ZILLIONARE_STATS_RECORD BY SORT-REC.
FD 排序文件
ID 的值是已排序的文件名。
COPY 'CDD_RECORDS.ZILLIONARE_STATS_RECORD' FROM DICTIONARY
REPLACING ZILLIONARE_STATS_RECORD BY SORTED-REC.
工作存储部分。
01 常数。
05 排序文件名 PIC X(7) 值“TMP.SRT”。
05 SORTED-FILE-NAME PIC X(8) VALUE 'STAT.SRT'。
01 STATUS-VARIABLES.
05 M-STAT PIC X(2).
05 D-STAT PIC X(2).
05 EOF-FLAG PIC X.
88 IT-IS-END-OF-FILE VALUE 'Y'.
01 STUFF.
05 TODAYS-DATE.
10 TODAY_YYYY PIC X(4).
10 TODAY_MM PIC X(2).
10 TODAY_DD PIC X(2).
05 TODAYS-DATE-FORMATTED.
10 FMT_MM PIC Z9.
10 FILLER PIC X VALUE '/'.
10 FMT_DD PIC 99.
10 FILLER PIC X VALUE '/'.
10 FMT_YYYY PIC 9(4).
05 FLT-1 COMP-2.
05 WORK-STR PIC X(65).
01 REPORT-DETAIL.
05 ELM-NO-DTL PIC Z9.
05 FILLER PIC X(3).
05 HIT-COUNT-DTL PIC ZZZ9.
05 FILLER PIC X(3).
05 SINCE-LAST-DTL PIC ZZZ9.
05 FILLER PIC X(5).
05 PCT-HITS-DTL PIC Z9.999.
05 FILLER PIC X(4).
05 AVE-BTWN-DTL PIC ZZ9.999.
01 REPORT-HDR1.
05 THE-DATE PIC X(12).
05 FILLER PIC X(20).
05 PAGE-TITLE PIC X(17).
01 REPORT-HDR2.
05 FILLER PIC X(33).
05 GROUP-TITLE PIC X(20).
01 REPORT-HDR3.
05 HDR3-TXT PIC X(40) VALUE
'No Hits Since Pct_hits Ave_btwn'.
01 REPORT-HDR4.
05 HDR4-TXT PIC X(40) VALUE
'-- ---- ----- -------- --------'.
程序部。
A000-MAIN。
PERFORM B000-HSK.
SORT SORT-FILE
ON DESCENDING KEY SINCE_LAST IN SORT-REC
INPUT PROCEDURE IS S000-DSTAT-INPUT
GIVING SORTED-FILE.
PERFORM B010-REPORT-DRAWING-NUMBERS.
STRING SORT-FILE-NAME, ';*' DELIMITED BY SIZE INTO WORK-STR.
CALL 'LIB$DELETE_FILE' USING BY DESCRIPTOR WORK-STR.
STRING SORTED-FILE-NAME, ';*' DELIMITED BY SIZE INTO WORK-STR.
CALL 'LIB$DELETE_FILE' USING BY DESCRIPTOR WORK-STR.
*
* 设置报告的第二部分
*
将空间移动到 RPT-DTL。
在前进页面之前编写 RPT-DTL。
MOVE SPACES TO EOF-FLAG.
MOVE ' Mega Drawing Numbers' TO GROUP-TITLE.
SORT SORT-FILE
ON DESCENDING KEY SINCE_LAST IN SORT-REC
INPUT PROCEDURE IS S001-MSTAT-INPUT
GIVING SORTED-FILE.
PERFORM B010-REPORT-DRAWING-NUMBERS.
STRING SORT-FILE-NAME, ';*' DELIMITED BY SIZE INTO WORK-STR.
CALL 'LIB$DELETE_FILE' USING BY DESCRIPTOR WORK-STR.
STRING SORTED-FILE-NAME, ';*' DELIMITED BY SIZE INTO WORK-STR.
CALL 'LIB$DELETE_FILE' USING BY DESCRIPTOR WORK-STR.
CLOSE RPT-FILE.
CALL 'LIB$SPAWN' USING BY DESCRIPTOR 'EDIT/READ ZILL_DUE.RPT'.
EXIT PROGRAM.
B000-HSK。
调用“COB_FILL_IN_LOGICALS”。
MOVE SPACES TO STATUS-VARIABLES.
ACCEPT TODAYS-DATE FROM DATE YYYYMMDD.
MOVE TODAY_YYYY TO FMT_YYYY.
MOVE TODAY_DD TO FMT_DD.
MOVE TODAY_MM TO FMT_MM.
OPEN OUTPUT RPT-FILE.
MOVE SPACES TO REPORT-HDR1.
MOVE TODAYS-DATE-FORMATTED TO THE-DATE.
MOVE 'Due Number Report' to PAGE-TITLE.
MOVE SPACES TO REPORT-HDR2.
MOVE 'Drawing Numbers' TO GROUP-TITLE.
- 处理排序后的选择文件的段落和
- 创建与绘图相关的报告部分
- 号码。
B010-报告-图纸-编号。
MOVE SPACES TO EOF-FLAG.
OPEN INPUT SORTED-FILE.
READ SORTED-FILE
AT END SET IT-IS-END-OF-FILE TO TRUE.
PERFORM C010-DRAWING-HEADINGS.
PERFORM UNTIL IT-IS-END-OF-FILE
MOVE SPACES TO REPORT-DETAIL
MOVE ELM_NO IN SORTED-REC TO ELM-NO-DTL
MOVE HIT_COUNT IN SORTED-REC TO HIT-COUNT-DTL
MOVE SINCE_LAST IN SORTED-REC TO SINCE-LAST-DTL
MOVE PCT_HITS IN SORTED-REC TO PCT-HITS-DTL
MOVE AVE_BTWN IN SORTED-REC TO AVE-BTWN-DTL
MOVE REPORT-DETAIL TO RPT-DTL
WRITE RPT-DTL BEFORE ADVANCING 1 LINE
READ SORTED-FILE
AT END SET IT-IS-END-OF-FILE TO TRUE
END-READ
END-PERFORM.
CLOSE SORTED-FILE.
C010-绘图-标题。
MOVE SPACES TO RPT-DTL.
MOVE REPORT-HDR1 TO RPT-DTL.
WRITE RPT-DTL BEFORE ADVANCING 2 LINES.
MOVE SPACES TO RPT-DTL.
MOVE REPORT-HDR2 TO RPT-DTL.
WRITE RPT-DTL BEFORE ADVANCING 1 LINE.
MOVE SPACES TO RPT-DTL.
MOVE REPORT-HDR3 TO RPT-DTL.
WRITE RPT-DTL BEFORE ADVANCING 1 LINE.
MOVE SPACES TO RPT-DTL.
MOVE REPORT-HDR4 TO RPT-DTL.
WRITE RPT-DTL BEFORE ADVANCING 1 LINE.
- 用于将到期编号过滤到排序文件中的段落。
- 创建一个临时浮点进行比较
- 输入文件中的浮点值。当更大时
- 记录被释放到排序文件。
S000-DSTAT-输入。
OPEN INPUT DRAW-STATS.
READ DRAW-STATS NEXT
AT END SET IT-IS-END-OF-FILE TO TRUE.
PERFORM UNTIL IT-IS-END-OF-FILE
MOVE SINCE_LAST IN DSTATS-REC TO FLT-1
IF FLT-1 >= AVE_BTWN IN DSTATS-REC
MOVE DSTATS-REC TO SORT-REC
RELEASE SORT-REC
END-IF
READ DRAW-STATS
AT END SET IT-IS-END-OF-FILE TO TRUE
END-READ
END-PERFORM.
CLOSE DRAW-STATS.
- 用于将到期编号过滤到排序文件中的段落。
- 创建一个临时浮点进行比较
- 输入文件中的浮点值。当更大时
- 记录被释放到排序文件。
S001-MSTAT-输入。
OPEN INPUT MEGA-STATS.
READ MEGA-STATS NEXT
AT END SET IT-IS-END-OF-FILE TO TRUE.
PERFORM UNTIL IT-IS-END-OF-FILE
MOVE SINCE_LAST IN MSTATS-REC TO FLT-1
IF FLT-1 >= AVE_BTWN IN MSTATS-REC
MOVE MSTATS-REC TO SORT-REC
RELEASE SORT-REC
END-IF
READ MEGA-STATS
AT END SET IT-IS-END-OF-FILE TO TRUE
END-READ
END-PERFORM.
CLOSE MEGA-STATS.
结束程序 COB_ZILL_DUE_REPORT_SUB。
抱歉,“代码”功能在此编辑器中的工作方式。
某些部分必须存在。如果没有 INPUT-OUTPUT SECTION,您的程序将无法执行 I-O。这是您将名称映射到物理存储的地方。
如果你有一个 INPUT-OUTPUT SECTION 那么你必须有一个 FILE SECTION。这是您定义每个命名文件的记录布局的地方。 LABEL RECORDS 在处理磁盘数据文件时始终为 STANDARD,在编写报告文本文件时为 OMITTED。还有一些条款我不记得了。请注意所有这些 FD 声明中包含的 SD。 FD 是文件定义,SD 是排序定义。
如果您要使用任何局部变量,则必须有一个 WORKING-STORAGE SECTION。您不能即时声明变量,它们都必须在此处声明。此 PSECT 获得 DATA 段属性等。如果您调用了某个服务或某事并且它的地址不正确,那么尝试在此 PSECT 中执行代码,操作系统会将您的应用程序从鞍座中删除。
在 PROCEDURE DIVISION 之后创建的所有 PSECT 都标记为 EXEC,写保护。如果您在执行期间尝试覆盖此处的任何内容,操作系统会将您的程序从鞍座中删除。任何其他试图在这里编写的程序也将被淘汰。
向下扫描到 A000-MAIN 中的 SORT SORT-FILE。 COBOL 排序例程非常棒。请注意,我提供了一个 INPUT PROCEDURE,它是一个段落。在当时运行 ROSCOE 的 IBM 大型机上,这必须是 INPUT SECTION。他们需要 PSECT 上的不同属性,以便系统排序例程可以读/写。
这是那本书中另一个程序的一个 sn-p。
*
* FMS 定义
*
复制“MEGA_TEXT_LIB”的“COBFDVDEF”。
链接部分。
01 FMS-STUFF.
05 FMSSTATUS PIC S9(9) COMP.
05 RMSSTATUS PIC S9(9) COMP.
05 TCA PIC X(12).
05 WORKSPACE PIC X(12).
使用 FMS-STUFF 进行程序划分。
链接部分创建共享内存的 PSECT。当您调用返回值的外部例程时,它们需要在此处。您还必须授予您的 PROCEDURE DIVISION 访问链接部分所需的各种内容。
你可以在后面的代码中从这个 sn-p 看到
B010-USER-INPUT.
PERFORM C000-FORWARD-LOAD
CALL 'FDV$PUTAL' USING BY DESCRIPTOR SCREEN-REC.
MOVE SPACES TO WORK-STR.
CALL 'FDV$GETAL' USING BY DESCRIPTOR WORK-STR
BY REFERENCE TERMINATOR.
EVALUATE TERMINATOR
WHEN FDV$K_FK_E6 SET LOAD-FORWARD TO TRUE
WHEN FDV$K_FK_E5 SET LOAD-REVERSE TO TRUE
WHEN FDV$K_FK_F10 SET WE-ARE-DONE TO TRUE
END-EVALUATE.
只要你正确传递它,你可以传递任何你想要的局部变量。这是需要特殊PSECT属性的写作。
已经很晚了,我很累,但我似乎记得您可以在 PROCEDURE DIVISION 中的 SECTION 声明中使用 USING 子句。可用于 COBOL 的在线文档,至少被 GOOGLE 索引的文档确实是毫无价值的。如果您想要更详细的信息,请搜索大约 1980 年代的 COBOL 教科书。它不会有任何新东西,但会回答很多问题。
这是kind of bad tutorial on COBOL structure。