tirsdag den 8. september 2015

How the assembler works (3)

I will now start a series of articles about macro language. What is a macro? It is an interpretal programming language understood by the assembler and meant to generate real symbolic instructions. You can use macroes to generate instructions that must be in every program, usually start and end of a program. Another typical way to use macroes is to make a table with entries that can be loaded by a program and used as parameters.

The smallest macro you can make is the this one

MACRO
NAME
MEND
  1. The first entry tells the assembler that this is a Macro. 
  2. Next line is its name. 
  3. The last line tells the assembler that it is the end of the macro. 

Between the name and MEND come a number of instructions and the NAME-line takes some variables to the macro. Think macro language as a separate programming language and the macro as a program.

Table example

Let us start with a table of names. It is just for fun and should give you the feel of how to use macroes.

TABLE1   TABLE START
         TABLE ENTRY,PROGRAMMER=YES
         TABLE ENTRY,PROGRAMMER=YES,CNAME=SONJA
         TABLE ENTRY,CNAME=CARL,SURNAME=NIESLEN
         TABLE ENTRY,CNAME=EDWARD,SURNAME=GRIEG,PROGRAMMER=NEVER
         TABLE END
The table contains four entries with a START and an END. Each table entry contains the christian name, surname of a person, and an indication whether he or she is a programmer or not. Probably a silly table but good as an example.

START

The first two lines are as the minimum macro above
          MACRO
&LABEL   TABLE &STATE,&CNAME=JENS,&SURNAME=ELBAEK,&PROGRAMMER=
  1. We start every macro with MACRO
  2. All names prefixed with "&" are variables and those after the name are parameters to the macro some with a default value. &LABEL is also a variable but it takes no default value. &STATE has no equal sign because it is a positional parameter, the rest are in the keyword=value form 


Later on we need to count the number of entries, so we will define a global variable called &COUNT which we can access in all six invocations of the TABLE-macro. That is opposed to a local variable that will be reinitiated during each invocation.
          GBLA  &COUNT

Testing STATE

The &STATE parameter takes three values as you might have noticed in the table example:
  • START
  • ENTRY
  • END
We check that and go to the appropriate section in the macro by:

          AIF   ('&STATE' EQ 'START').START
          AIF   ('&STATE' EQ 'ENTRY').ENTRY
          AIF   ('&STATE' EQ 'END').END
          MNOTE 8,'THERE MUST BE A STATE
          MEXIT
All macro instructions start with an "A" so these are IF-statements. The test is surrounded by brackets. If the variable contains alphanummeric value you must enclose the variable with quote. If the statement is true the assembler will proceed at the label prefixed by a dot. If none of the IF's are true there will be written a message and the assembler will stop with condition code 8.

.START

.START    ANOP
&LABEL    CSECT
&LABEL    RMODE ANY
          DC    CL32'&LABEL - &SYSDATE..&SYSTIME'
&COUNT    SETA  1
          ENTRY ENTRY&COUNT
          AGO   .END_OF_MACRO
  1. The .START-label is a No OPeration, again prefixed with "A". 
  2. Every assembler program must have a CSECT and our gets the name in the &LABEL (TABLE1). 
  3. We wish to be able to load it in 31-bit address storage. 
  4. Then we create a constant in the program/table that tells the name and data and time when assembled. 
  5. We set the global counter to one by the SETA-instruction which is used for nummeric SET. SETC is used for alphanummeric SET of variables. 
  6. We set the entrypoint at the first entry 
  7. and finally go to end of the macro. We could have used MEXIT as above but I prefer this way.
That was the start of the table and we are now ready to create each entry in the table

.ENTRY 

.ENTRY    ANOP
ENTRY&COUNT DS  0F
&COUNT    SETA  &COUNT+1
          DC    A(ENTRY&COUNT)
          DC    CL8'&CNAME'
          DC    CL8'&SURNAME'
          AIF   ('&PROGRAMMER' EQ 'YES').PROGRAMMER
          DC    C'0'
          AGO   .END_OF_MACRO
.PROGRAMMER ANOP
          DC    C'1'
          AGO   .END_OF_MACRO

  1. ENTRY starts with its assembler label (prefixed with dot)
  2. We create a lable suffixed with counter value
  3. and adds 1 to the counter
  4. We need an address to the next entry so we makes a address constant
  5. Then a constant with the first name
  6. and one with the surname
  7. We test whether the parameter &PROGRAMMER is "YES". 
  8. If not we define a constant with "0"
  9. and goes to the end
  10. otherwise we go to the lable .PROGRAMMER and 
  11. make a constant with the value 1 that indicates the person is a programmer
  12. and go to end.
