E.3 Conditional Assembly

Many programming environments, including some high-level languages, provide for conditional assembly or conditional compilation based upon situation-dependent parameters. The motivations for this capability, and some of the situations where it is useful, have historically included the following:

  • bracketing segments of a program initially written as aids during development and debugging, which may contain useful internal documentation in the comments but which are not needed in the production version;

  • producing simplified versions of a product (e.g., a demo version);

  • accommodating the presence or absence of particular hardware features; and

  • tailoring a general library macro to produce appropriate code for a specific situation.

Deriving such alternative versions of software from a common source file contributes to consistency, long-term maintainability, and perhaps even provability of correctness when meticulously done.

A conditional assembly block is bounded by the .if assembler directive at the top, the .endif assembler directive at the bottom, and an optional .else directive at some intermediate position:

 .if argument < first range of statements > .else < second range of statements > .endif 

where the argument must be an "absolute expression," i.e., a constant or an expression, such as the difference symbA-symbB, computable using the location counter for a single section, but not a difference involving different sections or any sum of symbolic addresses.

The first included range of lines is considered by the assembler if the argument is nonzero but entirely skipped over if the argument is zero. Conversely, the second included range of lines is considered by the assembler only if the argument is zero.

Each range of lines either will be completely considered for assembly (and for interpretation of any nested conditionals or macros) or else will be entirely omitted from consideration. When a conditional range is not considered, any new symbols introduced within that range will not become defined.

Other forms of .if are also provided: .ifdef symbol assembles the following section of code if the specified symbol has already been defined at some earlier line but does not itself define that symbol; and .ifndef symbol or .ifnotdef symbol assembles the following section of code if the specified symbol has not already been defined at some earlier line but does not itself define that symbol.

Conditional blocks may be nested. If an outer condition is not satisfied, the inner conditionals will not be considered for assembly. The .if and .endif directives must be strictly matched. Consider the following example:

 .ifdef    SYMBOL1 ... < Outer range (A) > ... .ifdef    SYMBOL2 ... < Inner range (B) > ... .endif ... < Outer range (C) > ... .endif 

The following chart summarizes which of the three ranges will be assembled, depending on whether SYMBOL1 and/or SYMBOL2 has been previously defined:

SYMBOL1

SYMBOL2

What is assembled

Undefined

Undefined

nothing

Defined

Undefined

ranges (A), (C)

Undefined

Defined

nothing

Defined

Defined

ranges (A), (B), (C)

Notice that there is no circumstance in which range (B) would be assembled but ranges (A) and (C) would not be assembled.



ItaniumR Architecture for Programmers. Understanding 64-Bit Processors and EPIC Principles
ItaniumR Architecture for Programmers. Understanding 64-Bit Processors and EPIC Principles
ISBN: N/A
EAN: N/A
Year: 2003
Pages: 223

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net