Subroutine

from Wikipedia, the free encyclopedia
Basic principle of a subroutine

A subprogram is a part of a computer program that provides a specific functionality . It can program parts of other programs / invoked are to take on a task and then branches to the calling point again back. A subroutine is i. d. Usually identified by an identifier (e.g. a name) and data can be passed to it as arguments for processing.

With regard to the terminology , a large number of variants are known from practice, some of which are used synonymously, some with semantic differences. Names such procedure ( procedure ), function ( function ), routine or subroutine , Surgery, Section , Module are some often historically and in the context of different programming languages emerged, but essentially correspond to the importance subroutine 'or so called. Thus, in the context of object-oriented programming techniques (methods) a - - depending on the programming language class , an object or a generic function as self-contained units assigned.

With regard to creation, maintenance and execution , subroutines can, depending on the type of implementation, be independent components ('subroutines' in the narrower sense, which are often pre- compiled in program libraries ) or, together with other functional parts, form the program code of a specific program.

Purpose of subroutines

The encapsulation of program parts in subroutines arises from the paradigm of procedural programming . The two most important advantages that are achieved in software design are the reusability of program parts and the improvement of the comprehensibility and maintainability of the source code .

Subroutines for certain technical or operational functions (e.g. a check digit calculation ) as a company-wide standard are one aspect of the software architecture .

The modular programming and software modules are a continuation of the concept of subroutines .

terminology

function
In programming languages ​​such as C, C ++, C #, Java or Python, all subroutines are generally called functions. In languages ​​like Pascal or BASIC, only those subroutines are called functions that return a value to the caller.
procedure
A procedure is often understood to be a special function that does not provide a return value (e.g. in Pascal or BASIC). FORTRAN77 acting under procedures all functions and procedural subroutines (subroutines) together.
In contrast to this, procedures in COBOL are only the instructions (commands) formulated in the 'Procedure Division', which can be named by 'Paragraphs', regardless of whether they are used as a subroutine or not. In PL / I , too, the instructions contained in the command part of the source text - which are to be processed procedurally (= 'progressively') - are referred to as “procedures”.
method
In object-oriented programming languages, a method is understood to be subroutines of or in classes.

history

David Wheeler , Maurice V. Wilkes and Stanley Gill are considered to be the developers of the first subroutine (then also called Wheeler-jump ).

In early imperative programming languages (for example early BASIC and FORTRAN variants) there was only the concept of the parameterless subroutine, which was called via jump instructions and could only interact with the main program via global variables.

With the advent of structured programming , the concept of the procedure with call parameters developed, which were initially mainly transferred as reference parameters ( call-by-reference ), i.e. a change to the parameter within the procedure changes the associated parameter at the point where the procedure is called. The introduction of explicit return values ​​from procedures (or functions) made it possible to calculate results without changing the reference parameters.

In a further step, value parameters were introduced for transfer to procedures ( call-by-value ) in order to further reduce undesirable effects on the main program.

To avoid program errors , a strong typing of parameters has been introduced in some programming languages ​​such as Pascal : the parameters actually used must be relatively strictly assignment-compatible with the formally declared parameters.

In some programming languages, such as Modula-2 , procedure variables can be called or used as parameters.

Finally, procedures as object-related methods or access functions became part of the object-oriented paradigm , for example in the programming languages Java and C ++ .

Different implementations

Depending on the development environment or programming language used , subroutines can be implemented in different ways:

  • As a logically self-contained part in the source code of a program. With regard to administrative management (e.g. in the event of changes), compilation and technical execution on a computer, such source code sections are an integral part of the overall program. Depending on the programming language and the type of implementation , the subroutine has access to all, only certain or only its own data and functions.
A variant of this is the use of program code parts that are managed as independent source text elements managed in program libraries : These are inserted into the source code of the programs using them by special instructions (e.g. include ) in the source code made available for compilation (temporarily) . Such code parts from source text libraries are also called 'copybook' (e.g. in the programming languages ​​COBOL or RPG ).
  • As administrative and independent programs for execution . They are only loaded "dynamically" at execution time. In some cases, for example with DLLs , such 'reloaded modules' can contain several and different subroutines. For details, see Dynamic Linking .
  • A hybrid form of both are subroutines with their own source code and separate compilation . However, your machine code is "statically bound" together with the code of the programs calling you to form an executable file . For details, see Static Linking .

Within these basic variants, certain programming languages ​​provide additional function details that can be used when linking and loading subroutines. See the examples for overloading or overwriting .

