[ Previous | Next | Contents | Home | Search ]
AIX Version 4.3 Assembler Language Reference

.using Pseudo-op

Purpose

Allows the user to specify a base address and assign a base register number.

Syntax

.using Expression,Register

Description

The .using pseudo-op specifies an expression as a base address, and assigns a base register, assuming that the Register parameter contains the program address of Expression at run time. Symbol names do not have to be previously defined.

Note: The .using pseudo-op does not load the base register; the programmer should ensure that the base address is loaded into the base register before using the implicit address reference.

The .using pseudo-op only affects instructions with an implicit-based address. It can be issued on the control section (csect) name and all labels in the csects. It can also be used on the dsect name and all the labels in the dsects. Other types of external symbols are not allowed (.extern).

Using Range

The range of a .using pseudo-op (using range) is -32768 or 32767 bytes, beginning at the base address specified in the .using pseudo-op. The assembler converts each implicit address reference (or expression), which lies within the using range, to an explicit-based address form. Errors are reported for references outside the using range.

Two using ranges overlap when the base address of one .using pseudo-op lies within the ranges of another .using pseudo-op. When using range overlap happens, the assembler converts the implicit address reference by choosing the smallest signed offset from the base address as the displacement. The corresponding base register is used in the explicit address form. This applies only to implicit addresses that appear after the second .using pseudo-op.

In the next example, the using range of base2 and data[PR] overlap. The second l instruction is after the second .using pseudo-op. Because the offset from data[PR] to d12 is greater than the offset from base2 to d12 , base2 is still chosen.

        .csect  data[PR]
        .long   0x1
dl:     .long   0x2
base2:  .long   0x3
        .long   0x4
        .long   0x4
        .long   0x5
d12:    .long   0x6
        l 12, data_block.T(2)   # Load addr. of data[PR] into r12
        ca1 14, base2(12)       # Load addr. of base2 into r14
        .using base2, 14
        l 4, d12                # Convert to 1 4, 0xc(14)
        .using data[PR], 12
        l 4, d12                # Converts to 1 4, 0xc(14)
                                # because base2 is still chosen
        .toc
data_block.T:   tc data_block[tc], data[PR]

There is an internal using table that is used by the assembler to track the .using pseudo-op. Each entry of the using table points to the csect that contains the expression or label specified by the Expression parameter of the .using pseudo-op. The using table is only updated by the .using pseudo-ops. The location of the .using pseudo-ops in the source program influences the result of the conversion of an implicit-based address. The next two examples illustrate this conversion.

Example 1:

            .using   label1,4
            .using   label2,5
            .csect   data[RW]
label1:     .long    label1
            .long    label2
            .long    8
label1_a:   .long    16
            .long    20
label2:     .long    label2
            .long    28
            .long    32
label2_a:   .long    36
            .long    40
            .csect   sub1[pr]
            1        6,label1_a      # base address label2 is
                                     # chosen, so convert to:
                                     # 1 6, -8(5)
            1        6,label2_a      # base address label2 is
                                     # chosen, so convert to:
                                     # 1 6, 0xc(5)

Example 2:

            .csect  data[RW]
label1:     .long   label1
            .long   label2
            .long   12
label1_a:   .long   16
            .long   20
label2:     .long   label2
            .long   28
            .csect  sub2[pr]
            .using  label1,4
            1       6,label1_a       # base address label1 is
                                     # chosen, so convert to:
                                     # 1 6, 0xc(4)
           .using   label2,5
            1       6,label1_a       # base address label2 is
                                     # chosen, so convert to:
                                     # 1 6, -8(5)

Two using ranges coincide when the same base address is specified in two different .using pseudo-ops, while the base register used is different. The assembler uses the lower numbered register as the base register when converting to explicit-based address form, because the using table is searched from the lowest numbered register to the highest numbered register. The next example shows this case:

        .csect  data[PR]
        .long   0x1
dl:     .long   0x2
base2;  .long   0x3
        .long   0x4
        .long   0x5
