如何在大型机汇编程序中对一对带有“+”或“-”前缀的传递值求和?

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?

如何在 Matplotlib 中使用带有大型数组的网格网格?

C++ Primer 5th笔记(chap 18 大型程序工具)命名空间特性