The system functions (such as reading, writing, clock, etc.) provided in a computer system form a special category of subroutines . They are not referred to as subroutines in the narrower sense, but are used according to the same process principle: Calling by means of instructions , usually with parameter / argument transfer, execution of the subfunction, for example in the operating system , then return to the calling program with continuation of processing.

Examples

The examples in the programming languages ​​C, C ++ and Java show details on programming with subroutines.

C, C ++ or Java

The following example is a subroutine in C , C ++ or Java that receives a value when it is called and multiplies it by a constant value. It is intended to demonstrate the conversion from inches to centimeters.

float inch2cm(float length) {
    return 2.54 * length;
}

python

The following example in Python are in messagefrom given string on the screen, but returns no value.

def hello(message):
    print(message)

Assembler

A simple Hello World program in assembly language , the four lines from the mark printrepresent the subroutine.

segment code

..start:
    mov ax, data
    mov ds, ax
    call print ; Aufruf des Unterprogramms
    mov ah, 4Ch
    int 21h ; Beenden des Programms

print:
    mov dx, hello
    mov ah, 09h
    int 21h
    ret

segment data
    hello: db 'Hello World!', 13, 10, '$'

Object modules mainframe IBM world

  • Calling programs send a call command and transfer (with 'USING x, y…') a list with the addresses of the data fields / data structures that the subroutine needs or should return. In the machine code of the program, the compiler loads register 1 with the address of the address list and register 14 with the return address, and register 15 with the entry address in the subroutine, then branching there (via 'BR 15').
  • Called programs take over the transferred addresses to address their structurally identical data declarations (whose identifiers can, however, be chosen differently), so that these 'foreign' data can be addressed with the commands of the subroutine.
  • After processing in the subroutine, the return jump takes place via register 14.

The following example shows how and with which calling conventions the calling and called modules interact. Assume a fictitious main program that calls a subprogram called UPRO. See also the graphic opposite:

Structure of the call interface
  • Source code of the calling program (in the example COBOL-like code):
* Daten:
  A.
   >Struktur von A, z. B.:
   Ax >Format und Längen
   Ay ...
  B.
   B1 (Definitionen, ggf. weitere Teilfelder)
   B2 (Definitionen)
   B3 (Definitionen)
* Funktionscode:
   A-ROUTINE.
   A-1. >Befehle-1
        Call UPRO Using A, B2.
   A-2. >Befehle-2, z. B. Auswerten und Verarbeiten Rückgabewert(e)
   A-ROUTINE Exit.
    >beliebige weitere Routinen/Befehle
* Programm-Ende
  • Source code of the subprogram, if necessary from another programming language:
The object code generated from this is integrated in the load module of the main program.
* Datendefinitionen:
   A-DAT >Format und Sub-Struktur wie in A; andere Bezeichner möglich!
   B-2  dto.
   C-x  z. B. eigene Definitionen von UPRO
* Funktionscode:
   Entry UPRO Using A-DAT, B-2.
         >Feldbezeichnungen von Using ggf. abweichend, Reihenfolge identisch zu 'Call'!
   >Weitere Befehle des Unterprogramms:
   >Mit vollem Zugriff (auch ändernd) auf die Struktur (Einzelfelder) von A-Daten und B2.
    Ggf. setzen Returncode, z. B. in B-2 (= B2)
   Exit = UPRO-Ende
  • Sequence of the subroutine call (call and return ):
(code generated by the compiler, coded by the programmer for assembler programs)
* Call im rufenden Programm:
   Setzt in einer (vom Compiler angelegten) Hauptspeicher-Adressliste
    mit 2 Einträgen die Adresse von A und von B-2
   Setzt einen Zeiger (Register, konkret R1) auf die Adressliste
   Setzt einen Zeiger (Register 14) auf die Rückkehradresse A-2.
   Setzt einen Zeiger (Register 13) auf die Register-Savearea,
    (Speicherbereich automatisch vom Compiler reserviert, Details siehe)
   Lädt Register 15 mit der Adresse (Entrypoint) des Unterprogramms 
    (die z. B. vom Linkage Editor im Maschinenprogramm eingesetzt wurde)
   Verzweigt über R15 in das Unterprogramm
* Entry im Unterprogramm:
   >Sichern der Registerstände in die Savearea des rufenden Programms (lt. R13)
    Speichern der Adresse dieser Savearea (= Inhalt R13) in einem eigenen Speicherbereich 
   >Übernehmen der übergebenen Variablen (aus Adressliste lt. R1):
    Adr(A-DAT) = aus Adressliste(1. Adresse), Adr(B-2) = aus Adressliste(2. Adresse)
   >Verarbeitung – mit Zugriff auf übergebene und eigene Daten sowie individueller Registernutzung
