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:
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:
Notice that there is no circumstance in which range (B) would be assembled but ranges (A) and (C) would not be assembled. |