如何在大型机汇编程序中对一对带有“+”或“-”前缀的传递值求和?
Posted
技术标签:
【中文标题】如何在大型机汇编程序中对一对带有“+”或“-”前缀的传递值求和?【英文标题】:How to Sum a Pair of Passed Values Having a '+' or '-' Prefix in Mainframe Assembler? 【发布时间】:2017-03-15 14:18:53 【问题描述】:我有一个 COBOL 程序,它读取一个文件,该文件包含字符格式的右对齐数值对,最长为 15 位,每个都带有前导符号,没有前导零。例如:
Value One Value Two Result
----+----1----+----2----+----3----+----4----+----5----+
+123456789012345 -123456789012345 0
-2345 +5432 +3087
+543210987 -789012345 -245801358
+999999999999999 -888888888888888 +111111111111111
我需要一个 Assembler 子例程来计算这些值的总和并返回结果。任何人都可以发布一个示例汇编程序子例程吗?
【问题讨论】:
与任何其他语言一样,将其划分为子“问题”:当文件不是 eof 时,读取一行,跳过前导空格,获取符号,将 ascii 字符串解码为二进制值,根据符号从总和中添加/减去它 【参考方案1】:我假设这里的目标是将 EBCDIC 字符串转换为压缩(或可能未压缩)十进制字符串。我还假设 IBM 大型机是指具有 370/390 指令集的东西。
假设这是家庭作业,您应该有机器级打包(或解包)十进制格式的文档。对于压缩十进制,最后一个“半字节”将包含“符号”。您还可以进行网络搜索以查找文档。由于我不确定您使用的是哪个大型机,我建议您进行网络搜索,而不是发布一个可能无用的链接。
我不确定这是否是一个问题,但如果您需要的指令具有需要可变的固定值操作数(如字符串大小),请使用执行指令用变量覆盖该固定值操作数操作数。
要将压缩十进制转换回 EBCDIC,请使用编辑和标记类型指令。我不记得 EBCDIC 是用什么来打包十进制的。
【讨论】:
【参考方案2】:解决方案:
SAMPLE CSECT
SAVE (14,12) SAVE CALLER REGS
LR 12,15 R12 = BASEREG
USING SOSAMP,12
SR 2,2 R2 = 0
LM 3,5,0(1) R3->NUM1,R4->NUM2,R5->ACCUM OUT
LM 6,9,0(3) SAVE NUM1 CHARS IN R6-R9
*
TRT 0(16,3),HEXTBL FIND THE '+' OR '-' CHAR IN NUM1
MVI 0(1),X'40' OVERLAY WITH SPACE
EX 2,SIGN1 SET NUM1 SIGN ACCORDING TO '+' OR '-'
*
TRT 0(16,4),HEXTBL FIND THE '+' OR '-' CHAR IN NUM2
MVI 0(1),X'40' OVERLAY WITH SPACE
EX 2,SIGN2 SET NUM2 SIGN ACCORDING TO '+' OR '-'
*
PACK 8(8,3),0(16,3) PACK NUM1
PACK 0(8,3),0(16,4) PACK NUM2
LA 0,C'+' R0 = C'+' (ASSUMES POSITIVE RESULT)
AP 0(8,3),8(8,3) SUM NUM1 + NUM2
BNM GOEDMK IF POSITIVE, GO
LA 0,C'-' ELSE R0 = C'-'
GOEDMK MVC 0(16,5),EDPAT MOVE EDIT PATTERN TO RESULT
EDMK 0(16,5),0(3) EDIT AND MARK RESULT
BZ RETURN IF ZERO, RETURN
BCTR 1,0 ELSE R1 MINUS 1
STC 0,0(1) STORE SIGN OF RESULT
RETURN SR 15,15 SET RETURN CODE = ZERO
STM 6,9,0(3) RESTORE NUM1 CHARS FROM R6-R9
RETURN (14,12),RC=(15) RETURN
SIGN1 NI 15(3),X'00'
SIGN2 NI 15(4),X'00'
EDPAT DC X'40202020202020202020202020202120'
HEXTBL DC 256X'00'
ORG HEXTBL+C'+'
DC X'CF'
ORG HEXTBL+C'-'
DC X'DF'
ORG
END
用于测试的 COBOL“驱动程序”程序:
IDENTIFICATION DIVISION.
PROGRAM-ID. SAMPLEC.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT INFILE ASSIGN INFILE.
SELECT OUTFILE ASSIGN OUTFILE.
DATA DIVISION.
FILE SECTION.
FD OUTFILE RECORDING MODE F.
01 OUTREC.
05 PIC X(38).
05 RSLT PIC X(16).
FD INFILE RECORDING MODE F RECORD CONTAINS 0.
01 INREC.
05 NUM1 PIC X(16). 05 PIC X(3).
05 NUM2 PIC X(16). 05 PIC X(3).
05 PIC X(16).
WORKING-STORAGE SECTION.
01. 05 SAMPLE PIC X(8) VALUE 'SAMPLE'.
05 PIC X VALUE 'N'. 88 EOF VALUE 'Y'.
05 HEADING1 PIC X(52) VALUE
' Value One Value Two Result'.
05 HEADING2 PIC X(55) VALUE
'----+----1----+----2----+----3----+----4----+----5----+'.
PROCEDURE DIVISION.
OPEN INPUT INFILE OUTPUT OUTFILE
WRITE OUTREC FROM HEADING1
WRITE OUTREC FROM HEADING2
PERFORM READ-INFILE
PERFORM UNTIL EOF
MOVE INREC TO OUTREC
CALL SAMPLE USING NUM1, NUM2, RSLT
WRITE OUTREC
PERFORM READ-INFILE
END-PERFORM
GOBACK.
READ-INFILE. READ INFILE AT END SET EOF TO TRUE END-READ.
还有一些 JCL 来运行 COBOL 驱动程序:
//<jobname> JOB
//JOBLIB DD DISP=SHR,DSN=<sample load library>
// EXEC PGM=SAMPLEC
//OUTFILE DD SYSOUT=*
//INFILE DD *
+123456789012345 -123456789012345
-2345 +5432
+543210987 -789012345
+999999999999999 -888888888888888
/*
//
【讨论】:
请解释您的解决方案 解释,第一部分:问题的关键是识别每个传入字符串中的符号字符并设置相应的值,以便系统将其识别为有符号数。 TRT 很好地做到了这一点,在这种情况下,使用转换表,其中符号字符:“+”和“-”被转换为适当的掩码值:X'CF'和 X'DF',用于将字符串转换为有符号数. 这些有助于理解答案。您应该考虑将它们添加到答案中,而不是将它们添加为 cmets 解释,第二部分:序列:TRT、MVI、EX 对每个字符串执行此操作,为 PACK 和 AP 操作做准备,获得对的总和。子例程的其余部分将总和放在传递的“结果”字段中,根据结果的符号在其前面加上“+”或“-”字符。 COBOL 驱动程序和 JCL 只是将数据提供给子例程以进行测试。以上是关于如何在大型机汇编程序中对一对带有“+”或“-”前缀的传递值求和?的主要内容,如果未能解决你的问题,请参考以下文章
如何在python中对没有标题的大型csv信号文件进行分类?
在 SQL Server 中对大型表进行分区的最佳方法是啥?
如何在 PySpark 中的大型 Spark 数据框中对行的每个子集进行映射操作
Open Graph 命名空间声明:带有 XMLNS 或 head 前缀的 HTML?