为什么在某些应用程序中使用这样的代码而不是MOVE?
add 16 to ZERO giving SOME-RESULT
我在一些专业编写的代码中发现了这一点。Sorce在这个页面
为什么在某些应用程序中使用这样的代码而不是MOVE
add 16 to ZERO giving SOME-RESULT
在没有看到更多代码的情况下,它似乎是IBM汇编程序到COBOL的翻译。特别地,ZAP
(Zero and Add Packed)指令可以从字面上转换为上述指令,特别是如果SOME-RESULT
是COMP-3
。因此,检查翻译的人可以看到ZAP
指令被忠实地翻译了。
或者,这可能是汇编程序程序员的一个笑话。
看过代码后,我还注意到的使用
subtract some-data-item from some-data-item
它被用来代替
move zero to some-data-item
这与IBM Assembly中使用的压缩十进制字段的操作一致;"柔性";移动。所谓灵活,我的意思是压缩十进制指令包含一个长度字段,因此不需要使用特定大小的MVC
指令。
这种特殊的风格不同寻常,可能与抓住侵犯版权的行为有关。
根据我的经验,我确信我知道程序员会这么做的原因。这与数字的二进制表示有关。
我打赌SOME-RESULT
是packed-decimal
(或COMP-3
)格式的数字。假设该字段的定义如下
05 SOME-RESULT PIC S9(5) COMP-3.
这导致了一个3字节的字段,其十六进制表示方式类似于
x'00016C'
十进制数字编码为二进制编码的十进制(BCD,每半字节一个十进制数字),最后半个字节保持符号。
让我们来看看符号是如何定义的:
- 如果它是x'C',x'A',x'F',x'E'(咖啡馆)中的一个,那么这个数字是正数
- 如果它是x'B',x'D'中的一个,那么这个数字就是负数
- x"0"..中的任意一个x‘9’不是有效的符号,所以我们可以区分有符号压缩小数和无符号小数
然而,分区编号(PIC 9(5) DISPLAY
)(如源代码中所示)看起来如下:
x'F0F0F0F1F6'
正如您所看到的,每个十进制数字都是一个EBCDIC字符,"区域"部分(前半个字节)始终是x'F'。
现在我们离你的问题越来越近了!
当我们使用时会发生什么
MOVE 16 TO SOME-RESULT
如果您只将一个数字MOVE
添加到这样的字段中,这将导致在机器代码级别上被编译为PACK
指令。
PACK SOME-RESULT,=C'16'
pack指令获取分区编号,并通过只选取每个字节的后半个字节并将其存储在打包编号的半个字节中来对其进行打包,只有一个例外!当涉及到最后一个字节时,它只需翻转两个半字节,并将它们存储在小数的最后半个字节中。
这意味着分区小数的最后一个字节的区域成为压缩小数中的符号:
x'00016F'
现在我们有一个x'F'作为符号,这是一个有效的正号
然而,如果使用这个Cobol指令而不是会发生什么
ADD 16 TO ZERO GIVING SOME-RESULT
这编译成多个机器级指令
PACK SOME_RESULT,=C'0'
PACK TEMP,=C'16'
AP SOME_RESULT,TEMP
(或类似的-关键是在某个地方需要AP
)
这对结果产生了轻微的影响,因为AP
(加法压缩)指令总是将结果符号设置为x'C'(表示正结果)或x'D'(表示负结果)。
所以区别在于符号
x'00016C'
最后,问题是,为什么会产生这种差异?毕竟,x'F'和x'C'都是有效的正号。那为什么在乎呢?
有一种情况下,这种微小的差异可能会导致大问题:当压缩小数是索引键的一部分时,即使数字在语义上相同,我们也不会得到匹配!
因为这种情况经常发生在像VSAM和DL/I(后来的IMS/DB)这样的旧数据库中;归一化";压缩小数,如果它们是索引键的一部分。
然而,一些程序员在不知道为什么的情况下采用了这种做法,所以你可能会遇到使用这种";归一化";即使数据不用于索引键。
您可能还想知道为什么编译器不优化ADD 16 TO ZERO
。我很确定它曾经这样做过,但这破坏了很多应用程序,所以这个特定的优化再次被删除,或者至少成为了一个带有警告的非默认选项。
其他有用信息
请注意,如果使用LIST
编译选项(请参阅此示例输出),至少Enterprise Cobol for z/OS编译器允许您准确地查看源代码生成的机器代码。我建议始终使用选项LIST, MAP, OFFSET, XREF
进行编译,因为即使只有来自异常终止的程序转储,这些选项也可以在Cobol源中找到确切的问题。
无论如何,良好的编程实践不是关心编译器或机器代码,而是关心其他必须维护的程序员,从而阅读和理解代码。良好的做法是始终喜欢简单易读的说明,并在偏离此规则时记录原因(在代码中)。
有些程序员喜欢做一些事情"只是因为他们可以";。我有一种感觉,这就是你在这里看到的。这和做一样有意义
a := 0 + b
会去的。