dl2:    .long   0x6
        1 12, data_block.T(2)   # Load addr. of data[PR] into r12
        1 14, data_block.T(2)   # Load addr. of data[PR] into r14
        .using data[PR], 12
        1 4, dl2                # Convert to: 1 4, 0x14(12)
        .using data[PR], 14
        1 4, dl2                # Convert to: 1 4, 0x14(12)
        .toc
data_block.T:   .tc data_block[tc], data[PR]

Using Domain

The domain of a .using pseudo-op (the using domain) begins where the .using pseudo-op appears in a csect and continue to the end of the source module except when:

These two exceptions provide a way to use a new base address. The next two examples illustrate these exceptions:

Example 1:

        .csect  data[PR]
        .long   0x1
dl:     .long   0x2
base2;  .long   0x3
        .long   0x4
        .long   0x5
dl2:    .long   0x6
        1 12, data_block.T(2)   # Load addr. of data[PR] into r12
        ca1 14, base2(12)       # Load addr. of base2 into r14
        .using base2, 14
        1 4, dl2                # Convert to: 1 4, 0xc(14)
                                # base address base2 is used
        1 14, data_block.T(2)   # Load addr. of data[PR] into r14
        .using data[PR], 14
        1 4, dl2                # Convert to: 1 4, 0x14(14)
        .toc
data_block.T:   .tc data_block[tc], data[PR]

Example 2:

        .csect  data[PR]
        .long   0x1
dl:     .long   0x2
base2;  .long   0x3
        .long   0x4
        .long   0x5
dl2:    .long   0x6
        1 12, data_block.T(2)   # Load addr. of data[PR] into r12
        ca1 14, base2(12)       # Load addr. of base2 into r14
        .using base2, 14
        1 4, dl2                # Convert to: 1 4, 0xc(14)
        .drop 14
        .using data[PR], 12
        1 4, dl2                # Convert to: 1 4, 0x14(12)
        .toc
data_block.T:    .tc data_block[tc], data[PR]
Note: The assembler does not convert the implicit address references that are outside the Using Domain. So, if these implicit address references appear before any .using pseudo-op that defines a base address of the current csect, or after the .drop pseudo-ops drop all the base addresses of the current csect, an error is reported.

The next example shows the error conditions:

        .csect  data[PR]
        .long   0x1
dl:     .long   0x2
base2;  .long   0x3
        .long   0x4
        .long   0x5
dl2:    .long   0x6
        1 4, dl2                # Error is reported here
        1 12, data_block.T(2)   # Load addr. of data[PR] into r12
        1 14, data_block.T(2)   # Load addr. of data[PR] into r14
        .using data[PR], 12
        1 4, dl2
        1 4, 0x14(12)
        .drop 12
        1 4, dl2                # Error is reported here
        .using data[PR], 14
        1 4, dl2
        1 4, 0x14(14)
        .toc
data_block.T:   .tc data_block[tc], data[PR]
        .csect  data1[PR]
dl3:    .long   0x7
        .using  data[PR], 5
        1 5, dl3                # Error is reported
                                # here, dl3 is in csect
                                # data1[PR] and
                                # Using table has no entry of
                                # csect data1[PR] 
        l 5, dl2                # No error, because dl2 is in
                                # data [PR]

Parameters

Register Represents the register number for expressions. It must be absolute and must evaluate to an integer from 0 to 31 inclusive.
Expression Specifies a label or an expression involving a label that represents the displacement or relative offset into the program. The Expression parameter can be an external symbol if the symbol is a csect or Table of Contents (TOC) entry defined within the assembly.

Examples

The following example demonstrates the use of the .using pseudo-op:

.csect data[rw]
.long 0x0, 0x0
d1:     .long 0x25
# A read/write csect contains the label d1.
.csect text[pr]
.using data[rw], 12
l 4,d1
# This will actually load the contents of
# the effective address, calculated by
# adding the address d1 to the address in
# GPR 12, into GPR 4

Related Information

Pseudo-ops Overview.

The .csect pseudo-op, .drop pseudo-op.


[ Previous | Next | Contents | Home | Search ]