# LIST CC UNN REM 112 ,FONT 1 27 9 ,PRINT 100 ,END 1************************************************************ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ALP: Assembly Language Preprocessor * * * * User's Guide * * * * * * Computer Center Branch * * Division of Computer Research and Technology * * National Institutes of Health * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ************************************************************ Version 6.19 5/10/88 1 1 Level 2 Software Support (Revised November 1986) This software product, or a certain portion of it, has been assigned Level 2 support status. The Level 2 designation is made by the Computer Center for any of three reasons: First, an entire software product may be designated Level 2 if it is in test status, or the Center determines that rapid problem resolution and long-term product availability can not be ensured with the vendor support available. Second, an interface to specific peripheral hardware devices (e.g., terminals or plotters) will receive Level 2 support, even if the remainder of the product is designated Level 1. Third, an interface to processors not at the NIH Computer Utility (e.g., microprocessors or other computer installations) will receive Level 2 support, even if the remainder of the product is designated Level 1. If a hardware device/terminal is not specifically mentioned in the documentation for this product, no interface to it is supported (even as Level 2). While unsupported devices may sometimes function with the interfaces provided, any problems encountered are wholly the user's responsibility. This support policy is necessary in order to provide services for the large number of devices (e.g., terminals, plotters, microprocessors) commonly owned/used by end users. It is not practical for the NIH Computer Center to be familiar with the hardware characteristics of the myriad devices that can take advantage of these services. Users of this product should be fully aware that Level 2 software support provides documentation, non-critical Programmer Trouble Report (PTR) service, and limited INTERFACE preannouncement of changes, but does not guarantee continued availability or conversion assistance if this software is discontinued by the vendor or the Computer Center. In addition, no Programmer Assistance and Liaison (PAL) Unit consulting will be available on questions pertaining to the use of or problems with software receiving Level 2 support. The Computer Center will accept PTRs for problems if they are accompanied by all of the documentation necessary for diagnosis and resolution. When the Computer Center staff member responsible for the problem area described in a PTR for a product receiving Level 2 support receives all pertinent documentation on the problem, the staff member will frequently act as a technical guide with the burden of the work remaining with the user. Resolving or circumventing problems with software receiving Level 2 support may require resources (e.g., hardware/terminals or source code) that are not available to the Computer Center staff. Since the Computer Center is often completely unfamiliar with the specific devices/terminals involved, the vendor may be the sole source of vital information required for problem resolution or circumvention. For this reason, the "Critical" designation for PTRs is not applicable and will be disregarded by the Center. Once a PTR and all supporting documentation is received by the Computer Center, the work to get a resolution is a mutual effort of the user, the Computer Center and the author or vendor for products designated to receive Level 2 support. Since the Computer Center must rely on the cooperation/interest of the 1vendor/developer of a product, it is possible that some problems may never be resolved. The effects of this reduced support from the Computer Center should be thoroughly considered before incorporating any software receiving Level 2 support into critical applications. It must be stressed that the proper functioning or long-term availability of software receiving Level 2 support cannot be guaranteed by the Computer Center. The following chart outlines Computer Center services available for software receiving Level 2 support. For further information on Levels of software and how to submit PTRs, see the appropriate section of the Computer Center Users Guide. If questions remain on this policy, contact the PAL Unit Consulting Desk of the NIH Computer Center. SERVICE LEVEL 2 SOFTWARE SUPPORT CONSULTING (PAL DESK) a) personal visit No b) telephone No (Users will have to rely on technical documentation provided by the Computer Center and their own resources) PROGRAMMER TROUBLE REPORT (PTR) Yes "CRITICAL" PTR DESIGNATION No REFUNDS Yes DOCUMENTATION Yes TRAINING Resources permitting SOFTWARE MAINTENANCE a) Currency maintained with respect Resources to new versions and facilities permitting b) Formal change testing (Test Job No Stream) c) Informal change testing Yes d) Guarantee of orderly, fully No documented conversion if product is discontinued e) Preannouncement in INTERFACE of Resources all new facilities permitting f) Preannouncement in INTERFACE of Resources changes which cause old versions permitting of programs to function incorrectly or differently g) Preannouncement in INTERFACE of Yes discontinuance of support or changes in support status (Level) h) Preventive and corrective fixing Resources by Computer Center staff permitting 1 Table of Contents I. Introduction . . . . . . . . . . . . . . . . . . . . . . 1 II. The ALP Language . . . . . . . . . . . . . . . . . . . . 3 Input format . . . . . . . . . . . . . . . . . . . . . 3 Comment convention . . . . . . . . . . . . . . . . . . 3 Statement differentiation . . . . . . . . . . . . . . . 4 Compound statements . . . . . . . . . . . . . . . . . . 5 Predicates . . . . . . . . . . . . . . . . . . . . . . 6 III. ALP Statements . . . . . . . . . . . . . . . . . . . . . 8 Conditional and alternative statements (IF). . . . . . 8 Loop statements (DO). . . . . . . . . . . . . . . . . . 9 Case selection (CASE). . . . . . . . . . . . . . . . . 14 Predicate selection (SELECT). . . . . . . . . . . . . . 16 Loop control mechanisms (EXIT and NEXT) . . . . . . . . 18 Branching (GOTO and RGOTO). . . . . . . . . . . . . . . 20 Control of base register assignment (USE) . . . . . . . 21 Inline data (DATA) . . . . . . . . . . . . . . . . . . 22 Conditional assembly (ASM) . . . . . . . . . . . . . . 23 Including ALP code in macros (MACRO) . . . . . . . . . 26 Reversion to BAL (BAL) . . . . . . . . . . . . . . . . 28 Block Comments (COMMENT). . . . . . . . . . . . . . . . 29 Listing format control (TITLE,SUBTITLE,EJECT,SPACE) . . 30 IV. Non-Control Extensions . . . . . . . . . . . . . . . . . 32 V. The Implementation of ALP . . . . . . . . . . . . . . . 34 VI. ALP Syntax . . . . . . . . . . . . . . . . . . . . . . . 35 VII. ALP Readability Macros . . . . . . . . . . . . . . . . . 39 VIII. Macros for Environment Enhancement . . . . . . . . . . . 41 AREA and AREAEND . . . . . . . . . . . . . . . . . . . . 42 DEBLANK . . . . . . . . . . . . . . . . . . . . . . . . 45 EDIT . . . . . . . . . . . . . . . . . . . . . . . . . . 47 EXI . . . . . . . . . . . . . . . . . . . . . . . . . . 49 MCLC, MMVC, MNC, MOC and MXC . . . . . . . . . . . . . . 51 MFC . . . . . . . . . . . . . . . . . . . . . . . . . . 52 MTC . . . . . . . . . . . . . . . . . . . . . . . . . . 53 MTR . . . . . . . . . . . . . . . . . . . . . . . . . . 54 MTRT . . . . . . . . . . . . . . . . . . . . . . . . . . 55 MZC . . . . . . . . . . . . . . . . . . . . . . . . . . 56 DF . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 SF . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 TF . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 ZF . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 1 OSCALL . . . . . . . . . . . . . . . . . . . . . . . . . 61 OSENTER . . . . . . . . . . . . . . . . . . . . . . . . 62 OSEXIT . . . . . . . . . . . . . . . . . . . . . . . . . 63 OSSETUP . . . . . . . . . . . . . . . . . . . . . . . . 64 OPENP . . . . . . . . . . . . . . . . . . . . . . . . . 66 CBDELINK . . . . . . . . . . . . . . . . . . . . . . . . 67 CBDLINKH . . . . . . . . . . . . . . . . . . . . . . . . 69 CBDLINKT . . . . . . . . . . . . . . . . . . . . . . . . 70 CBLINK . . . . . . . . . . . . . . . . . . . . . . . . . 72 CBLINKH . . . . . . . . . . . . . . . . . . . . . . . . 73 CBLINKT . . . . . . . . . . . . . . . . . . . . . . . . 74 IX. ALP Coding Hints . . . . . . . . . . . . . . . . . . . . 75 X. Sample Program . . . . . . . . . . . . . . . . . . . . . 76 XI. Using ALP at NIH . . . . . . . . . . . . . . . . . . . . 80 XII. References . . . . . . . . . . . . . . . . . . . . . . . 82 1 - 1 - I. INTRODUCTION The choice of the proper vehicle -- assembly language or higher-level language -- for writing so-called "systems programs" is a subject of constant debate (1,2). With a few notable exceptions (3,4), the trend has been toward continued use of assembly languages, generally those provided by vendors of computer systems. Fortunately, the field is now well enough explored that most assemblers are relatively powerful, incorporating macro or preprocessor facilities such as symbolic substitution, conditional assembly, etc. Given the architecture of most currently-available hardware and the orientation of assemblers toward that hardware, very little has been done to provide sophisticated control or data structures. Considering that until fairly recently this was also the case even for compiler-level languages, perhaps it is not too surprising. For better or worse, systems being implemented at the assembly language level have -- inevitably -- grown in size and complexity. This is one of the major factors (along with the desire to work in terms closer to the nature of the application being developed) that led to the evolution of higher-level languages. It has also fostered the investigation of more powerful tools for building systems whose implementation is constrained, for one reason or another, to the use of assembly language. The various approaches taken have included more powerful macro facilities, compilers for languages which can be straightforwardly and efficiently translated (some into object code, others into assembly source), highly-optimized compilers which attempt to relieve the concerns about staying close to the underlying hardware, and preprocessors which provide capabilities similar to those available with macro systems but with increased flexibility. It is a tool of this last type which will be described below. Our search for a means of making assembly language programming easier began in the first place because we were faced with a large project which we had already decided would be done in assembly language. This was due to the environment in which the end result would operate, efficiency considerations, and the lack of any reasonable alternative, as well as experience with previous versions of the system. It was obvious, though, that features not provided by the available assemblers would greatly improve both the speed with which the project could proceed and its eventual maintenance and enhancement. The most realistic goal was to provide better control structures, perhaps assembly language's most serious deficiency. In addition, we sought to improve the overall reliability of the new system by minimizing the chances of certain types of coding and logic errors which are encouraged by the scarcity of good control structures and the consequent requirement for explicit branching, labels, etc. Hence some form of "structured" programming technique seemed to be indicated. 1 - 2 - For reasons of practicality, we preferred to use something already developed and in use. A preprocessor (AL) which provided many of the features we were looking for had been developed by Edward C. Haines at MITRE, and we decided to use that as a base (portions of this document are taken from the original reference (5)). The salient features of AL were that it provided: . "predicates" for condition testing . an "IF ... THEN ... ELSE ..." structure . "WHILE ... DO ..." and "DO ... UNTIL ..." . a "COUNT" statement for iterative loops . a conditional branching capability in addition, it allowed: . free-form input, with label and statement delimiters . comments . transparent use of regular assembly language After acquiring the source for AL and examining it, we made a number of enhancements. These include: . extension of predicates to allow grouping . generalization of the loop control structures into .. DO-WHILE / WHILE-DO .. DO-UNTIL / UNTIL-DO .. DO-FOR / FOR-DO (replacing AL's "COUNT") .. DO-FOREVER / FOREVER-DO (replacing AL's "LOOP") . addition of CASE and SELECT statements . generalization of explicit branching to allow .. GOTO (replacing AL's "BIF") .. RGOTO (for register form of branch) . improved loop controls .. EXIT .. NEXT . local control of base register assignment for DSECTs through USE . access to conditional assembly facilities through the ASM statements . support for ALP code in macros through the MACRO statement . substitution of '<'/'>' and 'BEGIN'/'END' for AL's use of parentheses as compound statement delimiters . recording of nesting level and display on listing . automatic indentation according to nesting level . provision for title and subtitle control as well as eject and space . allowance for presence of macro variables (i.e. those beginning with "&") in operand fields . acceptance of macro and sequence symbols as labels . limited optimization of internally-generated branches Fortunately, AL proved to be a reasonable basis for expansion. Our task would have been far greater had we been forced to start from scratch. 1 - 3 - II. THE ALP LANGUAGE Following sections will describe each ALP statement in some detail. A syntax description in augmented BNF is contained in section VI. INPUT FORMAT +____________ ALP resembles PL/I in some respects. Programs are composed of statements, separated by semi-colons (';'). Source code may be entered in free form in columns 1-72 (columns 73-80 should contain some sort of sequence information). The program must be terminated with an "END" statement (i.e. "END;"). Labels are delimited by a colon (':'), and multiple labels may appear on a single statement. Otherwise, labels obey assembler conventions. That is, they must be one to eight characters in length, consist of 'A'-'Z', '0'-'9', '$', '@', or '#', and begin with 'A'-'Z', '$', '@', or '#'. In order to allow for sequence symbols, set symbols, and labels into which macro variables are to be substituted, '.', '&', '(', and ')' are also allowed. Ampersands should be doubled in order to prevent confusion with the AND operator. Examples: program: S1; S2; S3; END; labeling: LABEL: S; L1: L2: S; .SEQ: AGO .SEQ2; &&CHAR: SETC 'ABC'; X&&Y(2)Z: DC H'0'; COMMENT CONVENTION +__________________ Like PL/I, ALP allows comments wherever a blank is legal. However, the delimiting mechanism is quite different. ALP comments begin with a percent sign ('%') and are terminated by the end of the input line. Examples: LA R1,2; % THIS IS A COMMENT Block comments are also supported, see section III. 1 - 4 - STATEMENT DIFFERENTIATION +_________________________ There are two types of ALP statements, which, unless stated otherwise will be treated equivalently in the rest of this document. The first type consists of those beginning with keywords meaningful to ALP, which it processes. The second consists of those which ALP does not recognize and passes on to the assembler on the assumption that they are BAL statements or macro calls. In the latter type, the usual assembler conventions about operand fields apply, with three changes: 1. Comments must be entered as described above -- a blank signals only the end of the field, not the start of comments as well. 2. If an ampersand ('&') is to appear in an operand other than inside a quoted string, it must be doubled to distinguish it from ALP's predicate conjunction operator (see below). For example: LA REG,&&CON; LA REG,=C'&STRING'; 3. Since ALP input is free form, the only place special continuation is required is when operand fields must be split across line boundaries. In such cases, end the first part of the field with an underscore -- it will be continued with the next non-blank character (ignoring any intervening comments) and the underscore will be discarded. If a quoted string must be broken, end the first part with a quote-underscore pair and continue with a quote on the next line. The underscore, any intervening blanks, and the two extra quotes will be discarded. For example: TPUT MESSAGE,_ LENGTH; and DC C'THIS IS A LONG CONSTANT '_ 'WHICH WILL BE CONTINUED'; 1 - 5 - COMPOUND STATEMENTS +___________________ Simple statements may be combined into compound statements by enclosing them in angle brackets ("<" and ">") or "BEGIN"-"END" symbols and separating them with semicolons. Examples: BEGIN S1; S2; S3; END Spacing is irrelevant, except that there must be a delimiter (such as a blank) following the "BEGIN" and preceding the "END". Also, there is no semicolon required preceding the "END" or ">". However, a semicolon must follow a compound statement wherever one is required after a simple statement. Although "BEGIN"-"END" and "<"-">" are generally inter- changeable, special consideration must be taken in two cases: 1) An "END" bracket must never be labeled. An acceptable equivalent is a labeled null statement preceding the terminating bracket. For example: BEGIN statement; statement; label: ; END 2) If the final statement in a group of statements to be bracketed has no operands, a semicolon must precede the terminating "END" or the "<"/">" form must be used to prevent the "END" from being mistaken for an operand on the statement. 1 - 6 - PREDICATES +__________ The concept necessary for most control structures is that of predicate. A predicate is a sequence of statements that produces a truth value. On the System/370, testing of truth conditions is accomplished by setting a condition code (with an instruction such as a comparison) and then conditionally branching on the status of the condition code. The instructions that set the condition code are sometimes, but not often, what people logically want to think of as the predicate. The execution of conditional branches is almost always not what people want to think about (cf Dijkstra(6)). In ALP, a simple predicate is a sequence of instructions (possibly empty) that defines a condition code setting. A predicate is then a Boolean combination of simple predicates involving the operators '&' ("AND"), '|' ("OR"), and '^' ("NOT"). The conditional branches (and unconditional branches where necessary) are implied by the control statements. The programmer is, for the most part, freed from worrying about what condition code value(s) will be set and how to test them. ***************************************************************** A number of macros have been provided to improve the readability of ALP programs and to provide additional information for ALP's use in determining condition tests, etc. They will be used freely in the examples that follow: see sections VII and VIII for complete information. Note that use of these macros is not required. ***************************************************************** Examples: simple predicate: predicate: ^ & | < & > | Grouping is such that a&b|c&d is interpreted as a&(b|(c&d)); there is no operator precedence, but grouping of predicates in angle brackets is allowed. IF, DO, etc. should not be used within a predicate because they introduce uncertainty in the condition actually being tested. The way in which predicates are evaluated does not always insure that all instructions in the predicate are executed. Thus, care should be taken that processing does not depend on the execution of all instructions in a predicate involving Boolean combinations of simple predicates. 1 - 7 - The appropriate condition code test is determined from the op-code of the last statement of the predicate; if the name is not recognized, the default is '=' (equal, or zero). The test can be explicitly specified by using a special statement of the form: CC ccstring where ccstring is composed of characters from the set 0 = E Z 1 L M 2 P H 3 O N ^ These are used as in the form of the extended mnemonics of the assembler except that they specify the "truth" condition (as opposed to the branch condition) and any combination of characters is allowed. Since equality is the appropriate truth condition for most predicates, only non-standard cases are coded into the preprocessor. These are: OPENP (NZ), TF (NZ), TM (NZ), TS (NZ), TRT (NZ), RM (M), RZ (Z), RP (P), RMZ (NP), RMP (NZ), RZP (NM), RNM (NM), RNZ (NZ), RNP (NP), RNMZ (P), RNMP (Z), RNZP (M). 1 - 8 - III. ALP STATEMENTS CONDITIONAL AND ALTERNATIVE STATEMENTS +______________________________________ Conditional and alternative statements are provided by the IF-THEN-ELSE statement. Its format is: IF predicate THEN statement ELSE statement where the "ELSE" clause is optional. Examples: IF THEN STH R2,BLKSIZE; at assembly time would appear (subject to label differences) as: LH R2,0(R1) LTR R2,R2 BNP @0001 STH R2,BLKSIZE @0001 ---- IF THEN LA R3,1 ELSE LA R3,2; would generate: L R2,0(R3) LTR R2,R2 BNZ @0001 LA R3,1 B @0002 @0001 LA R3,2 @0002 ---- NOTE: If a simple statement without operands (such as an operand-less machine op-code or macro call) comprises the predicate or the "THEN" clause in an "IF ... THEN ... ELSE" construct, it must be enclosed in '<'/'>' bracketing symbols to prevent the following keyword ('THEN' or 'ELSE') from being interpreted as an operand of the statement. ***************************************************************** Note that ALP-generated labels begin with a commercial "at-sign" ('@'). Labels generated outside macro definitions will consist of an at-sign followed by a four-digit decimal integer (e.g. @0001). Labels generated inside a macro (see the discussion of support for ALP code in macros) will involve a special symbol so that multiple invocations of the macro will not generate duplicate labels (e.g. @&@001). ***************************************************************** 1 - 9 - LOOP STATEMENTS +_______________ There are four sets of loop-producing statements: . DO-WHILE and WHILE-DO . DO-UNTIL and UNTIL-DO . DO-FOR and FOR-DO . DO-FOREVER and FOREVER-DO The two forms differ in the position of the test which terminates the loop: whether it comes after (as in the first form) or before (as in the second) the body of the loop. The format of the first set is: WHILE predicate DO statement or DO statement WHILE predicate Examples: WHILE ^ DO ; generates: @0001 CR R3,11 BE @0002 MVI 0(R3),C' ' LA R3,1(,R3) B @0001 @0002 ---- DO WHILE ^; generates: @0001 MVI 0(R3),C' ' LA R3,1(,R3) CR R3,R11 BNE @0001 1 - 10 - The DO-UNTIL set is similar to the DO-WHILE set except that the "sign" of the test is reversed. Its format is: DO statement UNTIL predicate or UNTIL predicate DO statement Examples: DO UNTIL ; translates to: @0001 LR R1,R2 L R2,0(,R1) LA R2,0(,R2) C ADR,EADR(R2) BNH @0001 @0002 ---- UNTIL DO ; generates: @0001 C ADR,EADR(R2) BH @0002 LR R1,R2 L R2,0(,R1) LA R2,0(,R2) B @0001 @0002 ---- 1 - 11 - A simple loop counting mechanism is provided by the DO-FOR set. The number of times the loop is to be executed is determined by the value of a specified register (set by a previous statement) on entry to the loop. The register is decremented once per cycle until it is zero. The format is: DO statement FOR register or FOR register DO statement Examples: DO FOR R12; translates to: @0001 IC R1,0(R11) BAL R9,PCHAR LA R11,1(,R11) BCT R12,@0001 FOR R12 DO ; generates: LTR R12,R12 BNP @0002 @0001 IC R1,0(R11) BAL R9,PCHAR LA R11,1(,R11) BCT R12,@0001 @0002 ---- 1 - 12 - The last of the loop control structures are also the simplest: a "do-once" structure and an infinite loop, with responsibility for escaping from it placed on the programmer. The format of the "do-once" is: DO statement This form is useful where the statement is a compound one containing EXIT statements (described in a later section), which permit escape from the compound statement. Similarly, a NEXT statement (see below) occurring in such a compound statement will cause control to be transfered to the start of the statement. The format of the infinite loop is: DO statement FOREVER or FOREVER DO statement Examples: DO FOREVER; and FOREVER DO both translate to: @0001 LA R2,1(,R2) B @0001 1 - 13 - The WHILE-DO/DO-WHILE, UNTIL-DO/DO-UNTIL, and FOR-DO/DO-FOR constructs, as well as the "do-once" form, may also be followed by an optional "THEN statement". This allows the specification of action to be taken if and only if control "falls through" the DO (e.g. when the register specified in a FOR-DO construct becomes zero), but not if control is transfered via an EXIT statement. FOREVER-DO/DO-FOREVER cannot take a THEN clause. Example: DO BEGIN ... EXIT; ... END THEN BEGIN ... END; NOTE: Introduction of THEN as part of the DO construct requires care in the nesting of statements under certain circumstances. Nesting of DO's within DO's can cause confusion of THEN's in the same way that nesting of IF's can cause confusion of ELSE's. In either case bracketing symbols must be used to prevent attaching the dependent clause to the inner statement instead of the outer. 1 - 14 - CASE SELECTION +______________ The CASE statement permits the selection of an action designated by the value of a register. Its format is: CASE register MAX expression MIN expression; case-label: statement; ... ENDCASE The case to be executed is designated by the contents of the specified register. This index must be a multiple of four greater than or equal to zero and be contained in a register other than register zero. A maximum value (used to generate a branch table, but not checked at execution time) is required, and may be any valid previously defined assembler expression which evaluates to a multiple of four greater than the minimum value. A minimum value (also used to generate the branch table) is optional, has a default value of 0, and may be any valid previously defined assembler expression. The case to be executed is designated by the value of the "case-label" assigned to it. Each such label consists of an assembler expression, two expressions separated by the keyword "THRU", or a series of these two types separated by commas. As shown above, the case label is separated from the statement making up the case by a colon. If duplicate or overlapping case labels are specified, the last one takes precedence. This allows a default action to be defined which will take effect if a case is specified for which a statement was not otherwise provided. If a default action is not provided, a program check (invalid op-code) will occur if a case is specified for which no statement was entered. Example: CASE R15 MAX 16; 0: ; 4,16: LA R15,4; 8 THRU 12: LA R15,8; ENDCASE; translates to: B @0001(R15) @0001 B @0002 B @0003 B @0004 B @0004 B @0003 @0003 LA R15,4 B @0002 @0004 LA R15,8 @0002 ---- 1 - 15 - The CHECK option may be used in a CASE statement to specify that the minimum and maximum values are to be checked. An ELSE clause may be added after the ENDCASE to specify the action to be taken for an out of bounds value. If no ELSE clause is used, an operation exception will occur for an invalid value. Example: CASE R15 MAX 16 MIN 4 CHECK; 4,16: LA R15,4; 8 THRU 12: LA R15,8; ENDCASE ELSE ABEND 1234,DUMP; translates to: C R15,=A(4) BL @0004 C R15,=A(16) BH @0004 B @0001-4(R15) @0001 B @0002 B @0003 B @0003 B @0002 @0002 LA R15,4 B @0005 @0003 LA R15,8 B @0005 @0004 ABEND 1234,DUMP @0005 ---- The CASE statement may also have a THEN clause which functions in the same manner as for the DO statement. The THEN clause must follow an ELSE clause, if present. 1 - 16 - PREDICATE SELECTION +___________________ The SELECT statement is analogous to the CASE statement in that it allows the selection of an action designated by the validity of a specified condition. In the CASE statement this condition is the equality of the specified register to a value given in the "case-label". In the SELECT statement the condition is the truth of one or more predicates which take the place of CASE "case-label"s. The format is: SELECT; predicate: statement; ... ENDSEL Execution of the statement is as follows: each predicate is evaluated in turn and, if true, its associated statement is executed. The sequential nature of this process means that the execution of a selected statement can influence the truth of a predicate forming the selection-label on a later statement. For example: LI R1,1; SELECT; :
  • ; :
  • ; ENDSEL; As in the previous example, multiple elements of the selection list may be executed in turn. The SELECT FIRST form of the construct specifies that only the first statement for whose predicate is true will be executed, and no others "below" it -- regardless of the fact that their predicates may also be true. Applying this option to the example above: LI R1,1; SELECT FIRST; :
  • ; :
  • ; ENDSEL; In this case, only the first selected case ("LI R1,2") would be executed, since no other predicates would be tested. 1 - 17 - An additional option, applicable to SELECT FIRST form only, allows specification of an action to be performed if no predicate in the selection-list is true. Its form is as follows: SELECT FIRST; predicate: statement; ... ENDSEL ELSE statement Example: LI R1,0; SELECT FIRST; :
  • ; :
  • ; ENDSEL ELSE LI R1,4; A THEN clause may also be appended to a SELECT statement. The statement following THEN is executed if control "falls through" to the end of the statement but not if an EXIT statement is used. For example; SELECT FIRST; :
  • ; :
  • ; ENDSEL ELSE LI R1,4 THEN MH R1,=H'10000'; NOTE: Although the effect of the SELECT FIRST ... ELSE is easily obtained with IF-THEN-ELSEs, the SELECT construct is generally more readable, and may clarify the processing being carried out. 1 - 18 - LOOP CONTROL MECHANISMS +_______________________ In order to reduce the necessity for coding explicit branches, ALP provides ways to escape from and reenter a control structure. The first is the EXIT statement, whose complete form is: EXIT FROM label IF predicate where the "FROM label" and "IF predicate" clauses are optional. Examples: EXIT; EXIT FROM BLOCK1; EXIT IF ; EXIT FROM BLOCK1 IF ; NOTE: If both are specified, the FROM clause must precede the IF clause. When used inside a loop construct (DO-WHILE, etc.), EXIT causes control to be transfered to the first instruction following the loop (bypassing any THEN clause). The EXIT statement may also be used inside a CASE or SELECT statement to terminate execution of the case. An EXIT without a FROM clause causes a transfer of control to the first instruction immediately following the construct containing the EXIT. An EXIT followed by a FROM clause causes a transfer of control to the first instruction following the construct whose label is specified in the FROM clause. Both forms may be modified by the IF clause to provide both conditional and unconditional EXITs. Examples: (target labels are shown only for reference) BLOCK1: DO BEGIN ... BLOCK2: DO BEGIN ... EXIT; % TO TARGET1 ... EXIT FROM BLOCK1; % TO TARGET2 ... END; TARGET1: ... ... END; TARGET2: ... FOREVER DO BEGIN LA R2,1(,R2); EXIT IF ; MVI 0(R2),C'*'; END; 1 - 19 - In an analogous manner, the NEXT statement, NEXT OF label IF predicate causes transfer of control, conditionally or unconditionally, to the point at which the next iteration of the construct named by "label" begins (e.g. to the "BCT" in a "FOR" structure). If no OF clause is specified, the next iteration of the innermost loop is begun. In a CASE or SELECT statement, a NEXT causes a transfer of control back to the point of case selection. Examples: WHILE DO ; CASE R15 MAX 8; 0: ; 4: ; 8: CALL ERROR2; ENDCASE; SELECT; :
  • ; : ; ENDSEL; BLOCK1: DO BEGIN BLOCK2: DO BEGIN ... NEXT; % NEXT ITERATION OF BLOCK2 ... NEXT OF BLOCK1; % NEXT ITERATION OF BLOCK1 ... END WHILE ; END WHILE ; NOTE: If an EXIT or NEXT statement occurs in the THEN clause of a DO, CASE or SELECT statement, it applies to the containing statement. NOTE: It is possible to code statements like: IF predicate THEN EXIT; However, this causes less efficient code to be generated than if the EXIT statement had been used in the form EXIT IF predicate; Hence the latter form is recommended. This is equally true for the NEXT statement. 1 - 20 - BRANCHING +_________ The final control statement, an admission of our failure to write completely structured programs, is an explicit branch. Its format is: GOTO label IF predicate A branch-register form is also available: RGOTO register IF predicate where the "IF" clauses in both forms are optional. Examples: GOTO X; translates to: B X RGOTO REG; generates: BR REG GOTO X2 IF ; generates: TM 0(R1),X'40' BNZ X2 RGOTO REG2 IF ; generates: BCTR R3,0 LTR R3,R3 BZR REG2 NOTE: "GOTO/RGOTO ... IF ..." generates more efficient code than "IF ... THEN GOTO/RGOTO ...", and is therefore preferable (even though the latter may be easier to think of). 1 - 21 - CONTROL OF BASE REGISTER ASSIGNMENT FOR DSECTS +______________________________________________ Control of base register assignment for DSECTs through USING and DROP assembler statements, while not difficult, is frequently not easy to relate to the processing being performed. ALP's USE statement allows explicit use of a data structure for the duration of a single statement -- simple or compound -- and automatically provides the appropriate USING and DROP directives. Its format is: USE register AS dsect-name IN statement Example: USE R12 AS MSGBLK IN L R11,MSGLEN; translates to: USING MSGBLK,R12 L R11,MSGLEN DROP R12 Multiple "register AS dsect-name" units may be specified, using commas as separators. Example: USE R1 AS PARMBLK1, R2 AS PARMBLK2 IN BEGIN L R3,PARM1; L R4,PARM2 END; generates: USING PARMBLK1,R1 USING PARMBLK2,R2 L R3,PARM1 L R4,PARM2 DROP R1,R2 1 - 22 - INLINE DATA +___________ The DATA statement may be used to branch around data values which are included with executable code for purposes of clarity. The general form is DATA statement Examples: DATA CON: DC F'99' translates to B @0001 CON DC F'99' @0001 ... DATA BEGIN CONS: DC F'99'; DC F'999'; END translates to B @0001 CONS DC F'99' DC F'999' @0001 ... 1 - 23 - CONDITIONAL ASSEMBLY +____________________ While it is, of course, possible to use the assembler's conditional assembly facilities in a straightforward way, it is often more convenient to have ALP generate the necessary sequence symbols, take care of isolation of labels generated within conditional assembly blocks, and so on. The ASM statements provide these capabilities. The most often used ASM statement is the ASM IF: ASM IF (condition) THEN statement ELSE statement where the "ELSE" clause is optional. Examples: ASM IF ('&TYPE' EQ 'EMPTY') THEN statement; translates to: AIF (NOT ('&TYPE' EQ 'EMPTY')).@0001 statement .@0001 ANOP ASM IF (&&V EQ &&X) THEN statement1 ELSE statement2; generates: AIF (NOT (&V EQ &X)).@0001 statement1 AGO .@0002 .@0001 ANOP statement2 .@0002 ANOP NOTE: If "statement1" in the "... THEN ... ELSE ..." form is a simple statement without operands (e.g. a macro call without operands, an assembler op-code without operands, etc.) then it should be bracketed with '<'/'>' symbols to prevent the 'ELSE' from being interpreted as an operand of the statement. 1 - 24 - Most other ALP statements are available in the ASM form in an analogous way. . ASM WHILE (condition) DO statement THEN statement . ASM UNTIL (condition) DO statement THEN statement . ASM DO statement WHILE (condition) THEN statement . ASM DO statement UNTIL (condition) THEN statement . ASM DO statement THEN statement . ASM FOREVER DO statement . ASM DO statement FOREVER . ASM CASE set-expression; case-list: statement; ... ENDCASE THEN statement . ASM CASE set-expression; case-list: statement; ... ENDCASE ELSE statement THEN statement . ASM SELECT; (condition): statement; ... ENDSEL THEN statement . ASM SELECT FIRST; (condition): statement; ... ENDSEL THEN statement . ASM SELECT FIRST; (condition): statement; ... ENDSEL ELSE statement THEN statement . ASM FOR seta-variable FROM seta-expression BY seta-expression TO seta-expression DO statement THEN statement . ASM DO statement FOR seta-variable BY seta-expression TO seta-expression THEN statement . ASM EXIT . ASM EXIT FROM sequence-symbol . ASM EXIT IF (condition) . ASM EXIT FROM sequence-symbol IF (condition) . ASM NEXT . ASM NEXT OF sequence-symbol . ASM NEXT IF (condition) . ASM NEXT OF sequence-symbol IF (condition) . ASM GOTO sequence-symbol . ASM GOTO sequence-symbol IF (condition) 1 - 25 - Notable points are . "condition" represents a valid SETB expression. . the THEN clause is optional with all statements except ASM IF. . FROM, BY and TO are provided with ASM FOR to define the limits of the loop. The defaults are 1, 1 and infinity, respectively. If negative numbers are used, they must be written as "0-number", in honor of the assembler restriction on unary operators. FROM is not valid with ASM DO FOR. . The selection value in the ASM CASE statement may also be a SETC expression in quotes. If this is done, the case identifiers must also be SETC expressions in quotes. . MAX and MIN are not used with ASM CASE. . There is no ASM RGOTO statement. . ASM IF may also be written as ASMIF for compatability with earlier versions. 1 - 26 - INCLUDING ALP CODE IN MACROS +____________________________ Although macros are frequently used for describing data structures or for small common code segments containing little or no control structure, this is not always the case. In such instances it is desirable to write them in ALP in order to continue to maintain consistency and preserve the goals of using a structured language. ALP's MACRO statement allows the definition of assembler macros which may contain ALP constructs. Its format is: MACRO macro-label: macro-name macro-operands; GBLx and LCLx declarations macro-body MEND where: macro-label is the (optional) label to be placed on the first statement of the macro, and is of the form &&identifier macro-name is the name of the macro macro-operands is an (optional) operand field which names the symbolic operands of the macro, in the form &&identifier,&&identifier,... Example: MACRO &&LABEL: ZAP &&P1,&&P2; GBLA &&X; COPY NAMES; &&LABEL: IF THEN ELSE ; MEND; generates MACRO &LABEL ZAP &P1,&P2 GBLA &X COPY NAMES LCLC &@ &@ SETC '&SYSNDX' &LABEL LTR &P1,&P1 BNP @&@001 SR &P1,&P1 B @&@002 @&@001 LCR &P2,&P1 @&@002 ... NOTE: The doubling of ampersands ('&') is necessary, as described in section II, to prevent confusion with the predicate operator "AND". 1 - 27 - All GBLx and LCLx declarations and any COPY statements which copy in such statements must be grouped immediately after the MACRO header. This is because a local set symbol must be defined so that ALP-generated labels do not result in duplicate labels if a macro is invoked more than once. Assembler restrictions require that all set symbol declarations precede other statements, and ALP picks the point at which to define its own set symbol by detecting the first statement which is not a GBLx, LCLx, or COPY. Another consequence of this is that a COPY which copies in executable code MUST be preceded by a dummy statement of some sort to prevent premature generation of the ALP local set symbol. For example: MACRO EXAMPLE; GBLA &&X; ; % TO FOOL ALP COPY CODE; % TO COPY IN EXECUTABLE CODE MEND; ALP may also be used to process macros to be stored in assembler macro libraries. To facilitate this, ALP will pass through unchanged any ./ control cards which occur in the input stream. Thus, output from ALP may be passed directly to IEBUPDTE. 1 - 28 - REVERSION TO BAL +________________ While most assembler code can be written within the framework of ALP, it may occasionally be necessary to revert to BAL mode. The ALP statement "BAL;" will cause the preprocessor to enter a transparency mode, in which card images are simply copied from the input stream to the output stream. BAL mode is terminated when "ALP;" appears as the first non-blank symbol on a line. Any text beyond the "BAL;" on the same line is ignored. The format of the statement is: BAL; bal-code ALP; Examples: BAL; MACRO &L ADD &A,&B,&C L 15,&A A 15,&B ST 15,&C MEND ALP; BAL; IF &L1,&L2 ALP; 1 - 29 - BLOCK COMMENTS +______________ The comment statement is an alternate way of including a large block of comments in an ALP program. All lines following a "COMMENT;" statement are ignored. Normal processing is resumed when "ALP;" appears as the first non-blank character on a line. The advantage of COMMENT over normal comments is that WYLBUR's ALIGN and JUSTIFY commands may be used since there are no extraneous characters on the comment lines. Example: COMMENT; Normally a long-winded explanation of some part of the program would appear here. ALP; 1 - 30 - LISTING FORMAT CONTROL +______________________ Several conventions were adopted to allow control of the SYSPRINT listings of both ALP and the assembler. These are as follows: . The indentation of each line is automatically adjusted to be 3 times the nesting level at the start of the line. The nesting level is the number of unterminated BEGIN, <, CASE, SELECT and MACRO statements. . Blank lines are ignored by ALP, and may thus be used to format input source. They are not passed on to the assembler, and hence have no effect on its output. . If ALP is being used in conjunction with the assembler, a post-processor extracts location counter values from the assembler listing and adds them to the ALP listing. In order for this process to work properly, the input lines must be sequence numbered in ascending order in columns 73 through 80. Special care must be taken with COPY statements outside of macros as they will disrupt the sequencing. Sequence fields of all blanks or all zeroes are ignored. The IEBUPDTE statement ./ NUMBER NEW1=0,INCR=0 may be used to cause sequence numbers of all zeroes to be placed in a COPY module. . ALP provides limited support for the assembler directive SPACE. The ALP listing is arbitrarily spaced up two lines, and the SPACE and its operands (if any -- no checking for validity is performed) are passed on to the assembler. . ALP processes the EJECT assembler directive by causing a page eject and passing the EJECT (and any operands -- no checking is done) on to the assembler. . ALP accepts the assembler directive TITLE. The operands are stored for printing at the top of each page, and with the TITLE op-code are passed on to the assembler. No validity checking is performed, but there should be only one operand -- a quoted string. If a label is present, it is also passed to the assembler. Note that there is an assembler requirement that only one such "deck name" be present in any assembly. The default title is a standard ALP heading. . ALP supports a SUBTITLE statement. The operands, which should consist of a single quoted string, are stored for printing at the top of each page immediately below the current title. The SUBTITLE is converted to a TITLE directive and passed with its operands to the assembler. The default subtitle is a blank line. . ./ (IEBUPDTE) control cards cause a page eject. 1 - 31 - NOTE: SPACE, EJECT, TITLE, and SUBTITLE are all treated as regular assembly language statements -- no special notice is taken that they also influence formatting of the source listings. Hence some care must be taken in their placement in the source. For example, IF predicate THEN BEGIN statements END ELSE EJECT; BEGIN statements END; will cause the EJECT to form the body of the ELSE clause and not the desired BEGIN-END block. It is also not permissible to separate CASE or SELECT components with format control statements. 1 - 32 - IV. NON-CONTROL EXTENSIONS Some non-control extensions are provided by ALP in an attempt to improve the conceptual environment in which one programs at the assembly language level. There are several notions that are fairly well established in the machine instruction set and the basic assembly language. These include word, halfword, byte, and register operations. A very important data type not directly covered is the bit. Bit operations are adequately handled by byte instructions, but what is missing is a clear identification that one is dealing with bits. AL provided three 'extended mnemonics', TB, SB, and ZB for test bit, set bit, and zero bit. These allowed writing code as if the machine had instructions with byte and bit addressing rather than having to think about the appropriate mask to use with a particular kind of instruction. However, there were several problems with this approach, and we decided that the ability to use symbolic masks, etc. was more important. Hence these macros appear in a modified form or not at all. A very important set of instructions in the 360/370 are the byte string instructions. Unfortunately, the notion provided at the BAL level is rather poor. One problem is that the length field in the instruction is one less than the effective length. Another problem is that the BAL format confuses the length field with the base register field of the first operand. This latter problem is solved by separating out the length field. AL provided the MOVE instruction instead of MVC and the COMP instruction instead of CLC; these names also emphasize the importance and generality of these instructions rather than confusing one with "logical character". Since ALP provides extended macros for more than just MVC and CLC, we elected to use mnemonics closer to the original ones. Note that these extended facilities provide more than just modification of the format. Certain other operations are clarified with appropriate mnemonics. For example: ZR (for Zero Register), RP, RZ, etc. for Register Plus, Zero, and so on (all generate an LTR but imply different condition code tests), and ZI (for Zero Immediate -- an NI with 255-bitvalue mask). Macros useful in ALP for clarification purposes are listed below. Not all are actually required (see the end of section II for those that are built into the translator), but all have been found useful. Note that some AL macros have been changed or replaced, and others (due to our own preferences) discarded. 1 - 33 - AI - Add Immediate CI - Compare Immediate CIL - Compare Immediate Logical DI - Divide Immediate LI - Load Immediate LQS - Load Quoted String LT - Load and Test MI - Multiply Immediate RM - Register Minus RMP - Register Minus or Plus RMZ - Register Minus or Zero RNM - Register Not Minus RNMP - Register Not Minus or Plus RNMZ - Register Not Minus or Zero RNP - Register Not Plus RNZ - Register Not Zero RNZP - Register Not Zero or Plus RP - Register Plus RZ - Register Zero RZP - Register Zero or Plus SI - Subtract Immediate Z - Zero ZB - Zero Byte ZH - Zero Halfword ZHB - Zero High Byte ZHBR - Zero High Byte Register ZI - Zero Immediate ZR - Zero Register EXI - Execute immediate EDIT - Generate edit mask and ED/EDMK instruction MCLC - Multiple Compare Logical Characters MMVC - Multiple Move Characters MNC - Multiple AND Characters MOC - Multiple OR Characters MXC - Multiple Exclusive-OR Characters MFC - Multiple Fill Characters MTR - Multiple Translate MTRT - Multiple Translate and Test MZC - Multiple Zero Characters DF - Define Flags SF - Set Flags TF - Test Flags ZF - Zero Flags DEBLANK - Deblank a string OPENP - Check for successful open See sections VII and VIII for further information on these macros. 1 - 34 - V. THE IMPLEMENTATION OF ALP ALP has been implemented as a preprocessor to the standard OS/360 assembler, using macros within the assembler in some instances to enhance readability. The preprocessor is written in PL/I using recursive descent, and is approximately 3100 lines long. The post-processor for extracting location counter values is also written in PL/I and is approximately 365 lines long. ALP, the assembler and the post-processor are usually invoked in sequence by a small control program, allowing the two tasks to be executed as one job step. Cataloged procedures (see section XI) have been developed for using ALP. 1 - 35 - VI. ALP SYNTAX Notation Non-terminal symbols are lower case identifiers (which may include a "dash") Terminal symbols are either upper case identifiers or special symbols enclosed in quotation marks -> means "is defined as" | indicates alternatives " " means must be entered as is ( ) indicates an optional occurrence (0 or 1 times) ( )* indicates multiple optional occurrences (0 or more times) < > indicates a required selection of one of the enclosed alternatives < >* indicates a required selection of one or more of the enclosed alternatives Some non-terminals are left undefined. Their meaning should be obvious from their names. 1 - 36 - program -> statements ";" END ";" statements -> statement (";" statement)* statement -> (label ":")* compound-statement -> "<" statements ">" | BEGIN statements END simple-statement -> if | case | select | loop | goto | exit | next | mapping | data | conditional-assembly | macro | format-control | bal | cc | bal | comment if -> IF predicate THEN statement (ELSE statement) case -> CASE register-id (case-option)* ";" case-list ENDCASE (ELSE statement) (THEN statement) case-option -> MAX expression | MIN expression | CHECK case-list -> * case-label-list -> case-label ("," case-label)* case-label -> expression (THRU expression) select -> SELECT (FIRST) ";" selection-list ENDSEL (ELSE statement) (THEN statement) selection-list -> * loop -> predicate DO statement (THEN statement) | DO statement predicate (THEN statement) | FOR register-id DO statement (THEN statement) | DO statement FOR register-id (THEN statement) | DO statement (THEN statement) | FOREVER DO statement | DO statement FOREVER goto -> target (IF predicate) exit -> EXIT (FROM label) (IF predicate) 1 - 37 - next -> NEXT (OF label) (IF predicate) mapping -> USE register AS dsect-id ("," register AS dsect-id)* IN statement data -> DATA statement conditional-assembly -> asm-if | asm-case | asm-select | asm-loop | asm-goto | asm-exit | asm-next asm-if -> ASM IF setb-expression THEN statement (ELSE statement) asm-case -> ASM CASE set-expression ";" asm-case-list ENDCASE (ELSE statement) (THEN statement) asm-case-list -> * asm-case-label-list -> asm-case-label ("," asm-case-label)* asm-case-label -> set-expression (THRU set-expression) asm-select -> ASM SELECT (FIRST) ";" asm-selection-list ENDSEL (ELSE statement) (THEN statement) asm-selection-list -> * asm-loop -> ASM setb-expression DO statement (THEN statement) | ASM DO statement setb-expression (THEN statement) | ASM FOR seta-variable (FROM seta-expression) (BY seta-expression) (TO seta-expression) DO statement (THEN statement) | ASM DO statement FOR seta-variable (BY seta-expression) (TO seta-expression) (THEN statement) | ASM DO statement (THEN statement) | ASM FOREVER DO statement | ASM DO statement FOREVER asm-goto -> ASM GOTO sequence-symbol (IF setb-expression) asm-exit -> ASM EXIT (FROM sequence-symbol) (IF setb-expression) asm-next -> ASM NEXT (OF sequence-symbol) (IF setb-expression) macro -> MACRO (macro-label) macro-name (macro-operands) macro-label -> "&&"label":" macro-operands -> "&&"identifier (",&&"identifier)* 1 - 38 - format-control -> EJECT SPACE ( integer ) TITLE "'" title "'" SUBTITLE "'" subtitle "'" bal -> BAL; bal-segment ALP; comment -> COMMENT; text ALP; cc -> CC condition-code-string condition-code-string -> "> | predicate "&" predicate | predicate "|" predicate comment -> "%" text "end-of-line" 1 - 39 - VII. ALP READABILITY MACROS In the description that follows, r is a register a is any relocatable expression that is valid in an instruction c is a constant Macro Name Code Generated AI r,c Add Immediate LA r,c(,r) AI 0,c Add Immediate AL 0,=A(c) CI r,c Compare Immediate C r,=A(c) CIL r,c Compare Immediate CL r,=A(c) Logical DI r,c Divide Immediate D r,=A(c) LI r,c Load Immediate LA r,c LQS rx,ry,'str' Load Quoted String LA rx,=C'str' LA ry,length LT r,a Load and Test L r,a LTR r,r MI r,c Multiply Immediate MH r,=AL2(c) RM r Register Minus LTR r,r RMP r Register Minus or Plus LTR r,r RMZ r Register Minus or Zero LTR r,r RNM r Register Not Minus LTR r,r RNMP r Register Not Minus LTR r,r or Plus RNMZ r Register Not Minus LTR r,r or Zero RNP r Register Not Plus LTR r,r RNZ r Register Not Zero LTR r,r RNZP r Register Not Zero LTR r,r or Plus 1 - 40 - RP r Register Plus LTR r,r RZ r Register Zero LTR r,r RZP r Register Zero or Plus LTR r,r SI r,1 Subtract Immediate BCTR r,0 SI r,2 Subtract Immediate BCTR r,0 BCTR r,0 SI r,c Subtract Immediate SL r,=A(c) Z r,a Zero SR r,r ST r,a Z ,a Zero XC a(4),a ZB r,a Zero Byte SR r,r STC r,a ZB ,a Zero Byte MVI a,0 ZH r,a Zero Halfword SR r,r STH r,a ZH ,a Zero Halfword XC a(2),a ZHB a Zero High Byte MVI a,0 ZHBR r Zero High Byte Register LA r,0(,r) ZHBR 0 Zero High Byte Register N 0,=XL4'00FFFFFF' ZI a,c Zero Immediate NI a,255-(c) ZR r Zero Register SR r,r 1 - 41 - VIII. Macros for Environment Enhancement Conventions Macro operands are described using the following terms: cexpr4 - denote expressions which evaluate to a constant to be held in 4 bits cexpr8 - denote expressions which evaluate to a constant to be held in 8 bits relexpri - denotes a relocatable expression that is valid as a storage address in an instruction symbol - an identifier acceptable to the assembler reg - any register preg - any register except 0 1 - 42 - AREA, AREAORG and AREAEND - Define a structured storage area + ____________________________________________________________ AREA and AREAEND are used to define an area of storage which is structured into smaller named components. AREA begins the definition, DSs and DCs follow, and AREAEND terminates the definition. AREAORG is used to ORG back to the start of the area so that fields may be overlaid. The length of the area will be the maximum attained. AREA alignment<,DSECT=NO> symbol symbol The name of the total storage area. The length attribute will be correctly set. alignment X,H,F,D,0X,0H,0F,0D Specifies the boundary alignment for the area. Default is X (byte alignment). DSECT=NO Indicates that the area is not to be a DSECT. AREAEND symbol symbol A symbol which is to be EQUed to the length of the area. alignment X,H,F,D,0X,0H,0F,0D Specifies the boundary alignment for the end of the area. Default is what was specified in the AREA macro. 1 - 43 - AREAORG symbol symbol A symbol which is to be EQUed to the current length of the area. alignment X,H,F,D,0X,0H,0F,0D Specifies boundary alignment for the end of this overlay of the area. Default is what was specified in the AREA macro. NOTE: Area definitions may be nested. DSECT=NO is implied at the inner levels. EXAMPLE: WA AREA F WATEMP DS F WABYTE DS X WAHALF DS H WASIZE AREAEND 1 - 44 - EXAMPLE: WA AREA F WATEMP DS F WA2 AREA D WABYTE DS X WAHALF DS H WA2SIZE AREAEND WAHALF2 DS H WASIZE AREAEND generates WA DSECT WATEMP DS F WA2 DS OD WABYTE DS X WAHALF DS H DS OD WA2SIZE EQU *-WA2 WAHALF2 DS H DS OF WASIZE EQU *-WA prevsect CSECT where "prevsect" is the previous CSECT name 1 - 45 - DEBLANK - Deblank a string + __________________________ The DEBLANK macro removes leading and/or trailing blanks from a string. DEBLANK loc-reg,len-reg<,work-reg><,TYPE=symbol> <,NULL=NO><,ZERO=NO><,LABEL=symbol><,FILL=char> <,FILADDR=byte> loc-reg preg Specifies the starting address of the string to be deblanked. len-reg reg Specifies the length of the string to be deblanked. After the termination of the macro, this register will contain the new length of the deblanked string. work-reg preg Provides a work register to be used in the search. More efficient code may be generated if this register is provided. TYPE=symbol LEFT, RIGHT, or BOTH Specifies elimination of leading (LEFT) or trailing (RIGHT) blanks, or both (BOTH). Default is RIGHT. NULL=NO The NO condition specifies that the resulting string will never be 0. More efficient code may be generated if this option is specified. ZERO=NO The NO condition specifies that the value in the len register will never be 0. More efficient code may be generated if this option is specified. 1 - 46 - LABEL=symbol relexpri The location to receive control if the resulting string has a length of zero. FILL=char cexpr8 Used to specify a character other than blank to be stripped. FILADDR=byte relexpri Used to specify the location of the character to be stripped. May not be used with FILL. RETURNS: loc-reg = location of deblanked string len-reg = length of deblanked string 1 - 47 - EDIT - Generate edit mask and ED/EDMK instruction + _________________________________________________ EDIT is used to create both an appropriate mask string or editing numeric data and the ED or EDMK instruction to perform the requested operation. EDIT to-field,from-field<,to-length><,from-length> <,CALC=NO><,DIGITS=n><,MARK=YES> to-field relexpri or (preg) The address of the field to contain the edited source digits. It must be an even number of bytes in length. from-field relexpri or (preg) The address of the field containing the source digits to be EDITed to the to-field. It must contain sufficient digits to satisfy the implicit (or explicit) length of the to-field. to-length cexpr4 An explicit specification of the length of the to-field. It must be specified if the to-field is presented in base-displacement form. If specified it will override the implicit length for the to-field. from-length cexpr4 An explicit specification of the length of the from-field. It must be specified if the from-field is specified in base-displacement form. If specified it overrides the implicit length for the from-field. CALC=NO Indicates that the addresses specified are to be used exactly as is for the from- and to-fields in the generated ED or EDMK instruction. If not specified the macro will calculate the offset in the from-field to use in the ED or EDMK instruction. 1 - 48 - DIGITS=n cexpr4 Specifies the minimum number of significant digits to be produced. MARK=YES Indicates that an EDMK instruction should be generated. Register 1 will then point to the first significant character in the edited field. If the field does not produce a significatn digit, register 1 will point to the low order character of the edited field. 1 - 49 - EXI and EXORG - Execute immediate + _________________________________ EXI permits the instruction to be executed by an EX instruction to be coded at the same place in the source program. EXI ex-reg,opcode,operand1,operand2,, ex-reg reg The register to be used as the first operand of the EX instruction. opcode valid assembler opcode Operation code of the instruction to be executed. operand1 The first operand of the instruction to be executed. operand2 The second operand of the instruction to be executed. DECR=YES Specifies that the register is to be decremented by one before the EX instruction. INCR=YES Specifies that the register is to be incremented by one after the EX instruction. The condition code is not affected. 1 - 50 - NOTES: 1. The opcode to be executed may not be a macro unless it is one of the following: MCLC, MMVC, MNC, MOC, MTC, MTR, MTRT, MXC, MZC. When one of these is used, N=1 and a length of zero are forced. 2. An EXORG must be included within addressable range in order to assemble the instructions to be executed. 3. If an instruction occurs more than once, EXORG will assemble only one copy. 1 - 51 - Extended Length Facilities + __________________________ These macros generate inline code to provide extended length facilities. These macros provide an optional N=count operand to allow the writer to specify the exact number of instructions to be generated. If N=count is not present, and the length operand is an unsigned integer or a SETA symbol, then as many instructions as are required for the specified length will be generated. If N=count is not present and the length operand is not an unsigned integer or SETA symbol, then one instruction is generated. MCLC, MMVC, MNC, MOC, and MXC opcd oper1,oper2,length<,N=count><,ZERO=NULL> opcd MCLC, MMVC, MNC, MOC, or MXC oper1 relexpri or (preg) The address of the 1st operand. oper2 relexpri or (preg) The address of the 2nd operand. length The number of bytes affected. N=count unsigned integer or SETA symbol The number of instructions to be generated. ZERO=NULL Specifies that no instructions are to be generated if len is zero. Normally a single instruction would be generated. 1 - 52 - MFC - Fill a field + __________________ The MFC macro will fill a field with the specified charater. MFC loc,len<,FILL=char><,N=count><,ZERO=NULL> loc relexpri or (preg) The address of the field to be filled. len The length of the field to be filled. FILL=char cexpr8 The character to fill the field with. Default is blank (C' ') N=count unsigned integer or SETA symbol The number of instructions to be generated. ZERO=NULL Specifies that no instructions are to be generated if len is zero. 1 - 53 - MTC - Test a field + __________________ MTC tests a field for all zero (or other specified value) bytes. MTC loc,len<,FILL=char><,N=count><,ZERO=NULL> loc relexpri or (preg) Address of field to be tested. len Length of field. FILL=char cexpr8 The character to be tested for. Default is 0. N=count unsigned integer or SETA symbol Number of instructions to be generated. ZERO=NULL Specifies that no test is to be performed if len is zero. The condition code will be set to zero in that case. NOTE: If FILL is not specified, OC instructions are generated to test the field for zeros. If FILL is specified, CLC instructions are generated, even if FILL=0 is specified. 1 - 54 - MTR - Translate a field + _______________________ MTR translates a field using a specified translate table. MTR loc,table,len<,N=count><,ZERO=NULL> loc relexpri or (preg) Location of field to be translated. table relexpri or (preg) Location of translate table. len Length of field. N=count unsigned integer or SETA symbol Number of TR instructions to be generated. ZERO=NULL Specifies that no instructions are to be generated if len is zero. 1 - 55 - MTRT - Translate and test a field + _________________________________ MTRT performs a translate-and-test on a field. MTRT loc,table,len<,N=count><,ZERO=NULL> loc relexpri or (preg) Location of field. table relexpri or (preg) Location of translate-and-test table. len Length of field. N=count unsigned integer or SETA symbol Number of instructions to be generated. ZERO=NULL Specifies that no translate and test is to be performed if len is zero. The condition code is set to zero in that case. 1 - 56 - MZC - Clear a field + ___________________ The MZC macro will clear a field to all X'00's. MZC loc,len<,N=count><,ZERO=NULL> loc relexpri or (preg) The address of the field to be zeroed. len The length of the field to be zeroed. N=count unsigned integer or SETA symbol. The number of instructions to be generated. ZERO=NULL Specifies that no instructions are to be generated if len is zero. 1 - 57 - DF - Define flags + _________________ DF is used to define one or more flag bits and optionally assign initial values. DF flag-name,... flag-name symbol The name of the flag to be defined. Any number of flags may be specified. If more than 8 are specified, more than 1 byte will be reserved. INIT=(flag-name,...) list of symbols Specifies flags which are to be initially 1 (on). 1 - 58 - SF - Set flags + ______________ SF is used to turn on one or more flags defined with DF. SF flag-name,... flag-name symbol The name of a flag to be turned on (set to 1). Up to 8 flags may be specified; all must reside in the same byte. 1 - 59 - TF - Test flags + _______________ TF is used to test one or more flags defined with DF. TF flag-name,... flag-name symbol The name of a flag to be tested. Up to 8 flags may be specified; all must reside in the same byte. RETURNS: CC = Z all tested flags off O all tested flags on M some on, some off 1 - 60 - ZF - Zero flags + _______________ ZF is used to turn off one or more flags defined with DF. ZF flag-name,... flag-name symbol The name of a flag to be cleared. Up to 8 flags may be specified; all must reside in the same byte. 1 - 61 - OSCALL - Pass control to an OS-type subroutine + ______________________________________________ The OSCALL macro will pass control to a specified subroutine using OS calling conventions. OSCALL routine<,A><,R1=parm><,R0=parm> <,R15=parm> routine relexpra or vsymbol or (preg) The address of the subroutine to be called. A The address specified in the routine parameter is a relexpra. R1=parm addrla A parameter to be passed in register 1. R0=parm addrla A parameter to be passed in register 0. R15=parm addrla A parameter to be passed in register 15. NOTE: Register 15 is loaded with the entry point address unless R15=parm is specified 1 - 62 - OSENTER - Generate OS entry code + ________________________________ The OSENTER macro will generate proper OS entry linkage code. OSENTER <(reg1,reg2),...><,ENTRY=NO> <,BASE=NO><,SAVE=area><,PACK=YES> <,FORWARD=YES><,ID=identification> reg1,reg2 regs Registers to be saved in STM form. Any number of parenthesized pairs may be specified. If reg2 is the same as reg1, then reg2 and the parentheses may be omitted. ENTRY=NO Requests that an ENTRY point not be generated. BASE=NO Requests that a base register not be established. SAVE=area relexpri The address of the users register save area. PACK=YES Registers are to be stored packed at 12 bytes after the start of the save area. FORWARD=YES Specifies that the forward linking of save areas is to be performed. Normally only backward linking is done. ID=identification symbol or string or * Specifies an identifying character string to be assembled 4 bytes after the entry point. * indicates that the entry name (or the CSECT name if there is no entry name) is to be used. NOTES: 1. The base register is BASER (see OSSETUP). 2. If SAVE=area is not specified, then no new save area will be established. 3. The generated code does not depend on register 15 being loaded with the entry point address unless ID=identification is specified. 1 - 63 - OSEXIT - Generate OS return code + ________________________________ The OSEXIT macro will generate proper OS exit linkage code. OSEXIT <(reg1,reg2)...>,<,SAVE=area><,LTR=reg> <,PACK=YES><,RC=value><,FLAG=YES> reg1,reg2 registers Registers to be restored in LM format. Any number of parenthesized pairs may be specified. When reg2 is the same as reg1, reg2 and the parentheses may be omitted. SAVE=area relexpri The address of the program's register save area. LTR=reg reg Requests that an LTR reg,reg be performed to set the condition code upon return. PACK=YES Must be specified if PACK=YES was coded on the corresponding OSENTER macro. RC=value valuela Specifies a return code to be loaded into register 15. FLAG=YES Specifies that X'FF' is to be placed into the high-order byte of word 4 of the save area after the registers are restored. NOTE: If SAVE=area is not specified, then the registers are restored from the area pointed to by register 13. Note that SAVE=0(SAVER) and SAVE=0(13) are perfectly acceptable. 1 - 64 - OSSETUP - Set up OS linkage environment + _______________________________________ The OSSETUP macro, used once at the start of the program (after macro definitions, but before any code or EQUs), defines register names and optionally defines certain OS control blocks. symbol OSSETUP <,DCB=YES> <,R15=name><,R14=name><,R13=name><,BASER=name> <,R1=name><,R0=name> symbol 1-8 characters (required) CSECT name for the module. REGS=option PLI or NO PLI is used to request PL/I compatible register definitions. NO specifies that register definitions should not be included. DCB=YES Define OS DCB DSECT. R15=name symbol Name to be used by OSENTER, OSEXIT and OSCALL to refer to register 15. Default is RCR. R14=name symbol Name to be used by OSENTER, OSEXIT and OSCALL to refer to register 14. Default is RTNR. R13=name symbol Name to be used by OSENTER, OSEXIT and OSCALL to refer to register 13. Default is SAVER. BASER=name symbol Register to be loaded by OSENTER as a base register. Default is BASER. R1=name Name to be used by OSENTER, OSEXIT and OSCALL to refer to register 1. Default is VR1. R0=name Name to be used by OSENTER, OSEXIT and OSCALL to refer to register 0. Default is VR0. 1 - 65 - NOTE: Register definitions are as follows: Default PLI Register Absolute name Symbolic name Symbolic name 0 R0 VR0 VR0 1 R1 VR1 VR1 2 R2 XRA, LOWR XRA,HIGHR 3 R3 XRB XRB 4 R4 XRC XRC 5 R5 XRD XRD 6 R6 XRE XRE 7 R7 XRF XRF 8 R8 XRG XRG 9 R9 XRH XRH 10 R10 XRI XRI 11 R11 XRJ BASER,HIGHR 12 R12 BASER, HIGHR GCBR 13 R13 SAVER SAVER 14 R14 RTNR RTNR 15 R15 RCR RCR LOWR and HIGHR are for use with OSENTER and OSEXIT when specifying registers to be saved and restored. 1 - 66 - OPENP - Check for successful open + _________________________________ The OPENP macro will check DCBOFLGS to see if the DCB was opened successfully. OPENP dcb-addr dcb-addr relexpri The address of the DCB to be checked. RETURNS: If the DCB was opened successfully, the condition code will be set to a non-zero value. NOTE: The DCBD macro must be included in the assembly. 1 - 67 - CBDELINK - Remove control block from linked list + ________________________________________________ CBDELINK is used to remove a control block from a linked list of similar control blocks. CBDELINK prev-reg,del-reg,work-reg,HEAD=loc <,TAIL=loc>,NEXT=dsect-loc <,BACK=dsect-loc> <,CB=dsect-name><,ZOT=YES> prev-reg preg Register must contain a pointer to the control block which immediately preceeds the one to be removed. Should contain zero if removing from the beginning of the list. del-reg preg Register must contain a pointer to the control block to be removed from the list. work-reg preg A work register. HEAD=loc relexpri Location of a word which contains a pointer to the first element in the list. Contains zero when the list is empty. TAIL=loc relexpri Location of a word which contains a pointer to the last element in the list. Contains zero when the list is empty. NEXT=dsect-loc symbol Name of the word defined in a DSECT for the control block which points to the next control block in the list. Contains zero for the last element in the list. BACK=dsect-loc symbol If present, indicates a doubly-linked list (forward and backward pointers). Name of the word defined in a DSECT for the control block which points to the preceeding control block in the list. Contains zero for the first element in the list. 1 - 68 - CB=dsect-id symbol The name of the DSECT for the control block. Omit if the control block is defined with EQUs instead of a DSECT. ZOT=YES Indicates that the NEXT and BACK fields in the control block being removed should be set to zero. 1 - 69 - CBDLINKH - Remove control block from head of linked list + ________________________________________________________ CBDLINKH is used to remove the first control block from a linked list of similar control blocks. CBDLINKH del-reg,work-reg,HEAD=loc<,TAIL=loc> NEXT=dsect-loc<,BACK=dsect-loc> <,CB=dsect-name><,ZOT=YES> del-reg preg Register must contain a pointer to the first control block in the linked list. work-reg preg A work register. HEAD=loc relexpri Location of a word which contains a pointer to the first element in the list. Contains zero when the list is empty. TAIL=loc relexpri Location of a word which contains a pointer to the last element in the list. Contains zero when the list is empty. NEXT=dsect-loc symbol Name of the word defined in a DSECT for the control block which points to the next control block in the list. Contains zero for the last element in the list. BACK=dsect-loc symbol If present, indicates a doubly-linked list (forward and backward pointers). Name of the word defined in a DSECT for the control block which points to the preceeding control block in the list. Contains zero for the first element in the list. CB=dsect-id symbol The name of the DSECT for the control block. Omit if the control block is defined with EQUs instead of a DSECT. ZOT=YES Indicates that the NEXT and BACK fields in the control block being removed should be set to zero. 1 - 70 - CBDLINKT - Remove control block from tail of a linked list + __________________________________________________________ CBDLINKT is used to remove the last control block from a linked list of similar control blocks. CBDLINKT prev-reg<,del-reg>,work-reg,head=loc <,TAIL=loc>,NEXT=dsect-loc <,BACK=dsect-loc><,CB=dsect-name> <,ZOT=YES> prev-reg preg Register must contain a pointer to the control block which immediately preceeds the one to be removed. Should contain zero if removing from the beginning of the list. del-reg preg Register must contain a pointer to the control block to be removed from the list. Required only if ZOT=YES is specified. work-reg preg A work register. HEAD=loc relexpri Location of a word which contains a pointer to the first element in the list. Contains zero when the list is empty. TAIL=loc relexpri Location of a word which contains a pointer to the last element in the list. Contains zero when the list is empty. NEXT=dsect-loc symbol Name of the word defined in a DSECT for the control block which points to the next control block in the list. Contains zero for the last element in the list. BACK=dsect-loc symbol If present, indicates a doubly-linked list (forward and backward pointers). Name of the word defined in a DSECT for the control block which points to the preceeding control block in the list. Contains zero for the first element in the list. 1 - 71 - CB=dsect-id symbol The name of the DSECT for the control block. Omit if the control block is defined with EQUs instead of a DSECT. ZOT=YES Indicates that the NEXT and BACK fields in the control block being removed should be set to zero. 1 - 72 - CBLINK - Add control block to linked list + _________________________________________ CBLINK is used to add a control block anywhere in a linked list of similar control blocks. CBLINK after-reg,new-reg,work-reg,HEAD=loc <,TAIL=loc>,NEXT=dsect-loc, <,BACK=dsect-loc><,CB=dsect-id> after-reg preg Register containing a pointer to the control block after which the new control block is to be added. Should contain zero if the new control block is to be first in the list. new-reg preg Register must contain a pointer to the control block to be added. work-reg preg A work register. HEAD=loc relexpri Location of a word which contains a pointer to the first element in the list. Contains zero when the list is empty. TAIL=loc relexpri Location of a word which contains a pointer to the last element in the list. Contains zero when the list is empty. NEXT=dsect-loc symbol Name of the word defined in a DSECT for the control block which points to the next control block in the list. Contains zero for the last element in the list. BACK=dsect-loc symbol If present, indicates a doubly-linked list (forward and backward pointers). Name of the word defined in a DSECT for the control block which points to the preceeding control block in the list. Contains zero for the first element in the list. CB=dsect-id symbol The name of the DSECT for the control block. Omit if the control block is defined with EQUs instead of a DSECT. 1 - 73 - CBLINKH - Add a control block at the head of a linked list + __________________________________________________________ CBLINKH is used to add a control block at the start of a linked list of similar control blocks. CBLINKH new-reg,work-reg,HEAD=loc<,TAIL=loc>, NEXT=dsect-loc<,BACK=dsect-loc> <,CB=dsect-id> new-reg preg Register must contain a pointer to the control block to be added. work-reg preg A work register. HEAD=loc relexpri Location of a word which contains a pointer to the first element in the list. Contains zero when the list is empty. TAIL=loc relexpri Location of a word which contains a pointer to the last element in the list. Contains zero when the list is empty. NEXT=dsect-loc symbol Name of the word defined in a DSECT for the control block which points to the next control block which in the list. Contains zero for the last element in the list. BACK=dsect-loc symbol If present, indicates a doubly-linked list (forward and backward pointers). Name of the word defined in a DSECT for the control block which points to the preceeding control block in the list. Contains zero for the first element in the list. CB=dsect-id symbol The name of the DSECT for the control block. Omit if the control block is defined with EQUs instead of a DSECT. 1 - 74 - CBLINKT - Add control block at the tail of a linked list + ________________________________________________________ CBLINKT is used to add a control block at the end of a linked list of similar control blocks. CBLINKT new-reg,work-reg,HEAD=loc,TAIL=loc, NEXT=dsect-loc<,BACK=dsect-loc> <,CB=dsect-id> new-reg preg Register must contain a pointer to the control block to be added. work-reg preg A work register. HEAD=loc relexpri Location of a word which contains a pointer to the first element in the list. Contains zero when the list is empty. TAIL=loc relexpri Location of a word which contains a pointer to the last element in the list Contains zero when the list is empty. NEXT=dsect-loc symbol Name of the word defined in a DSECT for the control block which points to the next control block in the list. Contains zero for the last element in the list. BACK=dsect-loc symbol If present, indicates a doubly-linked list (forward and backward pointers). Name of the word defined in a DSECT for the control block which points to the preceeding control block in the list. Contains zero for the first element in the list. CB=dsect-id symbol The name of the DSECT for the control block. Omit if the control block is defined with EQUs instead of a DSECT. 1 - 75 - IX. ALP CODING HINTS 1. Use indentation to indicate the nesting level. The ALP listing shows the current nesting level to the left of each input line. It is increased by BEGIN, <, CASE, SELECT, ASM CASE, ASM SELECT and MACRO and is reduced by END, >, ENDCASE, ENDSEL and MEND. With WYLBUR, tabs can be set every few positions (say 3) and each line indented by the number of tabs equal to its nesting level. 2. Avoid using explicit branching or "GOTOs". The ALP control structures show intent much more clearly. 3. Use the readability and environment macros -- they make the intent of a program much clearer. 4. Use the assembler USING statement for "global" base registers and the ALP USE statement for "local" base registers. 5. Using symbolic register names makes a program easier to understand. Name registers according to function. The OSSETUP macro provides one possible set of names. 6. Never use two names for the same register in a single section of code. 7. Always use RGOTO instead of BR and GOTO instead of B (if you must use explicit branching). 1 - 76 - X. SAMPLE PROGRAM The following problem is taken from an actual class for beginning assembly language programmers. Given: 50 full words in core, each containing a fixed-point (binary) value. The instructor will give you this data (in the form of DC statements) and describe the necessary JCL. The first constant will be labeled NUMBERS. Task: You are to determine the number of positive constants, the number of negative constants and the number of zero constants, as well as the sum of each of these. Store the five computed values into core and output them via a core dump. JFDUMP will be described in class. Computing the sums will not result in overflow. 1 - 77 - Assembly Language Solution: // EXEC ASMHCOMP //COMP.SYSIN DD * PROB1 START 0 SAVE (14,12),,* BALR 10,0 USING *,10 LA 12,SAVE ST 13,4(12) ST 12,8(13) LR 13,12 LA 2,50 MAX TIMES THRU SR 3,3 ZERO INDEX REG SR 4,4 # OF POS VALUES SR 5,5 # OF NEG VALUES SR 6,6 # OF ZERO VALUES TOP L 7,NUMBERS(3) GET VALUE LTR 7,7 SET CC BP POS POSITIVE BM NEG NEGAGIVE LA 6,1(,6) BUMP ZERO CTR GOBACK LA 3,4(,3) BUMP POINTER BCT 2,TOP KEEP GOING STM 4,6,NUMS SAVE RESULTS JFDUMP START=PROB1,END=NUMS+12 L 13,4(13) GO BACK RETURN (14,12),RC=0 POS LA 4,1(,4) BUMP COUNTER L 8,POSNUM GET # OF POS AR 8,7 ADD TO IT ST 8,POSNUM SAVE IT BACK B GOBACK KEEP GOING NEG LA 5,1(,5) BUMP COUNTER L 8,NEGNUM GET NUMBER AR 8,7 ADD TO IT ST 8,NEGNUM RESTORE IT B GOBACK KEEP GOING SAVE DC 18F'0' SAVE AREA NUMBERS DC 2F'8,1,1,0,2,-2,0,3,-3,0,4,-4,0,5,-5,0,6,-6,0,7,-7,0,8,-8,0' POSNUM DC F'0' POSITIVE VALUE NEGNUM DC F'0' NEGATIVE VALUE NUMS DS 3F COUNTERS END // EXEC ASMHLKGO //GO.SYSUDUMP DD SYSOUT=A 1 - 78 - ALP Solution (without macros): // EXEC ALPHCOMP //COMP.SYSIN DD * PROB1: START 0; SAVE (14,12),,*; BALR 10,0; USING *,10; LA 12,SAVE; ST 13,4(,12); ST 12,8(,13); LR 13,12; LI 2,50; % NUMBER OF TIMES THRU SR 3,3; % CLEAR INDEX REGISTER SR 4,4; % NUMBER OF POS VALUES SR 5,5; % NUMBER OF NEG VALUES SR 6,6; % NUMBER OF ZERO VALUES DO BEGIN L 7,NUMBERS(3); % GET VALUE IF THEN LA 6,1(,6) % ZERO VALUE ELSE IF THEN BEGIN % POSITIVE VALUE LA 4,1(,4); % BUMP COUNTER L 8,POSNUM; AR 8,7; ST 8,POSNUM; % COMPUTE SUM END ELSE BEGIN % NEGATIVE VALUE LA 5,1(,5); % BUMP COUNTER L 8,NEGNUM; AR 8,7; ST 8,NEGNUM; % COMPUTE SUM END; LA 3,4(,3); % BUMP POINTER END FOR 2; STM 4,6,NUMS; % SAVE RESULTS JFDUMP START=PROB1,END=NUMS+12; L 13,4(,13); RETURN (14,12),RC=0; SAVE: DC 18F'0'; % SAVE AREA NUMBERS: DC 2F'8,1,1,0,2,-2,0,3,-3,0,4,-4,0,5,-5,0,6,-6,'_ '0,7,-7,0,8,-8,0'; POSNUM: DC F'0'; % POSITIVE VALUE NEGNUM: DC F'0'; % NEGATIVE VALUE NUMS: DS 3F; END; // EXEC ALPHLKGO //GO.SYSUDUMP DD SYSOUT=A 1 - 79 - ALP Solution (with macros): // EXEC ALPHCOMP //COMP.SYSIN DD * PROB: TITLE 'CLASS PROBLEM 1'; PROB1: OSSETUP; SUBTITLE 'MAIN PROGRAM'; OSENTER (RTNR,HIGHR),SAVE=SAVE,FORWARD=YES; LI XRA,50; % NUMBER OF TIMES THRU ZR XRB; % CLEAR INDEX REGISTER ZR XRC; % NUMBER OF POS VALUES ZR XRD; % NUMBER OF NEG VALUES ZR XRE; % NUMBER OF ZERO VALUES DO BEGIN L XRG,NUMBERS(XRB); % GET NUMBER IF THEN AI XRE,1 % ZERO VALUE ELSE IF THEN BEGIN % POSITIVE VALUE AI XRC,1; % BUMP COUNTER L XRH,POSNUM; AR XRH,XRG; ST XRH,POSNUM; % COMPUTE SUM END ELSE BEGIN % NEGATIVE VALUE AI XRD,1; % BUMP COUNTER L XRH,NEGNUM; AR XRH,XRG; ST XRH,NEGNUM; % COMPUTE SUM END; AI XRB,4; % BUMP POINTER END FOR XRA; STM XRC,XRE,NUMS; % SAVE RESULTS JFDUMP START=PROB1,END=NUMS+12; OSEXIT (RTNR,HIGHR),RC=0,SAVE=SAVE; SUBTITLE 'CONSTANTS AND WORK AREA'; SAVE: DC 18F'0'; % SAVE AREA NUMBERS: DC 2F'8,1,1,0,2,-2,0,3,-3,0,4,-4,0,5,-5,0,6,-6,'_ '0,7,-7,0,8,-8,0'; POSNUM: DC F'0'; % POSITIVE VALUE NEGNUM: DC F'0'; % NEGATIVE VALUE NUMS: DS 3F; END; // EXEC ALPHLKGO //GO.SYSUDUMP DD SYSOUT=A 1 - 80 - XI. USING ALP AT NIH . The following procedures are available and conform to NIH conventions: ALP Procedure Corresponding Assembler Procedure + _____________ _________________________________ ALPHCOMP ASMHCOMP ALPHOBJ ASMHOBJ ALPHCOMF ASMHCOMP ALPHOBJF ASMHOBJ ALPHPRE None ALPHLKGO ASMHLKGO ALPHLDGO ASMHLDGO ALPHLKSM ASMHLKSM ALPHLKMM ASMHLKMM ALPHCALL ASMHCALL ALPHLOOK ASMHLOOK All symbolic parameters are the same. . Normally, ALPHCOMP and ALPHOBJ produce only the ALP listing. However, if ASMLIST='' is specified on the EXEC statement, the assembler listing will be produced as well. . ALPHCOMF and ALPHOBJF differ from ALPHCOMP and ALPHOBJ in that the assembler listing is placed on microfiche. Some additional symbolic parameters are provided to facilitate this: MFID=name Required. Specifies a 1-8 character name to be used to insure uniqueness of the DSNAME on the microfilm tape. Should begin with registered initials. MFNAME='dsname' Optional. Specifies the name of a data set containing PTFORM control records. A default suitable for most applications is included. MFSTOR=unit Optional. Specifies unit name for the PTFORM control data set. Default is MFSTOR=FILE. MFDISK=volume Optional. Specifies the volume on which the PTFORM control data set resides. 1 - 81 - . The procedure ALPHPRE may be used to perform ALP preprocessing without assembling the result. Normally, only the ALP listing is produced. However, if ASMLIST='' is specified on the EXEC statement the generated assembly code will be listed as well. . Problems or questions concerning ALP should be forwarded to the PAL Unit, Computer Center, DCRT, Building 12A, Room 1017, accompanied by a PTR (Programmer Trouble Report) and all necessary computer runs. This is currently the only method of support for this product. 1 - 82 - XII. REFERENCES 1. Fletcher, J. G. et al., "On The Appropriate Language For System Programming", SIGPLAN Notices Vol. 7, No. 7, (July 1972),28-32. 2. Lang, C. A., "Languages for Writing System Programs", in "Software Engineering Techniques". NATO Science Committee 101-106, April 1970. 3. Lyle, L. M., "A Hierarchy of High Order Languages for Systems Programming", SIGPLAN Notices Vol. 6, No. 9, (October 1971), 73&77. 4. Du Bois, P. J. et al., "The LRLTRAN Language As Used in the FROST and FLOE Time-Sharing Operating Systems", SIGPLAN Notices Vol. 6, No. 9, (October 1971), 92-104. 5. Haines, E. C., "AL: A Structured Assembly Language", M72-81, The MITRE Corp., Bedford, Mass., April 1972. Also SIGPLAN Notices Vol. 8, No. 1, (January 1973), 15-20. Also SIGPLAN Notices Vol. 8, No. 4, (April 1973), 16-21. 6. Dijkstra, E. W., "GO TO Statement Considered Harmful", "Communications of the ACM", Vol. 11, No. 3, (March 1968), 147-148. 1 COMMENT FORM Is the ALP User's Guide YES NO Clear? __ __ Well Organized? __ __ Complete? __ __ Accurate? __ __ Suitable for the beginner? __ __ Suitable for the advanced user? __ __ Comments:________________________________________________________ _________________________________________________________________ _________________________________________________________________ _________________________________________________________________ _________________________________________________________________ _________________________________________________________________ _________________________________________________________________ _________________________________________________________________ _________________________________________________________________ _________________________________________________________________ _________________________________________________________________ _________________________________________________________________ _________________________________________________________________ _________________________________________________________________ _________________________________________________________________ _________________________________________________________________ Please give page references where appropriate. If you wish a reply, include your name and mailing address. Send to: NIH DCRT Computer Center Technical Information Office Bldg. 12A, Rm. 1017 Bethesda, Maryland 20892 ,SEPARATOR