Comparing two DC - S0C1



High Level Assembler(HLASM) for MVS & VM & VSE

Comparing two DC - S0C1

Postby thermaltaker » Sat Oct 27, 2018 1:33 am

Hello friends,

I trying compare two DC. But i getting S0C1.. I don't know what is wrong, I was debugging many of hours but still same issue.. :oops:

COMPARE  CSECT                          
R0       EQU   0                        
R1       EQU   1                        
R2       EQU   2                        
R3       EQU   3                        
         USING *,12                      
         SAVE  (14,12),,*                
         SR    R2,R2                    
         SR    R3,R3                    
         USING *,R2                      
         LA    R2,VALUE1                
         L     R3,0(R0,R2)              
         CLC   0(R0,R3),VALUE2          
         BNE   EXIT1                    
*                                        
EXIT     WTO   'EQUAL'                  
         B     RET                      
*                                        
EXIT1    WTO   'NOT EQUAL'              
RET      RETURN (14,12),T,RC=0          
*                                        
         EJECT                          
VALUE1   DC    F'2'                      
VALUE2   DC    F'1'                      
         END                            
thermaltaker
 
Posts: 4
Joined: Sat Oct 27, 2018 1:20 am
Has thanked: 0 time
Been thanked: 0 time

Re: Comparing two DC - S0C1

Postby willy jensen » Sat Oct 27, 2018 1:50 am

Where to start?
1. You do not set up a proper base register
2. you have a second using 'USING *,R2'. My assembler throws a warning,I believe yours do too?
3. you load r3 from where r2 points to, which is x'00000000' as you just cleared r2 and set it as base.
4. your use of r0 as index and length don't make any sense'
But your 0C1 is caused by the ' BNE EXIT1 ' because r2 is defined as you base and contains zeroes so you are jumping to low core.

I strongly suggest that you find a proper manual with some good samples.
willy jensen
 
Posts: 467
Joined: Thu Mar 10, 2016 5:03 pm
Has thanked: 0 time
Been thanked: 70 times

Re: Comparing two DC - S0C1

Postby willy jensen » Sat Oct 27, 2018 2:48 am

Ok, just this once, but the sample is really not much use. For starters it does not set it's own save area.
COMPARE  CSECT                  
R0       EQU   0                
R1       EQU   1                
R2       EQU   2                
R3       EQU   3                
R12      EQU   12                
R15      EQU   15                
                                 
         SAVE  (14,12),,*        
         lr    r12,r15           basereg
         using compare,12    
         clc   value1,value2      
         BNE   EXIT1            
*                                
EXIT     WTO   'EQUAL'          
         B     RET              
*                                
EXIT1    WTO   'NOT EQUAL'      
RET      RETURN (14,12),T,RC=0  
*                                
VALUE1   DC    F'2'              
VALUE2   DC    F'1'              
         END                    
willy jensen
 
Posts: 467
Joined: Thu Mar 10, 2016 5:03 pm
Has thanked: 0 time
Been thanked: 70 times

Re: Comparing two DC - S0C1

Postby steve-myers » Sat Oct 27, 2018 6:43 am

Mr. Jensen is correct about the save area, but as you have discovered from trying Mr. Jensen's example it is not always necessary to obtain a new save area.

As written Mr. Jensen's program is guilty of one minor sin. It saves and restores too many registers. It does not use registers 2, 3, 4, 5, 6, 7, 8, 9, 10 and 11. Saving and restoring registers is the most expensive part of program linkage. In this program register 2 is a better candidate for the base register: the SAVE and RETURN macros store the registers in order starting with register 14, so it saves them in the order 14, 15, 0, ... 12. Specify SAVE (14,2) and RETURN (14,2) to save and restore just 5 registers rather than 15. You won't really see anything here, but if you should run this code millions of times you will see a difference

Your use of CLC is fine for equal / not equal, but if you need less than or greater than CLC won't work reliably.
         LM    14,15,VALUES
         CR    14,15
         LA    1,LESS
         BL    DOWTO
         LA    1,EQUAL
         BE    DOWTO
         LA    1,HIGH
DOWTO    WTO   MF=(E,(1))
         ...
VALUES   DC    0F'0'
VALUE1   DC    F'2'
VALUE2   DC    F'3'
LESS     WTO  'VALUE 1 IS LESS THAN VALUE 2',MF=L
EQUAL    WTO  'VALUE 1 IS EQUAL TO VALUE 2',MF=L
HIGH     WTO  'VALUE 2 IS GREATER THAN VALUE 2',MF=L

