我预计以下 COBOL 程序中的 ADD 指令会触发 ABEND S0C7。然而程序正常终止并且输出非常令人惊讶。
JCL 中的 SYSIN
//SYSIN DD *
5
//* There is only the character 5 in the SYSIN (well, followed by a newline character of course)
COBOL 程序
WORKING-STORAGE SECTION.
77 X PIC 9(10).
PROCEDURE DIVISION.
ACCEPT X
* This addition did not trigger an ABEND S0C7
ADD 1 TO X
DISPLAY 'X = ' X
STOP RUN
.
输出
X = 5000000001
然后我在调试器中运行该程序
ACCEPT 语句在 X 最左边的字符中移动了“5”,并在右侧的其他字符中移动了空格。更具体地说,接受后 X 看起来像这样:
'9 ' <-- These are the 10 characters of X
0987654321 <-- These are the bytes numbered for clarity
我想也许我的调试器的 X 显示有一个错误,并显示空格字符而不是零,但没有。我检查了 X 处的内存,它确实包含了 9 个字节,值为 0x40,这确实是 EBCDIC 中的“ ”字符。
然后我检查了编译器生成的程序集
好吧,我忘记复制工作时机器的确切输出,但这是伪语言的汇编代码。
* ADD 1 TO X
PACK XP, X * Pack X to XP
AP XP, ONEP * XP += 1
UNPK XP, X * Unpack XP to X
那么,我在这里错过了什么?
感谢您的帮助。
编辑 #1 - 2 月 26 日 - 我检查了确切的汇编代码
周一早上。从我工作的机器上获取汇编代码...
* ADD 1 TO X
PKA 672(R13),152(10,R9) PACK ASCII Y,X
AP 682(6,R13),1072(1,R13) ADD PACKED Y,1
UNPK 152(10,R9),682(6,R13) UNPACK X,Y
OI 161(,R9),X'F0'
...并且使用了编译选项 ZONEDATA(NOPFD)。
所以你正在使用分区十进制:
77 X PIC 9(10).
当您在输入中看到 c'9 ' 时,实际字节值是 x'F910F0F0F0F0F0F0F0F0'。仅考虑低半字节,因此这是有效的数值数据。
(同样的事情也适用于 ASCII,但范围是 x'30313233343536373839',但想法相同。除了符号字节之外,只使用低半字节。)
如您所见,您没有得到预期的输出,因为您直接接受到一个变量,该变量可以处理您向其抛出的分区十进制数据。
我觉得在这种情况下你需要清理你的输入。把它们放在一个字符串中,确保你有你想到的数字,并且只有你想到的数字,并确保你有正确的右对齐。