04.09.2015 Views

Assembler Language Macro "Boot Camp" Part 2

Macro Boot Camp Part 2.pdf - Kcats.org

Macro Boot Camp Part 2.pdf - Kcats.org

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>Assembler</strong> <strong>Language</strong><br />

<strong>Macro</strong> "<strong>Boot</strong> Camp"<br />

<strong>Part</strong> 2<br />

SHARE in Austin<br />

March 1 - 6, 2009<br />

Session 8159<br />

Who am I?<br />

Michael Stack, K Cats Consulting<br />

Instructor in Computer Science at Northern<br />

Illinois University from 1982 - 2007, including<br />

assembler language, data structures (in<br />

assembler), and applied systems programming<br />

Available Materials<br />

Materials described in these two sessions,<br />

as well as the <strong>Assembler</strong> <strong>Boot</strong> Camp, can be<br />

found at http://www.kcats.org/share<br />

Yesterday's Agenda (Brief Review)<br />

Our First <strong>Macro</strong> Instruction<br />

The Second Version of Our ADD <strong>Macro</strong><br />

The <strong>Macro</strong> Programming <strong>Language</strong><br />

1-4


Today's Agenda<br />

Variable Symbols We Can Change<br />

A Bit More on Variable Symbols<br />

Finally, the Add <strong>Macro</strong> Instruction<br />

Wrap Up<br />

Variable Symbols<br />

We Can Change<br />

(So that's why they're called<br />

Set Symbols)<br />

Set Symbols<br />

Now that we have AIf and AGo to control<br />

the path of code generation, it will be very<br />

useful to have a way to keep assembly-time<br />

data<br />

<strong>Assembler</strong> variables which can hold this<br />

data are called set symbols, of which there<br />

are three data types<br />

Arithmetic<br />

Binary (logical)<br />

Character<br />

Set Symbol Scope<br />

As with high level languages, set symbol<br />

variables have the scope characteristic<br />

The value assigned to a local set symbol is<br />

known only within one macro expansion,<br />

and each expansion of that - or any other -<br />

macro has its own copy of that local variable<br />

The value assigned to a global set symbol is<br />

known throughout the assembly<br />

5-8


Set Symbol Declaration<br />

Modern assemblers do not require that local<br />

Set Symbols be declared before use (older<br />

assemblers do, though)<br />

But it's a good idea to declare (and globals<br />

require it), as it's a great place to document<br />

the purpose of the variable<br />

Declaration describes the variable as<br />

Local or Global<br />

Arithmetic, Binary, or Character<br />

Set Symbol Declaration<br />

To declare a local set symbol of type x<br />

(where x is A, B, or C):<br />

seq_sym Lclx var_sym 1 ,var_sym 2 ,...<br />

where seq_sym may be a sequence symbol<br />

and each var_sym n is a variable symbol<br />

To declare a global set symbol of type x:<br />

seq_sym Gblx var_sym 1 ,var_sym 2 ,...<br />

Although more than one set symbol can be<br />

declared in one statement, limiting to one<br />

leaves room for a descriptive comment<br />

Arithmetic Set Symbol Assignment<br />

The SetA instruction is used to assign a<br />

value to an arithmetic set symbol (from now<br />

on called a SetA symbol)<br />

var_sym SetA arithmetic_expression<br />

var_sym is a variable symbol and<br />

arithmetic_expression (as described earlier)<br />

is evaluated as a signed, 32-bit number<br />

The default (initial) value of a SetA symbol<br />

is zero<br />

Arithmetic Set Symbol Assignment<br />

Example<br />

Here is some sample code:<br />

LclA &S Counter<br />

LclA &Con Assigned "constant"<br />

&S SetA 3 Initial value<br />

&S SetA &S+1 Increment by 1<br />

&Con SetA 2*(1-&S) Set &Con to -6<br />

And here's a real oddity: when &Con<br />

(whose value now is -6) is used in a model<br />