Many people discourage using the so called linkage registers (registers 0, 1, 14 and 15), but they are great when you need registers for just a couple of instructions like here.

Finally, what is this MF= stuff on the WTO macros? There are two parts of a traditional WTO macro: the code to send the message to the system, and the message. In WTO 'message' both parts are combined into one code block, but it is possible to separate them. WTO MF=(E,message) just creates the code to send the message to the system, and MF=L defines the message.
steve-myers
Global moderator
 
Posts: 2105
Joined: Thu Jun 03, 2010 6:21 pm
Has thanked: 4 times
Been thanked: 243 times

Re: Comparing two DC - S0C1

Postby thermaltaker » Sat Oct 27, 2018 11:08 am

Hello Mr. Jensen, hello Mr. Myers,

my main problem is that i don't understand what is base-register. I read many web pages where is explanation of base registr.. But still I don’t know for what is useful this register.

Yes, my compilator was have RC 4.. But I ignore it, because of many examples it was same situation.. I was think that is ok..

Thank you again for explanation. Today I will try write again anything and I will see. I must understand base register. Your code is very useful for me. I hope that I not get S0C1 when I will try to run him..
thermaltaker
 
Posts: 4
Joined: Sat Oct 27, 2018 1:20 am
Has thanked: 0 time
Been thanked: 0 time

Re: Comparing two DC - S0C1

Postby Robert Sample » Sat Oct 27, 2018 6:15 pm

But still I don’t know for what is useful this register.
In order to access memory (L, ST, CLC instructions for example), you must be able to address it -- which merely means you have to know its address (memory starts at byte 0 and goes through whatever the highest byte is). A base register establishes a base address and memory access instructions will then use an offset from the base register to determine the memory address of a particular byte. In classic assembler, a base register can be used to access up to 4096 bytes of memory (the offset is 3 bytes so X'000' through X'FFF' are the possible offsets).
000014 4120 F060            00060    15          LA    R2,VALUE1
in this line from an assembly, the operation code is 41, the register being loaded is 2, there is no offset from register 2 (hence 0), the address of VALUE1 is X'060' from the base register which is 15 (X'F').
Robert Sample
Global moderator
 
Posts: 3720
Joined: Sat Dec 19, 2009 8:32 pm
Location: Dubuque, Iowa, USA
Has thanked: 1 time
Been thanked: 279 times

Re: Comparing two DC - S0C1

Postby steve-myers » Sat Oct 27, 2018 8:36 pm

The first computer I used, back when dinosaurs really did rule was the IBM 7040. The 7040 was the trailing end of a computer architecture that started back in the dim mists of (almost) pre history when the switching circuits were ruled by vacuum tubes. One of the important reasons for the success (140 were made) of the 704 was its gigantic (for the day) 32K words of memory. No doubt there were people wondering how they could use all that memory!

There were two problems that ultimately led to the collapsed of the architecture. By the early 1960s it was clear much, much more memory would be required in the future. There were one off extensions that got 64K words of memory using bank switching, but, at best, this is a terribly clumsy way to add memory. The other problem is each instruction that addressed memory had a 15 bit field with the storage address of the data. Every time a program was loaded into memory these data addresses had to be relocated to contain the actual storage address of the data the instruction used. This was painfully slow.

Now, let's look at a System/360 program.
  Loc  Object Code    Addr1 Addr2  Stmt   Source Statement

000000                00000 0006C     1 BASEREG  CSECT
                                      2          SAVE  (14,2)
000000                                4+         DS    0H
000000 90E2 D00C            0000C     5+         STM   14,2,12(13)
000004 0520                           6          BALR  2,0
                 R:2  00006           7          USING *,2
000006 41F0 201E            00024     8          LA    15,SAVEAREA
00000A 50D0 F004            00004     9          ST    13,4(,15)
00000E 50F0 D008            00008    10          ST    15,8(,13)
000012 18DF                          11          LR    13,15
                                     12 * YOUR PROGRAM LOGIC GOES HERE!
000014 58D0 D004            00004    13          L     13,4(,13)
                                     14          RETURN (14,2),RC=0
000018 98E2 D00C            0000C    16+         LM    14,2,12(13)
00001C 41F0 0000            00000    17+         LA    15,0(0,0)
000020 07FE                          18+         BR    14
000022 0000
000024 0000000000000000              19 SAVEAREA DC    18F'0'
000000                               20          END   BASEREG


