ARM600page table generation

# ARM600 page table generation

## About this recipe

This recipe tells you how to use:

- armasm repetitive assembly;
- armasm conditional assembly;
- armasm macros;
- armasm and armlink to produce a plain binary output file (containing only the bytes you describe in your source program).

This recipe refers to the program pagetab.s in the examples directory. Although pagetab.s generates ARM600 page tables, it is not the format of the page tables which is being discussed in this recipe, but how they are generated using armasm. To find out more about ARM600 page tables please refer to the ARM600 datasheet.

## Repetitive assembly

The following code fragment is taken from pagetab.s:

``

               GBLA    counter
    counter    SETA 0

               WHILE   counter <= 3
               L1Entry SECTION, (counter:SHL:20), 0, U_BIT+C_BIT+B_BIT,
    SVC_RW
    counter    SETA counter+1
               WEND

### Explanation

GBLA counter declares a global numeric variable called counter which is initialized to zero using the SETA directive.

The WHILE ... WEND construct is then used to repeatedly assemble the lines between WHILE and WEND.

In this example, the loop body is assembled for counter = 0, 1, 2 and 3, but because the looping condition is checked at the top of the loop, it is possible for code between a WHILE and a WEND never to be assembled. For example, if counter were initialized to 4, the body of the WHILE ... WEND loop would not be assembled at all.

Each time around the loop the macro L1Entry is called (with 5 arguments), and then counter is incremented.

## Macro usage and conditional assembly

The following code fragment for L1Entry is also taken from pagetab.s:

``

    MACRO
    L1Entry $type, $addr, $dom, $ucb, $acc
    IF ($type=SECTION)
        DCD ((($addr):AND:&FFF00000):OR:(($acc):SHL:10) \
            :OR:(($dom):SHL:5):OR:($ucb):OR:($type))
        MEXIT
    ENDIF
    IF ($type=PAGE)
        DCD ((($addr):AND:&FFFFFC00):OR:(($dom):SHL:5) \
            :OR:(($ucb):AND:U_BIT):OR:$type)
    ELSE
        DCD 0 ; Invalid Level 1 Page Table Entry
    ENDIF
    MEND

Note that a backslash breaks a logical line of assembly language across two physical lines. However, there must be no character after the backslash on the line.

### Explanation

The macro definition is enclosed between MACRO and MEND. The first line of the definition gives the macro's name and lists its parameters.

The body of the macro illustrates the use of IF ... ENDIF and IF ... ELSE ... ENDIF to assemble different code conditional on a value known at assembly-time. In this example, the controlling expressions of the IFs involve a macro parameter ($type) which gets its value when the macro is called.

This macro definition also shows how the MEXIT directive can be used to exit from processing a macro before the MEND directive is reached. You can think of MEXIT as being like a return statement in a C function.

## Assembling the page tables in plain binary format

This section tells you how to create a file containing a plain binary image of the page tables. In other words, a file containing just the bytes you would need to load into memory and nothing else by way of symbolic information, file content descriptors, load addresses, etc.

You create a plain binary image in two steps: first you create a relocatable object file from your source file; then you use armlink to make a plain binary version of the relocatable object.

### Method

Set your current directory to that containing the pagetab.s program then assemble pagetab.s and link pagetab.o as follows:

``

    armasm pagetab.s -o pagetab.o -li
    armlink -bin -o pagetab pagetab.o

### Explanation

As in earlier examples, the -li option tells armasm to assemble code for a little-endian memory. This need not be specified if the tools have been configured for little-endian operation.

The -bin option tells armlink to make a plain binary output file containing nothing but the bytes you described in your source program.

Because pagetab contains no position-dependent data, you do not need to tell armlink where to base its output. If there had been position-dependent data or code, you would have had to use the -base address option to tell armlink where to base its output and, of course, you would only be able to use the output at that memory address.

## Related topics

- Loading constants into registers.