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 resetsssDefinedInPass
andsssUsed
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: ; ResetStatus:symDefInPass
and setsymFixed
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