The assembler performs its functions by reading through the assembly language statements sequentially from top to bottom, generating the machine code and a program listing as it proceeds. Since it reads statements sequentially, a special problem occurs in most assemblers which must be overcome. If the assembler encounters the statement
before it encounters the label CLEAR, it is unable to generate machine code for that instruction. This problem is solved by making the assembler perform two "passes" through the assembly language statements.Pass 1 of the assembler does not generate an object module or a listing. Its purpose is to assign values to labels and symbols. The assembler assigns labels by using an internal counter called the location counter. Each program section has a separate location counter, which indicates where the current instruction/data is in relation to the start of the section. Each time the assembler encounters an instruction, the location counter is incremented by the size of the instruction. As the assembler encounters program labels, the labels are assigned the current value of the location counter. As each symbol is encountered, the symbol is saved with its value.
During pass 2, the assembler generates the object module and/or listing, as specified by the invocation line. It uses the table of label/symbols to generate machine code values for instructions. It also uses the location counter to determine the section address that each instruction should occupy. The linker does the final job of assigning where each program section will go and generating the absolute object file.
Although two passes solve the problem previously mentioned, they do not solve it in the optimal fashion. If a microprocessor has two forms of a jump instruction, one that has an 8-bit range and one that has a 16-bit range, it is up to you to choose the appropriate form of the instruction. However, if the program changes, then some short jumps must be made into long ones and vice versa. Also, in many assemblers, instructions that reference data have only one opcode, and in the case of forward references there is no choice but to use the long form of the instruction. This is because when the assembler first sees the operand it does not know its size.
Unlike most assemblers, this one has the ability to perform more than two passes and, therefore, can optimize any instructions that use a forward reference. The PASS control allows you to set the number of passes. In this case, the assembler may go through the standard pass-1 phase many times to determine the final value of each label.
Throughout this manual, two-pass mode refers to the assembler performing two passes. Optimize mode refers to the assembler performing three or more passes. By default, the assembler operates in optimize mode.