statement, its absolute value is used:<br />

DC F'&Con' Generates 00000006<br />

(Don't ask)<br />

9-12


Arithmetic Set Symbol Assignment<br />

Example<br />

Here is some more sample code, this one to<br />

generate all of the register equates:<br />

<strong>Macro</strong><br />

EQURegs<br />

GblA &EQURegs Recall if already done<br />

LclA &Reg Counter (initially 0)<br />

AIf (&EQURegs NE 0).Done<br />

&EQURegs SetA 1 Don't generate again<br />

.Loop ANOP<br />

R&Reg EQU &Reg<br />

&Reg SetA &Reg+1 Increment reg number<br />

AIf (&Reg LE 15).Loop<br />

.Done MEnd<br />

Arithmetic Set Symbol Assignment<br />

Example<br />

Here is the output (assembler source) from<br />

EQURegs (first time only!)<br />

EQURegs<br />

+R0 EQU 0<br />

+R1 EQU 1<br />

+R2 EQU 2<br />

+R3 EQU 3<br />

+R4 EQU 4<br />

...<br />

+R12 EQU 12<br />

+R13 EQU 13<br />

+R14 EQU 14<br />

+R15 EQU 15<br />

Arithmetic Set Symbol Assignment<br />

Example<br />

Here is a slightly different version of the<br />

same macro (loop test at top):<br />

<strong>Macro</strong><br />

EQURegs<br />

GblA &EQURegs Recall if already done<br />

LclA &Reg Counter (initially 0)<br />

AIf (&EQURegs NE 0).Done<br />

&EQURegs SetA 1 Don't generate again<br />

.Loop AIf (&Reg GT 15).Done<br />

R&Reg EQU &Reg<br />

&Reg SetA &Reg+1 Increment reg number<br />

AGo .Loop<br />

.Done MEnd<br />

Binary (Logical) Set Symbol<br />

Assignment<br />

The SetB instruction is used to assign a<br />

value to a binary set symbol (from now on<br />

called a SetB symbol)<br />

var_sym SetB binary_value<br />

var_sym is a variable symbol and<br />

binary_value (described in the next slide) is<br />

evaluated as a 0 or 1<br />

The default (initial) value of a SetB symbol is<br />

zero<br />

13-16


Binary (Logical) Set Symbol<br />

Assignment<br />

A full description of the binary_value<br />

operand of SetB is beyond the scope of<br />

these sessions; simplified, it can be one of<br />

A binary digit (0 or 1)<br />

A binary value enclosed in parentheses<br />

An arithmetic value enclosed in parentheses<br />

If the value is 0, the assembler assigns a<br />

value of 0 to the symbol in the name field; if<br />

the value is not 0, the assembler assigns a<br />

value of 1<br />

A logical expression enclosed in parentheses<br />

Binary (Logical) Set Symbol<br />

Assignment Examples<br />

Each &X starts with initial &A, &B, & &C<br />

&A SetA 4<br />

&B SetB 1 (Note no parentheses)<br />

&C SetC 'XYZ' (This is a preview of SetC!)<br />

*<br />

&X SetB (&B) &X = ?<br />

&X SetB (NOT &B) &X = ?<br />

&X SetB (&A LE 15) &X = ?<br />

&X SetB ('&C' EQ 'XYZ') &X = ?<br />

&X SetB ((NOT &B) AND (&A LT 15)) &X = ?<br />

&X SetB ((&A GT 0) AND (&A LT 15)) &X = ?<br />

&X SetB (&B OR ('&C' EQ 'YES')) &X = ?<br />

&X SetB (&B AND NOT (&A GT 5)) &X = ?<br />

Character Set Symbol<br />

Assignment<br />

The SetC instruction is used to assign a<br />

value to a character set symbol (from now<br />

on called a SetC symbol)<br />

var_sym SetC 'character_string' note quotes!<br />

character_string is a sequence of characters<br />

and variable symbols (followed by '.' for<br />

concatenation) interpreted as characters<br />

The initial value of a SetC symbol is the null<br />

string<br />

Character Set Symbol<br />

Assignment Examples<br />

Here is a SetC example:<br />

&A SetA 4<br />

&B SetB 1<br />

&C SetC 'XYZ'<br />

*<br />

&X SetC 'A&A.B&B.C&C.' &X = ?<br />

&X evaluates to the string A4B1CXYZ<br />

Note that the arithmetic and binary values<br />

have been converted to character values<br />

(See Concatenation in the next section)<br />

17-20


Substrings of SetC Symbols<br />

Definition<br />

SetC operands can also be substrings by<br />

placing two arithmetic expressions,<br />

separated by commas and enclosed in<br />

parentheses, immediately following the<br />

character expression<br />

The first arithmetic expression identifies the<br />

first character of the substring<br />

The second arithmetic expression gives the<br />

length of the substring<br />

Substrings of SetC Symbols<br />

Examples<br />

'ABCDEF'(3,2) evaluates to 'CD'<br />

If &VAR evaluates to 2 and &STR evaluates<br />

to 'ABCD' then '&STR.%'(2,&VAR*2)<br />

evaluates to 'BCD%'<br />

'AB'.'CD'.'EFG'(1,2).'H' evaluates<br />

to 'ABCDEFH'<br />

(For . see concatenation in the next section)<br />

Meeting<br />

in<br />

Progress<br />

A Bit More on<br />

Variable Symbols<br />

Then we can really go to work!<br />

Concatenation<br />

Concatenation can sometimes be without<br />

ambiguity<br />

&this&that (variable.variable)<br />

this&that (ordinary.variable)<br />

Others are a problem<br />

&thisthat (variable.ordinary intended)<br />

We use the concatenation operator '.' to<br />

avoid the ambiguity<br />

&this.that<br />

21-24


Symbolic Parameter Sublists<br />

A single macro operand can be a list of<br />

elements, called a sublist, with one or more<br />

items enclosed in parentheses and<br />

separated by commas<br />

(X,2,Y)<br />

An individual sublist item can be referred to<br />

by a subscripted symbolic parameter, so if<br />

&ABC has the value (W,15)<br />

&ABC(1) has the value W<br />

&ABC(2) has the value 15<br />

But &ABC.(1) has the value (W,15)(1)<br />

Keyword Symbolic Parameters<br />

<strong>Macro</strong> prototype statements may have<br />

keyword operands as well as positional<br />

These are coded on the prototype as<br />

&Keyword=[default]<br />

The default value is optional<br />

The advantages of keyword parameters are<br />

They can have a default value<br />

They can be coded in any order when invoked<br />

But positionals look more like operands<br />

System Variable Symbols<br />

The third kind of variable symbol after<br />

symbolic parameters and set symbols is the<br />

set of system variable symbols<br />

These all begin with &SYS so this prefix<br />

should be avoided in programmer-created<br />

variable symbols<br />

Some popular examples<br />

&SYSTIME - time of the assembly<br />

&SYSDATC - Y2K-compliant date of assembly<br />

&SYSNDX - (see the following slides)<br />

System Variable Symbol &SYSNDX<br />

Here is a macro - what's its problem?<br />

<strong>Macro</strong><br />

&name AddVal &num,&val<br />

.*<br />

.* <strong>Macro</strong> to add &val to &num<br />

.*<br />

L 0,&num<br />

A 0,FWrd<br />

ST 0,&num<br />

B FWrd+4<br />

FWrd DC F'&val'<br />

MEnd<br />

25-28


System Variable Symbol &SYSNDX<br />

The way it's written, it can be used only<br />

once in an assembly (because of FWrd)<br />

We can fix this by concatenating &SYSNDX<br />

&SYSNDX has a new value assigned by the<br />

assembler each time a macro is called<br />

For the first macro, &SYSNDX is 0001<br />

It increases by 1 for any macro invocation<br />

Until it goes past 9999, it is four characters<br />

This can provide unique labels for macros<br />

System Variable Symbol &SYSNDX<br />

Here is the macro rewritten using &SYSNDX<br />

<strong>Macro</strong><br />

&name Add1 &num,&val<br />

.*<br />

.* <strong>Macro</strong> to add &val to &num<br />

.*<br />

L 0,&num<br />

A 0,FWrd&SYSNDX<br />

ST 0,&num<br />

B FWrd&SYSNDX+4<br />

FWrd&SYSNDX DC F'&val'<br />

MEnd<br />

Attributes of Symbols<br />

As should be expected in a HLL (!) like<br />

assembler, symbols have attributes<br />

We will be concerned with only three<br />

Type, which distinguishes one form of named<br />

object from another, such as character data<br />

from binary data<br />

Count, which gives the number of characters<br />

required to represent the data as a character<br />

string<br />

Number, which gives the number of sublist<br />

entries in a macro instruction operand<br />

Attributes of Symbols<br />

We can refer to these attributes inside<br />

macro instructions by using a single letter<br />

followed by a single quote: T' K' and N'<br />

For example in the Add1 macro<br />

T'FWrd&SYSNDX is F<br />

And if we invoke as Add1 F4,18 then<br />

K'&num is 2<br />

N'&num is 1<br />

We will see more in the next slides<br />

29-32


Finally, The Add<br />

<strong>Macro</strong> Instruction<br />

In which we analyze and<br />

demonstrate an overloaded Add<br />

Add <strong>Macro</strong> Definition:<br />

Prototype and Doc Box 1<br />

<strong>Macro</strong><br />

&Name Add &List,&Sum,&R=1,&WKR=0<br />

.********************************************************************<br />

.*<br />

.* Function:<br />

.* This macro generates assembler instructions to add multiple<br />

.* values held in storage as fullword, halfword, and packed data.<br />

.* The first operand is a sublist of the labels on the numbers<br />

.* to be added. The sum will be returned in register R= as a<br />

.* binary value. Optionally, the sum may be returned in storage<br />

.* at the location given by the second operand, which must be of<br />

.* the fullword, halfword, or packed data type. Instructions<br />

.* will be generated appropriate to the data types.<br />

.*<br />

.* Prototype Statement:<br />

.* &Name Add &List,&Sum,&R=1,&WKR=0<br />

.*<br />

Add <strong>Macro</strong> Definition:<br />

Prototype and Doc Box 2<br />

.*<br />

.* Symbolic Parameters:<br />

.* &List is a sublist of the values to be added, consisting of<br />

.* labels of storage areas of types F, H, and P (required)<br />

.* &Sum is a label of type F, H or P and is the calculated sum<br />

.* (optional)<br />

.* &R= is the sum accumulation register; it is required and<br />

.* must be different from &WKR=; &R always has the result<br />

.* &WKR= is a scratch register for CVB and CVD instructions in<br />

.* case the sum or any summand is type P (required if any<br />

.* binarydecimal conversion is necessary)<br />

.*<br />

.* Error Conditions:<br />

.* Missing summand sublist (8)<br />

.* Incorrect sum or summand type (4)<br />

.*<br />

Add <strong>Macro</strong> Definition:<br />

Prototype and Doc Box 3<br />

.*<br />

.* Notes:<br />

.* Two registers are altered and not saved. By default these<br />

.* are R0 and R1.<br />

.*<br />

.* This exercise and solution are patterned after the ADD macro<br />

.* in _<strong>Assembler</strong> <strong>Language</strong> Programming for the IBM 370, ASSIST<br />

.* Edition_, by Frank M. Carrano, p. 18.34<br />

.*<br />

.********************************************************************<br />

.*<br />

33-36


Add <strong>Macro</strong> Definition:<br />

Set Symbol Declaration & Init<br />

.*<br />

.* Define and initialize local set symbols<br />

.*<br />

LclA &J &List loop counter<br />

LclB &P 1 if decimal summand seen, else 0<br />

LclC &A Current binary operation (L or A)<br />

LclC &DEC Current decimal op (ZAP or AP)<br />

LclC &H 'H' if LH or AH, '' if L or A<br />

LclC &D Unique label for work area<br />

LclC &NM &Name for flexibility in use<br />

.*<br />

&J SetA 1 Start with first summand<br />

&P SetB 0 No decimal summands yet<br />

&A SetC 'L' First time use L, then A<br />

&DEC SetC 'ZAP' First time use ZAP, then AP<br />

&H SetC '' Set to 'H' if binary is halfword<br />

&D SetC 'DWrd&SYSNDX' Unique label for D work area<br />

&NM SetC '&Name' &NM can be cleared, &Name cannot<br />

.*<br />

Add <strong>Macro</strong> Definition:<br />

Initial Check, Main Loop<br />

.*<br />

.* Sublist &List is required - quit if not present, CC=8<br />

.*<br />

AIf (K'&List NE 0).Loop<br />

MNote 8,'** Error: Required list of summands missing ***'<br />

MExit ,<br />

.*<br />

.* Begin loop to process summands<br />

.*<br />

.Loop AIf (T'&List(&J) EQ 'P').Decimal<br />

AIf (T'&List(&J) EQ 'F').FullBin<br />

AIf (T'&List(&J) EQ 'H').HalfBin<br />

MNote 4,'** Warning: Invalid summand type - &List(&J) **'<br />

&J SetA &J+1 Increment loop counter<br />

AIf (&J LE N'&List).Loop Continue if more summands<br />

AGo .EndList Else done with list<br />

.*<br />

Add <strong>Macro</strong> Definition:<br />

Process Binary and Decimal<br />

.*<br />

.* Process binary load or add, either halfword or fullword<br />

.*<br />

.HalfBin ANOP ,<br />

&H SetC 'H'<br />

.FullBin ANOP ,<br />

&NM &A&H &R,&List(&J) Increment binary part of sum<br />

&A SetC 'A' Use A after first L<br />

&H SetC '' and set fullword default<br />

AGO .LoopEnd Continue<br />

.*<br />

.* Process decimal zero and add, or add<br />

.*<br />

.Decimal ANOP ,<br />

&NM &DEC &D,&List(&J) Increment decimal part of sum<br />

&DEC SetC 'AP' Use AP after first ZAP<br />

&P SetB 1 We have seen a decimal summand<br />

.*<br />

.LoopEnd ANOP ,<br />

Add <strong>Macro</strong> Definition:<br />

Add Dec Summand, Dec Result<br />

.*<br />

.* Bottom of loop - check if any more summands<br />

.*<br />

&J SetA &J+1 Increment loop counter<br />

&NM SetC '' Clear &NAME holder after first use<br />

AIf (&J LE N'&List).Loop Continue if more summands<br />

.*<br />

.* All summands processed - if any were dec, get binary of their sum<br />

.*<br />

.EndList AIf (NOT &P).NoDSum Skip if no decimal summand<br />

CVB &WKR,&D Get binary sum of decimal summands<br />

&A.R &R,&WKR Add to sum of binary summands<br />

.*<br />

.* If the result is to be decimal, convert result to dec, then save<br />

.*<br />

.NoDSum AIf (T'&Sum EQ 'O').CKD If omitted, don't save result<br />

AIf (T'&Sum NE 'P').NoDRes Skip if no decimal result<br />

CVD &R,&D Get decimal sum of summands<br />

ZAP &Sum,&D Copy to target<br />

AGO .CKD Go generate DWORD<br />

37-40


Add <strong>Macro</strong> Definition:<br />

Store Result, Gen Temp Storage<br />

.*<br />

.* If the result is to be binary, save as halfword or fullword<br />

.*<br />

.NoDRes AIf (T'&Sum EQ 'F').SaveSum<br />

AIf (T'&Sum EQ 'H').HalfSum<br />

MNOTE 4,'** Warning: Invalid sum type - &Sum **'<br />

AGO .CKD Bad type, don't save sum<br />

.HalfSum ANOP ,<br />

&H SetC 'H'<br />

.SaveSum ST&H &R,&Sum Save result<br />

.*<br />

.* If any decimal summands or result, generate scratch doubleword<br />

.*<br />

.CKD AIf (T'&Sum NE 'P' AND NOT &P).MEnd<br />

B &D+8 Branch around doubleword<br />

&D DS D Scratch area<br />

.*<br />

.MEnd MEnd<br />

Add <strong>Macro</strong> Output:<br />

Example 1<br />

This is similar to the code in ADD2, except<br />

that this uses the RX add instead of RR (A<br />

instead of AR)<br />

*<br />

Add (Word1,Word2),Word3<br />

+ L 1,Word1 Increment binary part of sum<br />

+ A 1,Word2 Increment binary part of sum<br />

+ ST 1,Word3 Save result<br />

...<br />

*<br />

Word1 DC F'4'<br />

Word2 DC F'6'<br />

Word3 DS F<br />

*<br />

Add <strong>Macro</strong> Output:<br />

Example 2<br />

AddDemo Add (One,Two,Three,Two,Three,One),Three<br />

+AddDemo L 1,One Increment binary part of sum<br />

+ AH 1,Two Increment binary part of sum<br />

+ ZAP DWrd0009,Three Increment decimal part of sum<br />

+ AH 1,Two Increment binary part of sum<br />

+ AP DWrd0009,Three Increment decimal part of sum<br />

+ A 1,One Increment binary part of sum<br />

+ CVB 0,DWrd0009 Get binary sum of dec summands<br />

+ AR 1,0 Add to sum of binary summands<br />

+ CVD 1,DWrd0009 Get decimal sum of summands<br />

+ ZAP Three,DWrd0009 Copy to target<br />

+ B DWrd0009+8 Branch around doubleword<br />

+DWrd0009 DS D Scratch area<br />

...<br />

*<br />

One DC F'1'<br />

Two DC H'2'<br />

Three DC PL2'3'<br />

Wrap Up<br />

In Which We Learn That Only<br />

a Small Fraction of the <strong>Macro</strong><br />

<strong>Language</strong> Has Been Covered<br />

41-44


Summary<br />

Two hours is just a start, but a good one<br />

For further information, John Ehrman often<br />

gives sessions at SHARE on advanced<br />

macro techniques: '<strong>Assembler</strong> as a Higher<br />

Level <strong>Language</strong>'<br />

Basic Conditional Assembly and <strong>Macro</strong><br />

Concepts<br />

Applied macro techniques<br />

Some of What Wasn't Covered<br />

Set symbols<br />

Subscripted set symbols and extended Set<br />

statements<br />

SetAF and SetCF<br />

Created set symbols<br />

Many data attributes (length, scaling,<br />

integer, etc.)<br />

Many system variable symbols<br />

&SYSLIST in particular<br />

Some of What Wasn't Covered<br />

Controlling macro expansion listing using<br />

PRINT GEN / NOGEN<br />

Defining macros within macros (!)<br />

Using macros to create job streams<br />

(SYSGEN) - important to understand SMP/E<br />

Using conditional assembly in open code<br />

(outside macros)<br />

Nevertheless...<br />

You now have a basic understanding of<br />

S/390 and z/OS assembler macro language<br />

You have seen what comprises a macro<br />

written in assembler language<br />

And you are ready, if you wish, to begin<br />

writing macros (the best way to learn) and<br />

go on to the next step<br />

So, ...<br />

45-48


Congratulations!<br />

49-52

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!