1.3 How the assembler works

The ARM® assembler reads the assembly language source code twice before it outputs object code. Each read of the source code is called a pass.

This is because assembly language source code often contains forward references. A forward reference occurs when a label is used as an operand, for example as a branch target, earlier in the code than the definition of the label. The assembler cannot know the address of the forward reference label until it reads the definition of the label.
During each pass, the assembler performs different functions. In the first pass, the assembler:
  • Checks the syntax of the instruction or directive. It faults if there is an error in the syntax, for example if a label is specified on a directive that does not accept one.
  • Determines the size of the instruction and data being assembled and reserves space.
  • Determines offsets of labels within sections.
  • Creates a symbol table containing label definitions and their memory addresses.
In the second pass, the assembler:
  • Faults if an undefined reference is specified in an instruction operand or directive.
  • Encodes the instructions using the label offsets from pass 1, where applicable.
  • Generates relocations.
  • Generates debug information if requested.
  • Outputs the object file.
Memory addresses of labels are determined and finalized in the first pass. Therefore, the assembly code must not change during the second pass. All instructions must be seen in both passes. Therefore you must not define a symbol after a :DEF: test for the symbol. The assembler faults if it sees code in pass 2 that was not seen in pass 1.

Line not seen in pass 1

The following example shows that num EQU 42 is not seen in pass 1 but is seen in pass 2:
    AREA x,CODE 
    [ :DEF: foo 
num EQU 42 
foo DCD num 
Assembling this code generates the error:
A1903E: Line not seen in first pass; cannot be assembled.

Line not seen in pass 2

The following example shows that MOV r1,r2 is seen in pass 1 but not in pass 2:
    AREA x,CODE 
    [ :LNOT: :DEF: foo 
    MOV r1, r2 
foo MOV r3, r4
Assembling this code generates the error:
A1909E: Line not seen in second pass; cannot be assembled.
Related concepts
6.13 Two pass assembler diagnostics
4.24 Instruction and directive relocations
Related reference
1.4 Directives that can be omitted in pass 2 of the assembler
9.18 --diag_error=tag[,tag,…]
9.15 --debug
Non-ConfidentialPDF file icon PDF versionARM DUI0379G
Copyright © 2007, 2008, 2011, 2012, 2014, 2015 ARM. All rights reserved.