We have produced one entry.
ENTRY1  DS    0F
        DC    A(ENTRY2)

        DC    CL8'JENS'
        DC    CL8'ELBAEK'
        DC    C'1'

There will come three additional entries. All entries will be linked together with the address in A(ENTRY&COUNT). Some call it a linked list.

.END

.END      ANOP
ENTRY&COUNT DC  A(-1)
          END


  1. The .END label
  2. The last addess constant will contain X'FFFFFFFF' in order tel the program that the table has ended
  3. The assemler instruction "END" that ends the assembler when it translates the symbolic machine instructions, - NOT the macro intrepretations.

.END_OF_MACRO

.END_OF_MACRO ANOP
              MEND
  1. The label at the end of the macro
  2. and the actual end. That will be the last statement in every macro

TABLE Macro

This is the full macro:

          MACRO
&LABEL    TABLE &STATE,&CNAME=JENS,&SURNAME=ELBAEK,&PROGRAMMER=
          GBLA  &COUNT
          AIF   ('&STATE' EQ 'START').START
          AIF   ('&STATE' EQ 'ENTRY').ENTRY
          AIF   ('&STATE' EQ 'END').END
          MNOTE 8,'THERE MUST BE A STATE'
          MEXIT
.START    ANOP
&LABEL    CSECT
&LABEL    RMODE ANY
          DC    CL32'&LABEL - &SYSDATE..&SYSTIME'
&COUNT    SETA  1
          ENTRY ENTRY&COUNT
          AGO   .END_OF_MACRO
.ENTRY    ANOP
ENTRY&COUNT DS  0F
&COUNT    SETA  &COUNT+1
          DC    A(ENTRY&COUNT)
          DC    CL8'&CNAME'
          DC    CL8'&SURNAME'
          AIF   ('&PROGRAMMER' EQ 'YES').PROGRAMMER
          DC    C'0'
          AGO   .END_OF_MACRO
.PROGRAMMER ANOP
          DC    C'1'
          AGO   .END_OF_MACRO
.END      ANOP
ENTRY&COUNT DC  A(-1)
          END
.END_OF_MACRO ANOP
          MEND


   Loc  Object Code    Addr1 Addr2  Stmt   Source Statement                      
                                      1 TABLE1   TABLE START
000000                00000 00084     2+TABLE1    CSECT
                                      3+TABLE1    RMODE ANY
000000 E3C1C2D3C5F14060               4+          DC    CL32'TABLE1 - 09/08/15.15.05'
                                      5+          ENTRY ENTRY1
                                      6           TABLE ENTRY,PROGRAMMER=YES
000020                                7+ENTRY1      DS  0F
000020 00000038                       8+          DC    A(ENTRY2)
000024 D1C5D5E240404040               9+          DC    CL8'JENS'
00002C C5D3C2C1C5D24040              10+          DC    CL8'ELBAEK'
000034 F1                            11+          DC    C'1'
                                     12          TABLE ENTRY,
                                                PROGRAMMER=YES,CNAME=SONJA
000038                               13+ENTRY2      DS  0F
000038 00000050                      14+          DC    A(ENTRY3)
00003C E2D6D5D1C1404040              15+          DC    CL8'SONJA'
000044 C5D3C2C1C5D24040              16+          DC    CL8'ELBAEK'
00004C F1                            17+          DC    C'1'
                                     18          TABLE ENTRY,CNAME=CARL,SURNAME=NIESLEN
000050                               19+ENTRY3      DS  0F
000050 00000068                      20+          DC    A(ENTRY4)
000054 C3C1D9D340404040              21+          DC    CL8'CARL'
00005C D5C9C5E2D3C5D540              22+          DC    CL8'NIESLEN'
000064 F0                            23+          DC    C'0'
                                     24          TABLE ENTRY,
                                      CNAME=EDWARD,SURNAME=GRIEG,PROGRAMMER=NEVER
000068                               25+ENTRY4      DS  0F
000068 00000080                      26+          DC    A(ENTRY5)
00006C C5C4E6C1D9C44040              27+          DC    CL8'EDWARD'
000074 C7D9C9C5C7404040              28+          DC    CL8'GRIEG'
00007C F0                            29+          DC    C'0'
                                     30          TABLE END
00007D 000000
000080 FFFFFFFF                      31+ENTRY5      DC  A(-1)
                                     32+          END



Take a look at the assembler list. Where has each entry got its values from and why?
By the way, why are there three X'00' at location counter
00007D. There are three others hidden. Find them.

Next time we will make a more complicated MACRO.



Ingen kommentarer:

Send en kommentar