Internal and External subroutines?



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

Internal and External subroutines?

Postby sudeepth » Thu Mar 13, 2014 2:21 pm

Hi ,
I did not understand a lot from the assemblers class. I would like to know in detail about the subroutines and example. I want to study about this online, can anyone suggest me some websites where I can learn about the subroutines.
sudeepth
 
Posts: 6
Joined: Thu Mar 13, 2014 2:13 pm
Has thanked: 1 time
Been thanked: 0 time

Re: Internal and External subroutines?

 

Re: Internal and External subroutines?

Postby dick scherrer » Fri Mar 14, 2014 12:52 am

Hello and welcome to the forum,

It is not clear what you are looking for (we,, not to me, anyway 8-).

Suggest you find a book about writing assembler rather than trying to learn using the reference manuals. The manuals are great for what the have, but seldom are they good as a tutorial.

If you have some code that you are not sure about, post it here and someone may be able to help. It is ok of this code is from a book, just mention this when posting. We should be able to help.
Hope this helps,
d.sch.
User avatar
dick scherrer
Global moderator
 
Posts: 6304
Joined: Sat Jun 09, 2007 8:58 am
Has thanked: 3 times
Been thanked: 92 times

Re: Internal and External subroutines?

Postby steve-myers » Fri Mar 14, 2014 6:20 am

A subroutine is just a routine that performs a service for some other routine.

An internal subroutine is just a subroutine that is in the same program as the routine that uses it and often uses an abbreviated calling sequence. An internal subroutine is usually just a few lines of code.

An external subroutine is a subroutine that is external to the program that uses it. That means it is assembled separately from the program that uses it. It is usually much larger than an internal subroutine. It is often statically linked with the routine that uses it.

For example, I often want a program to have an optional DD statement for some reason. However, I don't want to expose the DD statement if it is not provided, so I don't want to even attempt to open it if it isn't there. In other words, no IEC130I message when the program is run. So I wrote a small subroutine to test if a DD statement is present. The input to the subroutine is the parameter list created by an OPEN macro so I can test multiple DD statements. As an internal subroutine it is coded like this -
         CNOP  0,8
TESTDD   BASR  15,0
         SAVE  (14,3),,TESTDD
         LR    2,1
         SR    3,3
TDD0100  L     1,0(,2)
         N     1,=A(X'FFFFFF')
         DEVTYPE DCBDDNAM-IHADCB(,1),64(,13)
         LTR   15,15
         JZ    TDD0200
         LHI   3,4
TDD0200  TM    0(2),X'80'
         LA    2,4(,2)
         JZ    TDD0100
         LR    15,3
         RETURN (14,3),T,RC=(15)

It is called like this -
         LA    1,OPENPARM
         BAS   14,TESTDD
         ...
OPENPARM OPEN  (ADCB,INPUT),MF=L
ADCB     DCB   DDNAME=SYSIN,...


As an external subroutine, the code for TESTDD would be a little different.
TESTDD   CSECT
         SAVE  (14,3),,TESTDD
         LR    2,1
         SR    3,3
TDD0100  L     1,0(,2)
         N     1,=A(X'FFFFFF')
         DEVTYPE DCBDDNAM-IHADCB(,1),64(,13)
         LTR   15,15
         JZ    TDD0200
         LHI   3,4
TDD0200  TM    0(2),X'80'
         LA    2,4(,2)
         JZ    TDD0100
         LR    15,3
         RETURN (14,3),T,RC=(15)
         DC    0D'0'
         LTORG ,
         DCBD  DSORG=QS,DEVD=DA
         END   ,


There are a number of different ways to call an external subroutine. For example, if it is statically linked, it might be called like this -
         CALL  TESTDD,MF=(E,OPENPARM)
         ...
OPENPARM OPEN  (ADCB,INPUT),MF=L
ADCB     DCB   DDNAME=SYSIN,...


You can also call it dynamically, perhaps like this -
         LINK  EP=TESTDD,MF=(E,OPENPARM)
         ...