* Rücksprung ins rufende Programm:
   >Laden R13 mit der gespeicherten Adresse der Savearea
    Rückladen aller Register aus der Savearea lt. R13
   >Exit: Verzweigung (= Rückkehr) zu Adresse A-2 im rufenden Programm (lt. Inhalt R14)
   

The module could call further sub-modules according to the same scheme (register conventions, savearea). The necessary backup of the register statuses at the time of the call takes place in a memory structure called "savearea" of the calling modules, which has the following structure:

 |_A_|_B_|_C_|_D1_|_D2_|_.._|_D15_|   = 18 „Fullwords“ (je 4 Bytes) = 72 Bytes
   A = nicht belegt, reserviert    
   B = Adresse der Savearea des aufrufenden Moduls; vom aufgerufenen Modul in seiner eigenen Savearea gesetzt
   C = Adresse der Savearea des aufgerufenen Moduls; vom aufgerufenen Modul in der Savearea des aufrufenden Moduls gesetzt 
   Dn = Inhalt der Register „14 bis 12“ (entspricht R14,R15,R0,R1 .. R12):
       vom aufgerufenen Modul in der Savearea des aufrufenden Moduls gespeichert und vor dem Rücksprung zurückgeladen.

The save areas of the modules involved are linked to one another in their call sequence via the contents of memory locations B and C ; they show the status of the last module call. B. in debug mode during module tests, the call depth and the sequence can be determined and traced. This example shows a detailed assembler program code for the savearea handling .

Parameters / arguments

Subroutines (UP) carry out functions that usually require data belonging to the programs calling them. From the point of view of the subroutine, this data can be input or result values. Since, depending on the subprogram technique used, a subprogram basically only has 'access' to its own data, the programming techniques and languages ​​contain mechanisms with which the 'foreign' data are made available for the subprogram; only then can its commands address the 'external' data for them. Depending on the UP variant / programming language, different constellations can be distinguished in this regard:

  • The subprogram can access all data defined in the main program. Usually this is only the case with subroutines that belong to the source code of the main program.
  • The subroutine can access data (areas) that have been declared as 'global'.
  • The subroutine is explicitly 'given' 'its' data when it is called. The information about this are so-called "parameters".

The parameter technique is mainly used in subroutines developed independently of the calling program, in order to inform a UP to be called which data it should use / process. These parameters form the common interface between the calling and the calling UP. One example is "DispoSaldoCheck (account number, amount, answer)". In the sub-program and in the main program, this information must be declared structurally identically in accordance with uniformly applied conventions. The values ​​actually passed during the program execution for each call are called 'arguments', e.g. For example, the account number is '4711' and the amount is '-500.00', 'OK' or 'Overdraft' could be returned as an alternative. This pair of terms ( parameter and argument ) is synonymous with formal and actual parameters .

Parameters / arguments can be elementary data fields of any format, e.g. B. Text or Integer - or uniformly defined data structures on both sides of the interface . Regarding the usability of the transferred data, a distinction can be made as to whether they can only be read or also changed , for example for result values. Furthermore, it can be differentiated whether addresses (in the main memory) or the actual data are transferred with the parameters .

Technically (e.g. in the machine code) the parameters / arguments are transferred depending on the programming language and computer technology used with the help of different hardware devices. So z. B. the stack take the arguments or parameters are transferred via registers .

Individual evidence

  1. a b FU Berlin sub-programs
  2. FORTRAN77 standard, chap. 15. Retrieved September 20, 2010 (English).
  3. David Wheeler. 1985 Computer Pioneer Award. In: www.computer.org. IEEE, accessed October 20, 2013 .
  4. David Wheeler. 2003 Fellow. (No longer available online.) In: computerhistory.org. Computer History Museum, archived from the original on April 3, 2015 ; Retrieved October 20, 2013 . Info: The archive link was inserted automatically and has not yet been checked. Please check the original and archive link according to the instructions and then remove this notice. @1@ 2Template: Webachiv / IABot / www.computerhistory.org
  5. David J. Wheeler: The use of sub-routines in programs . In: Proceedings of the 1952 ACM national meeting (Pittsburgh) . ACM, New York 1952, pp. 235-236 , doi : 10.1145 / 609784.609816 .
  6. Maurice V. Wilkes, David J. Wheeler, Stanley Gill: Preparation of Programs for an Electronic Digital Computer, with special reference to the EDSAC and the use of a library of subroutines . 1st edition. Addison-Wesley, Cambridge (Massachusetts) 1951, OCLC 1189900 , p. 22 ( online [accessed October 20, 2013]).
  7. IBM SAVE