In this program SAVE and RETURN are macro calls: a "macro" is instructions to the Assembler (the program that translates source code to binary data for the computer) to generate addition code. This SAVE macro just generates one real instruction: STM 14,2,12(13). The convention in System/360 is register 13 contains the address of a save area, which is just a data area used to store registers.

BALR 2,0
USING *,2
LA 15,SAVEAREA
ST 13,4(,15)
ST 15,8(,13)
LR 13,15

The BALR instruction is normally used to call another program: this BALR instruction stores the address of the next instruction in register 2, but it does not actually go to another program because register 0 cannot be used for that purpose.

The USING instruction is a directive to the Assembler program. The USING instruction is the programmer promising the Assembler program that register 2 contains the current address.

LA 15,SAVEAREA

The LA (Load Address) instruction is a machine instruction that tells the computer to compute the address of SAVEAREA. 41F0201E is the binary data that the computer uses. 41 is the data the computer interprets as Load Address. F is register 15, where the computer will store the address, and 201E is the "address;" 2 is register 2, the base register, and 01E is the factor to add to the base register. The 01E was calculated by the Assembler program by using the address supplied by the USING instruction and the data address, 00024, supplied by the programmer and effectively determined by the Assembler: 24 - 6 = 01E. Back in 1968, when I understood what was going on I immediately saw 2 advantages compared to the IBM 704 tradition. First, the base register had a much larger potential address than the measly 32K of the 704. The second is once calculated by the Assembler this 01E was fixed. The system could load the program anywhere in storage without altering anything in the program.

The Assembler program is wonderfully flexible. You can specify the base register and offset directly without making the Assembler compute the offset. This is what ST 13,4(,15) is doing.

Many instructions do not require the Assembler (or the machine) to compute an address: this is what the BALR and LR instructions do in our little program.

Nothing is "free" in this scheme. Most instructions require the computer to do arithmetic to compute a data address in every instruction, and this has the effect that the computer runs slower. Perhaps 10 years later when virtual memory came in you had nay sayers grumbling about the computational cost of the extra arithmetic required under the covers for the virtual memory to work.
steve-myers
Global moderator
 
Posts: 2105
Joined: Thu Jun 03, 2010 6:21 pm
Has thanked: 4 times
Been thanked: 243 times

Re: Comparing two DC - S0C1

Postby enrico-sorichetti » Sat Oct 27, 2018 9:24 pm

cheers
enrico
When I tell somebody to RTFM or STFW I usually have the page open in another tab/window of my browser,
so that I am sure that the information requested can be reached with a very small effort
enrico-sorichetti
Global moderator
 
Posts: 3006
Joined: Fri Apr 18, 2008 11:25 pm
Has thanked: 0 time
Been thanked: 165 times

Re: Comparing two DC - S0C1

Postby willy jensen » Sun Oct 28, 2018 3:28 am

program is guilty of one minor sin. It saves and restores too many registers

;) Untill the day when you use one more register in your program and forget to change the SAVE or the RETURN. I prefer to stick with the defined standard. Then again, with assembler you are supposed to know what you are doing. Just be careful.
willy jensen
 
Posts: 467
Joined: Thu Mar 10, 2016 5:03 pm
Has thanked: 0 time
Been thanked: 70 times

Re: Comparing two DC - S0C1

Postby steve-myers » Sun Oct 28, 2018 5:40 am

willy jensen wrote:... I prefer to stick with the defined standard. ...

SAVE (14,12) is hardly a "defined standard." It's what instructors established 50+ years ago. The best that can be said for it is it's reliable.
willy jensen wrote:...Just be careful.

No argument. I have a small, semi standardized, internal process that I typically write from scratch in many programs. It's roughly one page. It starts with SAVE (14,4). Now that's fine. The register usage is dead on. But all to often, out of habit, I write RETURN (14,12) at the end. Oops.

IBM spent I don't know how many millions developing XPLINK, in part because SAVE (14,12) / RETURN (14,12) sucked up too many cycles and IBM got caught when the LE standard which uses, in effect, SAVE (14,12) / RETURN (14,12), was adopted in the C++ environment. This is a lesson that applies to all of us.
steve-myers
Global moderator
 
Posts: 2105
Joined: Thu Jun 03, 2010 6:21 pm
Has thanked: 4 times
Been thanked: 243 times

Next

Return to Assembler

 


  • Related topics
    Replies
    Views
    Last post