OPENPARM OPEN  (ADCB,INPUT),MF=L
ADCB     DCB   DDNAME=SYSIN,...


The advantage of calling it dynamically is if you should discover a mistake, you can correct the mistake, and the revised version would be used the next time the subroutine is used. On other hand, since the system must locate and actually load TESTDD when it is used, it is much slower than using a static call.

These users thanked the author steve-myers for the post:
sudeepth (Fri Mar 14, 2014 9:08 am)
steve-myers
Global moderator
 
Posts: 1917
Joined: Thu Jun 03, 2010 6:21 pm
Has thanked: 4 times
Been thanked: 206 times

Re: Internal and External subroutines?

Postby sudeepth » Tue Mar 18, 2014 5:32 am

I have been working on a small practice exercise and facing an Abend in selection sort while executing the program.

LA R2,TABLE
LOOP1 C R2,EOT
BE END1
LR R4,R2
LA R3,4(0,2)
LOOP2 C R3,EOT
BE END2
L R6,0(0,R3)
C R6,0(0,4)
BNM AHEAD
LR R4,R3
AHEAD LA R3,4(0,3)
B LOOP2
END2 L R5,0(0,2)
L R7,0(0,4)
ST R5,0(0,2)
ST R7,0(0,4)
LA R2,4(0,2)
B LOOP1
END1 DS 0H
sudeepth
 
Posts: 6
Joined: Thu Mar 13, 2014 2:13 pm
Has thanked: 1 time
Been thanked: 0 time

Re: Internal and External subroutines?

Postby steve-myers » Tue Mar 18, 2014 7:52 am

sudeepth wrote:I have been working on a small practice exercise and facing an Abend in selection sort while executing the program.

        LA    R2,TABLE
LOOP1    C     R2,EOT
         BE    END1
         LR    R4,R2
         LA    R3,4(0,2)
LOOP2    C     R3,EOT
         BE    END2
         L     R6,0(0,R3)
         C     R6,0(0,4)
         BNM   AHEAD
         LR    R4,R3
AHEAD    LA    R3,4(0,3)
         B     LOOP2
END2     L     R5,0(0,2)
         L     R7,0(0,4)
         ST    R5,0(0,2)
         ST    R7,0(0,4)
         LA    R2,4(0,2)
         B     LOOP1
END1     DS    0H
Without the table, it is difficult to analyze the code fragment you provided. Also, what ABEND did you get when you tried to run this code, and where in the code did it fail? Just telling us the code got an ABEND is essentially useless.

I'm guessing you are trying to do a "bubble" sort in this code.

When you post code use the code tags. I did this for you when I prepared this post.

This is a correct "bubble" sort.
         LA    2,4
         LA    3,EOT
         LA    4,TABLE
SORT1    LR    5,4
         BXH   5,2,SORT4
SORT2    L     0,0(,4)
         L     1,0(,5)
         CR    0,1
         BNH   SORT3
         ST    0,0(,5)
         ST    1,0(,4)
SORT3    BXLE  5,2,SORT2
         BXLE  4,2,SORT1
         DC    H'0'
SORT4    ...

TABLE    DC    F'5,-5'
EOT      DC    F'4'
Now I've been writing "bubble" sort sequences for more than 40 years, and I've been using BXH and BXLE instructions for at least that long. "Bubble" sorts are not very efficient, but they are easy to write. In this code, register 2 contains the number of bytes in each table entry, register 3 contains the address of the last entry in the table, and registers 4 and 5 point to table entries.

The BXH and BXLE instructions are hard for a beginner to understand, but they can be very useful. In the BXH instruction, the contents of register 2 are added to the contents of register 5. Register 5 is then compared to register 3. If register 5 is higher than register 3, the instruction branches. You should be able to figure out the BXLE instructions on your own.

There is no attempt to execute the DC H'0' after the last BXLE. Why?
steve-myers
Global moderator
 
Posts: 1917
Joined: Thu Jun 03, 2010 6:21 pm
Has thanked: 4 times
Been thanked: 206 times


Return to Assembler

 


  • Related topics
    Replies
    Views
    Last post