Object PASS represents one pass through the assembled program. The PASS structure is allocated on Pgm.Pool in PgmCreateProgram. The object is initialized in PassCreate and destroyed in PassDestroy .
Pass has its own memory pool.
EUROASM NOWARN=2101
pass PROGRAM FORMAT=COFF,MODEL=FLAT,WIDTH=32
INCLUDEHEAD euroasm.htm, \ Interface (structures, symbols and macros) of other modules used in this source.
ea.htm,eaopt.htm,exp.htm,mac.htm,msg.htm,pgm.htm,pgmopt.htm,sss.htm,sym.htm,var.htm
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 the name and value of %variables. .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 (except for [PSP]).
PassCreate Procedure PgmPtr
MOV ECX,[%PgmPtr]
MOV EAX,'0310' ; I0310 Assembling source pass !1D. EAX=0x30313330
JSt [ECX+PGM.Status],pgmEnvelope,.10:
MOV EAX,'0510' ; I0510 Assembling program pass !1D. EAX=0x30313530
.10: JNSt [ECX+PGM.Status],pgmFixingPass,.20:
ADD EAX,0x00010000 ; Change MsgId to I0320 or I0520.
.20: JNSt [ECX+PGM.Status],pgmLastPass,.30:
ADD EAX,0x00020000 ; Change MsgId to I0330 or I0530.
.30: Msg EAX,[ECX+PGM.PassNr] ; Report information about the start of pass..
RstSt [ECX+PGM.Status],pgmPassInit
MOV EBX,[ECX+PGM.PassPtr]
LEA ESI,[ECX+PGM.Eaopt]
MOV EAX,Ea.Eaopt::
CopyTo EAX,ESI,Size=SIZE#EAOPT ; Reinitialize EUROASM options from snapshot taken at the beginning of program.
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
MOV EAX,[ECX+PGM.SssList] ; Enumerate SSS objects and reset sssDefinedInPass
TEST EAX ; and sssUsed in sections and segments.
JZ .50:
ListGetFirst EAX
JZ .50:
.40: RstSt [EAX+SSS.Status],sssDefinedInPass
JSt [EAX+SSS.Status],sssGroup|sssStructure|sssImagePrefix,.45:
RstSt [EAX+SSS.Status],sssUsed
BufferClear [EAX+SSS.EmitBuffer]
JNSt [EAX+SSS.Purpose],sssPurposeCODE,.45:
JSt [ECX+PGM.Status],pgmPassInit,.45:
SetSt [ECX+PGM.Status],pgmPassInit
.45: ListGetNext EAX
JNZ .40: ; The next segment or section.
.50: MOV EAX,[ECX+PGM.SymList]
TEST EAX
JZ .80:
ListGetFirst EAX ; Reset Status:symDefInPass
JZ .80: ; and set symFixed for all symbols.
.60: RstSt [EAX+SYM.Status],symDefInPass
SetSt [EAX+SYM.Status],symFixed
ListGetNext EAX
JNZ .60: ; The next symbol.
.80: MOVD [ECX+PGM.CurrentSect],0 ; Reset the current section at the start of each pass.
.90:EndProcedure PassCreate
PassDestroy Procedure PgmPtr
BaseSect LocalVar Size=SIZE#SSS
MOV EBX,[%PgmPtr]
StackPop [Src.EaoptStack::] ; Check if the [Src.EaoptStack] is balanced inside PROGRAM..ENDPROGRAM.
Msg cc=NC,'3811' ; Unbalanced option stack. EUROASM POP missing.
JNSt [EBX+PGM.Status],pgmLastPass,.25: ; Remove unused implicit segments and their symSe in the final pass.
.10:ListGetFirst [EBX+PGM.SssList]
JZ .40:
.15:MOV ECX,[EAX+SSS.Status]
JNSt ECX,sssSegment|sssGroup,.20:
JNSt ECX,sssImplicit,.20:
Invoke SssCheckDirty::,EAX,EBX
JC .20: ; Skip when segment|group EAX is dirty (something was emitted to it)
MOV EDX,[EAX+SSS.SymPtr] ; or when its associated symbol was used.
JSt [EDX+SYM.Status],symUsed,.20:
ListRemove [EBX+PGM.SymList],[EAX+SSS.SymPtr]; Remove segment's associated symSe.
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 ; The next segment.
JNZ .15:
.25:XOR EDX,EDX ; Reset origin of each section to the bottom, i. e. to the offset 0 at asm-time.
ListGetFirst [EBX+PGM.SssList]
.30:JNSt [EAX+SSS.Status],sssSection,.35:
MOV [EAX+SSS.OrgLow],EDX
MOV [EAX+SSS.OrgHigh],EDX
.35:ListGetNext EAX
JNZ .30:
.40:ListGetFirst [EBX+PGM.SymList] ; Update scope of global symbols.
JZ .60:
.45:JNSt [EAX+SYM.Status],symGlobal|symGlobalRef, .55:
JSt [EAX+SYM.Status],symDefInPass,.50: ; If the symbol EAX was defined, its scope will be symPublic.
SetSt [EAX+SYM.Status],symExtern ; Global symbol was not defined in pass, it will be external or imported or forwarded.
RstSt [EAX+SYM.Status],symEstimated
MOV [EAX+SYM.OffsetLow],EDX
Invoke SssCreateExtern::,EAX,EBX ; Create external pseudosegment if it didn't exist yet.
JMPS .55:
.50:SetSt [EAX+SYM.Status],symPublic ; Global symbol was defined, it will be published.
.55:ListGetNext EAX ; The next symbol.
JNZ .45:
.60:MOV ESI,[EBX+PGM.PassPtr] ; Clear the PASS object.
.70:PoolDestroy [ESI+PASS.Pool] ; The pass which ends right now. PASS.VarList and PASS.MacList are deallocated.
MOV [%ReturnEAX],EAX
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
Pgm.PassNr and set flag Pgm.Status:pgmLastPass or :pgmFixingPass.
PassInspect Procedure PgmPtr
MOV EBX,[%PgmPtr]
JSt [EBX+PGM.Status],pgmLastPass, .90: ; If the final pass has just ended, return CF=0, no more passes needed.
JNSt [EBX+PGM.Status],pgmFixingPass, .10:
RstSt [EBX+PGM.Status],pgmFixingPass ; Last but one pass has just ended. Prepare for the final pass.
JMP .Final:
.10:MOV EAX,[EBX+PGM.PassNr]
INC EAX,EAX
CMP EAX,[EBX+PGM.Pgmopt.MaxPasses]
JNB .Fixing: ; MaxPasses approached, so this pass must be fixing
.20:; An ordinary pass is ending. If all symbols are fixed, goto .Final.
ListGetFirst [EBX+PGM.SymList]
JZ .Final:
.30:JNSt [EAX+SYM.Status],symFixed,.More: ; If any symbol is unfixed, more passes are needed.
.40:ListGetNext EAX
JZ .Final:
JMP .30: ; All symbols are fixed. Prepare for the final pass.
.Fixing: ; The fixing (last but one) pass is required.
SetSt [EBX+PGM.Status],pgmFixingPass
JMP .More:
.Final: ; CF=1, the final pass is required.
SetSt [EBX+PGM.Status],pgmLastPass
.More:INC [EBX+PGM.PassNr] ; CF=1, at least one more pass is necessary.
STC
.90:EndProcedure PassInspect
ENDPROGRAM pass