Most assemblers run over the source code twice. Each run is called a "pass," which is why you encounter the .IF1 and .IF2 pseudo operations. .IF1 is a conditional block which is assembled only on the first pass, while .IF2 is for the second pass. On the first pass, the assembler figures out the label addresses, while the REAL assembling is done on the second pass.
Why two passes? Because of the so-called "forward reference." Here is an example of a forward reference:
cmp ax,32
je jo1stuff ;this "forward refrence" refers to jo1stuff which occurs later in the source
mov dx,32
jo1stuff:
ret
So on the first pass, the assembler doesn't know anything about jo1stuff. No matter, it isn't assembling yet! All it does is increment the address counter (I'm not sure if that's the right term - its symbol is $ ). Then, when it sees jo1stuff, it stores the address counter as the label's value with the label name and type. So, on the second pass, the assembler now knows about jo1stuff and can now store the address in the object file.
Note also that during EACH pass, the assembler must also take note of any pseudo operations (most of them start with a . , but some, such as EVEN, ALIGN, PUBLIC, don't). These pseudo operations are instructions to the assembler which the microprocessor won't get to see, since the assembler reacts to them but does not assemble them. They are congruent to C's # operations, such as #include, etc. However, the assembler has to note them EACH pass because of the difference between the .IF1 and .IF2 pseudo-ops.
Sincerely,
AmkG
"Information has a tendency to be free. Which means someone will always tell you something you don't want to know."
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.