Peter Relson writes:
> An entertaining thought for an assembler enhancement would be
> a pseudo-op that generated "LA" or "LARL" depending on whether
> the target was in a CSECT or a DSECT (maybe allowing for LAY
> too).

We've often had suggestions for instructions that generate
alternative expansions depending on value or attributes of the
operands.  Even if additional attributes were made visible to
macros, this would be conceptually possible only in the same
cases that it would be possible to code a macro instruction to
perform that function.

If the operands are defined in advance or are in open code which
can be seen by lookahead, there are cases where something like
this is possible.  For example, one could select an appropriate
immediate instruction depending on the value range of a equated
symbolic operand.

However, if the information is not yet defined or there is some
aspect which has not yet been resolved (such as a branch offset)
it is only possible to make some sort of default assumption.  If
there is some solution that will always work, that may be
acceptable, for example making the "worst case" assumption that
an unknown immediate value may require up to 4 bytes.

It may be helpful to remember how the assembler works.  Most of
the processing occurs during the first pass, including macro
processing, and macros have access to most of the information
already known to the assembler, plus some lookahead capability
within open code.

During the first pass, code and data fragments are assembled as
far as possible, but a section may initially be assembled as
many fragments because of unresolved lengths, duplication
factors, alignment padding and similar.  Each unresolved item
is added to a list during the first pass.  Sometimes a further
reference to the same item (for example the definition of an
undefined symbol) will cause it to be resolved later in the
first pass, otherwise it is deferred to the end of the pass.

After the first pass, there is an "interlude" step where the
assembler scans the lists of unresolved items trying to resolve
them.  All fragments of each section are concatenated together
and all unresolved expressions are retried until they are either
resolved or determined to be unresolvable.

The assembler then performs the second pass, which writes out
the object file containing ESD, TXT, RLD and END information,
creating the listing as it goes.

The only way to effectively defer a code generation decision
during the first pass is to create an assembler expression which
will select between different values according to the value of
an expression.  The highly non-mathematical assembler feature
that anything divided by zero is zero is particularly useful in
this context.  For example, an expression of the form
(label-*)/(label-*) normally has a value of 1 but has a value of
zero if the label is on the next instruction, so it can be used
in various contexts to optimize generated branches within
structured programming macros (as I learned from John Hartmann,
author of CMS Pipelines).

Jonathan Scott, HLASM
IBM Hursley, UK

Reply via email to