Object PASS represents one pass through the assembled program. The PASS structure in allocated on Pgm.Pool in PgmCreateProgram. The object is initialized in PassCreate and destroyed in PassDestroy .
Pass has its own memory pool.
pass PROGRAM FORMAT=COFF,MODEL=FLAT,WIDTH=32 INCLUDEHEAD "euroasm.htm" ; Interface (structures, symbols and macros) of other modules.
pass HEAD ; Start of module interface.
PASS STRUC .Pool D D ; Memory pool for objects with pass-lifetime. .VarList D D ; Ptr to LIST structure which contains VAR objects with %variable name and value. .MacList D D ; Ptr to LIST structure which contains DICT objects with macro name and LinePtr. .ExpansionNr D D ; Initialized to 0 in PassCreate, incremented by CtxExpansionNrUpdate. ENDSTRUC PASS
ENDHEAD pass ; End of module interface. 7
symDefInPass and sets symFixed for all symbols.
sssDefinedInPass and sssUsed for all sections, segments, structures.
PassCreate Procedure PgmPtr
MOV ECX,[%PgmPtr]
JNSt [ECX+PGM.Status],pgmLastPass,.05:
Invoke PgmEvalEntry::, ECX
.05: MOV EAX,'0310' ; Assembling source pass !1D. EAX=0x30313330
JSt [ECX+PGM.Status],pgmEnvelope,.10:
MOV EAX,'0510' ; Assembling pass !1D. EAX=0x30313530
.10: JNSt [ECX+PGM.Status],pgmFixingPass,.20:
ADD EAX,0x00010000 ; EAX='0320' or '0520'.
.20: JNSt [ECX+PGM.Status],pgmLastPass,.30:
ADD EAX,0x00020000 ; EAX='0330' or '0530'.
.30: Msg EAX,[ECX+PGM.PassNr] ; Assembling pass !1D. ; Report information about the start of pass..
MOV EBX,[ECX+PGM.PassPtr]
LEA ESI,[ECX+PGM.Eaopt]
MOV EAX,Ea.Eaopt::
CopyTo EAX,ESI,Size=SIZE#EAOPT
PoolCreate Size=%EaPoolSize, ErrorHandler=EaMallocError::
MOV [EBX+PASS.Pool],EAX ; Create the pass memory pool.
MOV EDX,EAX
SUB EAX,EAX
MOV [EBX+PASS.ExpansionNr],EAX ; Reset expansion number.
ListCreate EDX, SIZE#VAR
MOV [EBX+PASS.VarList],EAX
ListCreate EDX, SIZE#MAC
MOV [EBX+PASS.MacList],EAX
; Enumerate SSS objects and reset sssDefinedInPass and sssUsed in sections and segments.
MOV EAX,[ECX+PGM.SssList]
TEST EAX
JZ .50:
ListGetFirst EAX
JZ .50:
.40: RstSt [EAX+SSS.Status],sssDefinedInPass
JSt [EAX+SSS.Status],sssGroup,.45:
JSt [EAX+SSS.Status],sssStructure,.45:
RstSt [EAX+SSS.Status],sssUsed
BufferClear [EAX+SSS.EmitBuffer]
.45: ListGetNext EAX
JNZ .40:
.50: ; Reset Status:symDefInPass and set symFixed in all symbols.
SUB EDX,EDX
MOV EAX,[ECX+PGM.SymList]
TEST EAX
JZ .80:
ListGetFirst EAX
JZ .80:
.60: RstSt [EAX+SYM.Status],symDefInPass
SetSt [EAX+SYM.Status],symFixed
ListGetNext EAX
JNZ .60:
.80: Invoke SssGetSegm::,ECX,sssPurposeCODE ; Find the first code segment to EAX.
MOV EDX,pgmoptFormatMask
AND EDX,[ECX+PGM.Pgmopt.Status]
CMP DL,pgmoptCOM
JNE .85: ; Skip it program format is not COM.
Invoke SssEmit::,EAX,0,0,256 ; Emit 256 stuff bytes to the first CODE segment (PSP pseudosection).
.85: MOV [ECX+PGM.CurrentSect],EAX ; ; Start the pass at the first code section..
.90:EndProcedure PassCreate
PassDestroy Procedure PgmPtr
PspSect LocalVar Size=SIZE#SSS
BaseSect LocalVar Size=SIZE#SSS
MOV EBX,[%PgmPtr]
TEST EBX
JZ .90:
; Check if the [Src.EaoptStack] is balanced.
StackPop [Src.EaoptStack::]
Msg cc=NC,'3811' ; Unbalanced option stack. EUROASM POP missing.
; Remove unused implicit segments.
.10:ListGetFirst [EBX+PGM.SssList]
JZ .40:
.15:RstSt [EAX+SSS.Status],sssExtAttr ; Remove possible pending attribute requests.
JNSt [EAX+SSS.Status],sssSegment,.20:
JNSt [EAX+SSS.Status],sssImplicit,.20:
Invoke SssCheckDirty::,EAX,EBX
JC .20: ; If dirty (something was emitted to it}.
ListRemove [EBX+PGM.SssList],EAX ; Remove unused implicit segment.
JMP .10: ; Start from the 1st object again, because the list was modified.
.20:ListGetNext EAX
JNZ .15:
.25:; Remove unused implicit groups.
ListGetFirst [EBX+PGM.SssList]
JZ .40:
.30:JNSt [EAX+SSS.Status],sssGroup,.35:
JNSt [EAX+SSS.Status],sssImplicit,.35:
Invoke SssCheckDirty::,EAX,EBX
JC .35: ; If dirty (something was emitted to it}.
ListRemove [EBX+PGM.SssList],EAX ; Remove unused implicit group.
JMP .25: ; Start from the 1st object again, because the list was modified.
.35:ListGetNext EAX
JNZ .30:
.40:; Update scope of global symbols.
ListGetFirst [EBX+PGM.SymList]
JZ .60:
.45:JNSt [EAX+SYM.Status],symGlobal|symGlobalRef, .55:
JSt [EAX+SYM.Status],symDefInPass,.50:
; Global symbol was not defined in pass, it will be external or imported or forwarded.
.48:SetSt [EAX+SYM.Status],symExtern
RstSt [EAX+SYM.Status],symEstimated
MOVD [EAX+SYM.OffsetLow],0
Invoke SssCreateExtern::,EAX,EBX
JMPS .55:
.50:; Global symbol was defined, it will be published.
SetSt [EAX+SYM.Status],symPublic
.55:ListGetNext EAX ; The next symbol.
JNZ .45:
.60: ; Clear the PASS object.
MOV ESI,[EBX+PGM.PassPtr] ; The pass which ends right now.
.70:PoolDestroy [ESI+PASS.Pool]
Msg cc=C,'2575','Pass',EDX ; Deallocation of virtual memory !1C.Pool !2Hh failed.
.80:Clear ESI,Size=SIZE#PASS ; Erase object PASS including its lists.
.90:EndProcedure PassDestroy
PassInspect Procedure PgmPtr
MOV EDI,[%PgmPtr]
JSt [EDI+PGM.Status],pgmLastPass,.90: ; Final pass has just ended, CF=0, no more passes needed.
JNSt [EDI+PGM.Status],pgmFixingPass, .20:
RstSt [EDI+PGM.Status],pgmFixingPass ; Last but one pass has just ended. Prepare for the final pass.
.10: SetSt [EDI+PGM.Status],pgmLastPass+pgmLastJustSet
JMPS .80:
.20: ; An ordinary pass is ending. If all symbols are fixed, set pgmLastPass.
ListGetFirst [EDI+PGM.SymList]
JZ .10:
.30: JNSt [EAX+SYM.Status],symFixed,.70: ; If any symbol is unfixed, more passes are needed.
.40: ListGetNext EAX
JNZ .30:
JMP .10: ; All symbols are fixed. Prepare for the final pass.
.70: ; Some symbol are still unfixed. Next pass is necessary.
MOV ESI,[EDI+PGM.PassNr]
LEA EAX,[EDI+PGM.Pgmopt]
ADD ESI,2
CMP ESI,[EAX+PGMOPT.MaxPasses] ; Has the pass number approached to its limit?
JB .80
SetSt [EDI+PGM.Status],pgmFixingPass ; MaxPasses approached, so this pass must be fixing.
.80: INCD [EDI+PGM.PassNr]
STC ; At least one more pass is necessary.
.90:EndProcedure PassInspect
ENDPROGRAM pass