| Index | Manual | Download | Source | Macros | Embedded word Case ins.
Sitemap | Links | Forum | Tests | Projects

# ea.htm
Tuning
EaTune
Class
EA
Object
Ea
Macro
EaStackCheck
Procedures
EaAssemble
EaBufferAlign
EaBufferRelease
EaBufferReserve
EaBufferSort
EaCreate
EaDestroy
EaDisplayPgm
EaDisplayPosition
EaFs2Id
EaId2Fs
EaIniAssemble
EaIniGlobal
EaMain
EaMallocError
EaStreamAlign
@RTprocedures

This source file ea.htm contains an object Ea which represents the executable file euroasm.exe. It provides initialization of €ASM and assembles all source files specified at cmdline.
As there is only one instance of EA, the object `Ea` is defined statically.

    ea PROGRAM FORMAT=COFF,MODEL=FLAT,WIDTH=32
       INCLUDEHEAD euroasm.htm, \  Interface (structures, symbols and macros) of other modules used in this source.
                   dict.htm, eaopt.htm, exp.htm, ii.htm, msg.htm, pfcoff.htm, pfmz.htm, pfpe.htm, \
                   pgm.htm, pgmopt.htm, reloc.htm, sss.htm, stm.htm, sym.htm

    ea HEAD ; Start of module interface.

↑ EaTune
  Global parameters for fine tuning of €ASM performance.

    %EaStackSize  %SETA 1M  ; €ASM machine stack ES:ESP reserved size.
                            ;  Fatal error is thrown on overflow.
    %EaPoolSize   %SETA 64K ; Initial POOL block brutto size.
                            ;  More blocks may be allocated on demand later.
    %EaBufferSize %SETA 4K  ; Initial BUFFER brutto size.
                            ;  It can be increased (doubled) on demand when underestimated.
    %EaStackDepth %SETA 16  ; Initial number of stackable objects on STACK.
                            ;  It can be increased (doubled) on demand when underestimated.

↑ EA
  Structure EA describes the main EuroAssembler object Ea which represents the compiler itself.
  Member `Ea.TimeStart` keeps the real system time when euroasm.exe launched. It is used to compute the duration of runtime, which will be reported with I0980. See also `Ea.Eaopt.TimeStamp`.
  Member `Ea.BufferStack` is a pointer to STACK which stacks QWORDS which contain
  1. pointer to preallocated BUFFER in low DWORD, and
  2. arbitrary nonzero identifier in high DWORD, or NULL when the buffer is released and free.
  Member `Ea.StackBottom` is computed from `Ea.StackOrg` decreased by the reserved stack size minus some safety reserve. It is used for protection from stack overflow.

    EA STRUC
    .Version       D 8*B     ; EuroAssembler version "YYYYMMDD".
    .EuroasmOS     D 4*B     ; Zero-padded shortcut of EuroAssembler platform (oper.system), e.g. "Win",0.
    .Errorlevel    D D       ; Highest errorlevel reached so far in any source.
                   ;+10h
    .StackOrg      D D       ; €ASM machine stack pointer (ESP) at program entry.
    .StackBottom   D D       ; Bottom of euroasm.exe reserved machine stack.
    .Pool          D D       ; Pointer to Ea memory POOL.
    .BufferStack   D D       ; Pointer to STACK of Qwords described above.
                   ;+20h
    .Status        D D       ; Binary flags in EaEnc encoding.
    .ArgNr         D D       ; Ordinal number of currently processed cmdline argument.
    .SubPtr        D D       ; Pointer to a suboperation string applied to the source file, e. g. euroasm.exe "Source.asm"{12..%&}
    .SubSize       D D       ; Size of the suboperation string including brackets.                                        ^
                   ;+30h
    .TimeStart     D D       ; Real time when euroasm.exe launched, as seconds since midnight Jan 1st 1970 UTC.
    .SrcTime       D D       ; Last write time of currently processed source file.
    .MemPeakSrc    D D       ; Memory allocated by Src.Pool.
    .StmCount      D D       ; Total number of statements parsed.
                   ;+40h
    .CodePage      D D       ; Codepage currently loaded and cached in Ea.CodeTable.
    .CodeTable     DU 128*U  ; Dynamically updated translate table from ANSI[128..255] to WIDE characters.
    .EaoptIni      DS EAOPT  ; Global default EUROASM options valid at start of each source.
    .Eaopt         DS EAOPT  ; Currently valid EUROASM options in charge. Dynamically updated.
    .Pgmopt        DS PGMOPT ; Global default PROGRAM options valid at the start of each source.
    .IniFile       DS FILE   ; Global configuration FILE euroasm.ini.
    .SrcFile       DS FILE   ; Currently processed source file specified on cmdline.
       ENDSTRUC EA

↑ EaEnc
  Encoding of EA status flags.

    eaAtLeast1File   EQU 1 ; euroasm.exe was launched with one or more input source file.
    eaWildcarded     EQU 2 ; Input source file was specified with wildcard(s) ?, *.
    eaIniSectEUROASM EQU 4 ; [EUROASM] section of euroasm.ini is currently processed.
    eaIniSectPROGRAM EQU 8 ; [PROGRAM] section of euroasm.ini is currently processed.

↑ EaStackCheck
  Macro EaStackCheck is used to protect the program from stack overflow. It should be used in recursively invoked procedures.
Input
  - Current value of ESP is compared with global member `Ea.StackBottom`.
Output
  Arithmetic flags are destroyed.
Error
  F9210 Memory reserved for machine stack is too small for this program.

    EaStackCheck %MACRO
        CMP ESP,[Ea.StackBottom::]
        Msg cc=B,'9210' ; Memory reserved for machine stack is too small for this source file.
       %ENDMACRO EaStackCheck

       ENDHEAD ea ; End of module interface.

↑ Ea
  Since there is only one instance of the main €ASM object Ea, it is defined statically in [.bss] segment.
The main EuroAssembler object model
  EaMain:: ; Executable entry. EaCreate ; Ea constructor. SysEachFile EaAssemble SourceFileFromCmdLine EaDestroy ; Ea destructor. SysExitProcess ; Terminate euroasm.exe.

    [.bss]
    Ea::        DS EA                 ; Instance of the main EuroAssembler object.
    [.data]
    EaVersion:: DB "%^DATE"           ; Date "YYYYMMDD" when €ASM was built.
    EaIniFileDefault:                 ; Factory default options from ../objlib/euroasm.ini will be built-in to euroasm.exe.
      INCLUDEBIN "../objlib/euroasm.ini"
    EaIniFileDefaultEnd:

↑ EaMain
  This is the main procedure of EuroAssembler and its entry point.
Invokes
  DictLookup EaBufferRelease EaBufferReserve EaCreate EaDestroy EaIniAssemble EaIniGlobal ExpParseKeyName ExpParseKeyValue
Invoked from
  OS program loader.

    [.text]
    EaMain:: PROC                                    ; Entry point of EuroAssembler. Here the execution begins and ends.
        MOV EAX,ESP
        Invoke EaCreate,EAX
        ; Command-line arguments are source file names mixed with EUROASM options,
        ;  separated with unquoted space or comma and they are processed in two passes:
        ; Cmdline pass 1 will ignore filenames and store each option as is to a temporary buffer.
        Invoke EaBufferReserve,EaMain
        MOV EBP,EAX
        BufferStore EBP, =B "[EUROASM]",9            ; Initialize contents with division name.
        BufferStoreByte EBP,10                       ; Terminate with line-feed.
    .10:INCD [Ea.ArgNr]                              ; Get the next argument (a filename or keyword option).
        SysGetArg [Ea.ArgNr]                         ; Set ESI,ECX to a cmdline argument.
        JC .30:                                      ; If there are no more arguments.
        MOV EBX,ESI                                  ; Pointer to a potential keyword.
        LEA EDI,[ESI+ECX]                            ; End of potential EUROASM keyword including its value.
        Invoke ExpParseKeyName::,ESI,EDI
        JC .10:                                      ; If the argument was not a keyword=, then it must be a filename. Ignore in pass 1.
        LEA EDX,[EAX-1]
        SUB EDX,EBX                                   ; EBX,EDX is now KeyName.
        Invoke ExpParseKeyValue::,EAX,EDI
        JC .10:                                      ; Ignore. Invalid options will be processed in cmdline pass 2 and treated as a filename.
        Invoke DictLookup::, DictEaoptMisc::,EBX,EDX ;  EBX,EDX is option key name, e.g."NOWARN". ESI,ECX is valid option value, e.g. "2100".
        JNC .20:
        Invoke DictLookup::, DictEaoptStatus::,EBX,EDX
        JNC .20:
        Invoke DictLookup::, DictEaoptFea::,EBX,EDX
        JC .10:                                      ; Ignore. Unknown options will be processed in cmdline pass 2 and treated as a filename.
    .20:SysGetArg [Ea.ArgNr]                         ; Reload the whole valid argument again.
        BufferStore EBP,ESI,ECX                      ; Accumulate unassembled cmdline options in temporary buffer EBP.
        BufferStoreByte EBP,10                       ; Terminate with line-feed.
        JMP .10:                                     ; The next cmdline argument.
    .30:BufferRetrieve EBP                           ; Reload plaintext cmdline EUROASM options from the temporary buffer EBP.
        ADD ECX,ESI
        ; Text at ESI..ECX is virtual euroasm.ini contents composed from [EUROASM] division and cmdline options.
        Invoke EaIniAssemble,ESI,ECX,Ea.Eaopt,Ea.Pgmopt ; Compile the contents to Ea.Eaopt object.
        ; Now it's time to report first informative messages. They are suppressible only by cmdline option NOWARN=0010..0020.
        MOV EBX,Ea.SrcFile.Name                      ; As SrcFile was not used yet, its room will be temporarily misused as the current directory name temporary storage.
        SysGetCurrentDirectory EBX
        PUSHD 8,Ea.Version
          MOV EAX,ESP
          MOV ECX,Ea.EuroasmOS
          Msg '0010',EAX,ECX                         ; EuroAssembler version !1S !2$ started.
        POP EAX,EAX
        Msg '0020',EBX                               ; Current directory is "!1$".
        Invoke EaIniGlobal                           ; Compile global euroasm.ini to Ea object.
        BufferRetrieve EBP
        ADD ECX,ESI
        Invoke EaIniAssemble,ESI,ECX,Ea.Eaopt,Ea.Pgmopt ; Reapply cmdline options again.
        Invoke EaBufferRelease,EBP                   ; Temporary buffer for cmdline options is no longer necessary.
        CopyTo Ea.EaoptIni, Ea.Eaopt                 ; Snapshot the starting options for each source.
        ; Cmdline pass 2 will read&assemble filename(s) and skip command-line options.
        MOVD [Ea.ArgNr],0                            ; Start with the first argument again.
    .40:INCD [Ea.ArgNr]
        SysGetArg [Ea.ArgNr]
        JC .80:                                      ; If there are no more arguments.
        MOV EBX,ESI                                  ; Pointer to a potential keyword.
        LEA EDI,[ESI+ECX]                            ; End of potential EUROASM keyword including its value.
        Invoke ExpParseKeyName::,ESI,EDI
        JC .50:                                      ; If the argument was not a keyword=, go and treat the argument ESI,ECX as a filename to assemble.
        LEA EDX,[EAX-1]
        SUB EDX,EBX                                  ; EBX,EDX is now KeyName. Check if it is valid.
        PUSH ECX,ESI
          Invoke ExpParseKeyValue::,EAX,EDI
        POP ESI,ECX
        JC .50:                                      ; If the option value was invalid, go and treat the argument ESI,ECX as a filename to assemble.
        ; EBX,EDX is key name.
        Invoke DictLookup::, DictEaoptMisc::,EBX,EDX
        JNC .40:                                     ; Skip a valid cmdline option.
        Invoke DictLookup::, DictEaoptStatus::,EBX,EDX
        JNC .40:                                     ; Skip a valid cmdline option.
        Invoke DictLookup::, DictEaoptFea::,EBX,EDX
        JNC .40:                                     ; Skip a valid cmdline option.
    .50:; ESI,ECX will be treated as a filename to assemble. It may be suboperated and it may have wildcards.
        ; String may look like file.asm or "file*.asm" or "file.asm"{1..40}.
        ; Filename wildcards without quotes will be solved by SysEachFile,
        ;   suboperation string will be parsed to Ea.SubPtr,Ea.SubSize.
        LEA EDX,[ESI+ECX]
        LODSB
        MOV [Ea.SubPtr],EDX                          ; Initialize Ea.Sub to an empty string.
        MOV [Ea.SubSize],0
        MOV EDI,ESI
        DEC ESI
        CMP AL,'"'
        JNE .60:                                     ; If filename is not in quotes, it cannot have suboperations.
        INC ESI                                      ; Source file is specified in quotes.
        REPNE SCASB                                  ; Find the closing quote.
        MOV [Ea.SubPtr],EDI
        SUB EDX,EDI                                  ; Suboperation size.
        LEA ECX,[EDI-1]
        MOV [Ea.SubSize],EDX
        SUB ECX,ESI                                  ; ESI,ECX is netto filename. It may contain wildcard characters ? *.
        SetSt [Ea.Status],eaWildcarded
        RstSt [Ea.Status],eaAtLeast1File
        MOV EDX,ECX
        MOV EDI,ESI
        MOV AL,"?"
        REPNE SCASB
        MOV ECX,EDX
        JE .70:
        MOV EDI,ESI
        MOV AL,"*"
        REPNE SCASB
        MOV ECX,EDX
        JE .70:
        RstSt [Ea.Status],eaWildcarded
    .60:MOV EDX,ECX
    .70:SysAssignFile Ea.SrcFile,ESI,EDX
        ; Resolve wildcards using SysEachFile, and invoke callback procedure EaAssemble
        ; on each resolved source file. Succesfull callback will set flag eaAtLeast1File.
        SysEachFile Ea.SrcFile,EaAssemble
        JSt [Ea.Status],eaWildcarded | eaAtLeast1File,.40: ; Fetch and assemble the next source.
        ; Filename read from cmdline was not found, perhaps no file matched the mask.
        PUSH EDX,ESI                                 ; ESI,EDX is nonwildcarded filename from cmdline.
         MOV EAX,ESP
         Msg '8010',EAX                              ; No such file "!1S".
        POP ESI,EDX
        JMP .40:                                     ; Fetch the next argument from cmdline.
    .80: ; All cmdline arguments were processed.
        CMP [Ea.ArgNr],1
        Msg cc=NA,'8000'                             ; No input file specified.
    .90:Invoke EaDestroy
        MOV ESP,[Ea.StackOrg]
        SysExitProcess [Ea.Errorlevel]               ; Shutdown EuroAssembler.
       ENDP EaMain::

↑ EaCreate StackOrg
  Constructor which initializes the Ea object.
Input
  StackOrg is value of ESP at program entry.
Output
  Object Ea is initialized.
Invoked by
  EaMain
Invokes
  EaIniAssemble

    EaCreate Procedure StackOrg
        MOV ESI,EaVersion
        MOV EDI,Ea.Version
        MOVSD                                        ; Copy the version string "YYYYMMDD" defined statically when €ASM was build.
        MOVSD
        ; Set €ASM system %variables values into Ea object.
        SysGetEuroasmOS
        MOV [Ea.EuroasmOS],EAX
        SysGetUTC                                    ; Get real system time as the number of seconds since 1.1.1970 to EAX.
        MOV [Ea.TimeStart],EAX
        MOV [Ea.Eaopt.TimeStamp],EAX                 ; Initialize nominal system time, too.
        ; Manage machine stack SS:ESP.
        MOV EBX,[%StackOrg]
        MOV [Ea.StackOrg],EBX                        ; EBX=Top of stack.
        SysGetStackSize                              ; EAX=size of this running €ASM reserved machine stack (SS:ESP).
        Msg cc=C,'9210'
        SUB EBX,EAX                                  ; EBX=bottom of stack.
        ADD EBX,4K                                   ; A safety reserve.
        MOV [Ea.StackBottom],EBX                     ; When ESP gets below this value, F9210 is reported.
        ; Pool of heap memory for €ASM own memory management.
        MOV EDI,%EaPoolSize
        PoolCreate  Size=EDI, ErrorHandler=EaMallocError
        MOV [Ea.Pool],EAX
        ; Stack of universal reserveable buffers.
        StackCreate EAX,8,Depth=%EaStackDepth        ; BufferStack items have two DWORDs each.
        MOV [Ea.BufferStack],EAX
        ; Initialize EUROASM options with factory defaults built-in  euroasm.exe body.
        Invoke EaIniAssemble,EaIniFileDefault,EaIniFileDefaultEnd, Ea.Eaopt, Ea.Pgmopt
       EndProcedure EaCreate

↑ EaDestroy
  Destructor of Ea object.
Input
  -
Output
  I0980, I0990
Error
  W2575
Invoked by
  EaMain

    EaDestroy Procedure
        MOV ECX,[Ea.StmCount]
        TEST ECX
        JZ .90:                                      ; If no statement was assembled.
        SysGetUTC
        SUB EAX,[Ea.TimeStart]
        JNZ .50:
        INC EAX                                      ; Round up the total assembly duration to at least 1 second.
    .50:MOV EBX,EAX                                  ; EBX is the duration of assembly.
        MOV EDX,[Ea.Pool]
        PoolDestroy EDX
        Msg cc=C,'2575','Ea',EDX                     ; Deallocation of virtual memory !1C.Pool !2Hh failed.
        ADD EAX,[Ea.MemPeakSrc]
        SHR EAX,10
        Msg '0980',EAX,[Ea.StmCount],EBX             ; Peak memory allocation !1D KB. !2D statements assembled in !3D s.
    .90:Msg '0990',[Ea.Errorlevel]                   ; EuroAssembler terminated with errorlevel !1D.
     EndProcedure EaDestroy

↑ EaAssemble
  This procedure assembles lines from `Ea.SrcFile` . The source filename might have been specified with wildcards. Usually the whole file is assembled but possible suboperation of source can be specified with `Ea.SubPtr,Ea.SubSize`.
  EaAssemble is callback procedure invoked in EaMain from the macro SysEachFile.
Object model
  See Ea object model and Stm object model.
Input
  EDI= pointer to WIN32_FIND_DATAW structure with file attributes (in Windows version only).
  Ea.SrcFile is assigned with the source file name, wildcards resolved. Leading "./" is removed, if any.
  Ea.SubPtr, Ea.SubSize specifies suboperation(s) with source file as given on cmd line, when only a part of it should be assembled, for instance `{1..%&-40}`. Ea.SubSize=0 when no suboperation of input source file was specified.
Output
  CF=0 if the source file was assembled.
Error
  CF=1 if fatal error occured (errorlevel 9) and €ASM needs to abort.
Invokes
  SrcAssemble SrcCreate SrcDestroy
Invoked from
  EaMain as a callback.
Tested by
  t1210

    EaAssemble Procedure
         LEA ESI,[EBX+FILE.Name]
         SysGetFileTime ESI
         MOV [Ea.SrcTime],EAX
         SetSt [Ea.Status],eaAtLeast1File
         Invoke SrcCreate::
         Invoke SrcAssemble::
         Invoke SrcDestroy::
         CMP EAX,[Ea.MemPeakSrc::]
         JNA .80:
         MOV [Ea.MemPeakSrc::],EAX
    .80: CMP [Ea.Errorlevel],9
         CMC                                         ; Return CF on fatal Euroasm error, such as bad memory allocation or stack overflow.
       EndProcedure EaAssemble                       ; This prevents SysEachFile from further wildcard expansions.

↑ EaMallocError
  Memory allocation exception handler. It is called from PoolCreate when allocation request failed (fatal error).
See also
  PoolCreate

    EaMallocError:: PROC
         Msg '9110'                                  ; Cannot allocate virtual memory.
         RET
         ENDP EaMallocError

↑ EaBufferReserve RequestingObject
  EaBufferReserve returns empty buffer from the stack of universal buffers.
  It will search Ea.BufferStack for unoccupied buffer and, if none found, create a new one and add it on the stack. The optimal initial Ea.BufferStack size depends on the nesting depth used in assembled program (macro in macro, nested suboperation etc) and it is increased on demand.
  Objects kept on Ea.BufferStack are QWORDS where the first DWORD is pointer to a BUFFER, and the second DWORD is nonzero identifier of occupation (zero value indicates that the buffer is released).
Input
  RequestingObject is address of the object which is going to use this buffer. It is used for debugging purpose only (to find out which Procedure requested the buffer).
Output
  CF=0, EAX= pointer to an empty buffer.
Error
  CF=1, EAX=0 fatal error F9312.
See also
  EaBufferRelease.
Invoked by
  ChunkInclude ChunkSuboperate CtxCreate CtxDiscard CtxFind EaIniGlobal EaMain ExpEval ExpEvalData ExpEvalIdentifier ExpParseDatatype ExpStoreInstr IiAssembleMultiop IiFlush LstGetFileName MemberAdd MemberUpdate PfDrectveCreate PfSuboperate PfcoffCompile PfcoffLoadPgm PfcomCompile PfelfCreate PfelfLoadPgm PflibcofCompile PflibomfCompile PfmzCompile PfomfLoadDataBlock PfomfLoadModule PfomfStoreData PfomfStoreModule PfpeBaserelocFixup PfpeCompile PfpeExportCreate PfpeImportCreate PfpeOptionalHeader PfrsrcLoadIconFile PfrsrcLoadPgm PgmDetectImportModule PgmListGlobals PgmListLiterals PgmListMap PgmOrderSymbols PgmSelectModules PgmoptSetDefaults PseudoData PseudoPROC1 PseudoSEGMENT PseudoSTRUC PseudopcDISPLAY PseudopcERROR PseudopcSET PseudopcSET2 PseudopcSETA PseudopcSETB PseudopcSETC PseudopcSETE PseudopcSETL PseudopcSETS PseudopcSETX RelocPurge SrcCreate SssGuessPurpose StmCreate StmExpandField StmListing SymCreate SymCreateLiteral VarExpand VarExpandField VarSuboperate

    EaBufferReserve Procedure RequestingObject
    BufRec LocalVar Size=8
          MOV EBX,[Ea.BufferStack]
          MOV ESI,[EBX+STACK.Ptr]
          SUB ECX,ECX
    .10:  SUB ESI,[EBX+STACK.Size]
          CMP ESI,[EBX+STACK.Bottom]
          JNB .50:
         ; No released buffer found on stack.
          BufferCreate [EBX+STACK.Pool],Size=%EaBufferSize
          JC .F9313:
          LEA EDI,[%BufRec]
          MOV [EDI],EAX
          MOV [EDI+4],ECX
          StackPush EBX,EDI
          JNC .30:
    .F9313:SUB EAX,EAX
          Msg '9313',[%RequestingObject]             ; Alloc.error reserving buffer for !1H.
          STC
          JMP .90:
    .30:  MOV ESI,EAX
    .50:  CMP [ESI+4],ECX                            ; ESI is at Qword which describes the buffer.
          JNZ .10:                                   ; The buffer is occupied. Try the lower one.
          LODSD
          MOV ECX,[%RequestingObject]
          TEST ECX
          JNZ .80:
          DEC ECX                                    ; If RequestingObject was not specified, use -1 (any nonzero is OK).
    .80:  MOV [ESI],ECX
          PUSHD [EAX+BUFFER.Bottom]
          POPD  [EAX+BUFFER.Ptr]                     ; BufferClear.
    .90:  MOV [%ReturnEAX],EAX
          EndProcedure EaBufferReserve

↑ EaBufferRelease BufferPtr
  EaBufferRelease will mark the specified buffer as free. It does not pop the buffer from Ea.BufferStack. Released buffer may be reused later by EaBufferReserve.
Input
  BufferPtr pointer to the buffer, as returned from EaBufferReserve. It may be 0, nothing happens in this case.
Output
  CF=0 Buffer was released and cleared.
Error
  CF=1 The specified buffer was not found on Ea.BufferStack.
See also
  EaBufferReserve.
Invoked by
  ChunkInclude ChunkSuboperate CtxDestroy CtxDiscard CtxFind EaIniGlobal EaMain ExpEval ExpEvalData ExpEvalIdentifier ExpParseDatatype ExpStoreInstr IiAssembleMultiop IiFlush LstGetFileName MemberAdd MemberUpdate PfDrectveCreate PfSuboperate PfcoffCompile PfcoffLoadPgm PfcomCompile PfelfDestroy PfelfLoadPgm PflibcofCompile PflibomfCompile PfmzCompile PfomfLoadDataBlock PfomfLoadModule PfomfStoreData PfomfStoreModule PfpeBaserelocFixup PfpeCompile PfpeExportCreate PfpeImportCreate PfpeOptionalHeader PfrsrcLoadIconFile PfrsrcLoadPgm PgmDetectImportModule PgmListGlobals PgmListLiterals PgmListMap PgmOrderSymbols PgmSelectModules PgmoptSetDefaults PseudoData PseudoPROC1 PseudoSEGMENT PseudoSTRUC PseudopcDISPLAY PseudopcERROR PseudopcSET PseudopcSET2 PseudopcSETA PseudopcSETB PseudopcSETC PseudopcSETE PseudopcSETL PseudopcSETS PseudopcSETX RelocPurge SrcCreate SssGuessPurpose StmDestroy StmExpandField StmListing SymCreate SymCreateLiteral VarExpand VarExpandField VarSuboperate

    EaBufferRelease Procedure BufferPtr
           MOV ECX,[%BufferPtr]
           MOV EBX,[Ea.BufferStack]
           JECXZ .90:
           MOV ESI,[EBX+STACK.Ptr]
    .10:   SUB ESI,[EBX+STACK.Size]
           CMP ESI,[EBX+STACK.Bottom]
           JB .90:
           CMP [ESI],ECX
           JNE .10:
           MOVD [ESI+4],0
    .90:EndProcedure EaBufferRelease

↑ EaBufferSort PtrBuffer
  EaBufferSort will alphabetically sort objects whose pointers are provided in the buffer. Objects may be SYM, VAR, MAC or any other class which begins with .NamePtr and .NameSize.
Input
  PtrBuffer Pointer to a BUFFER filled with DWORD pointers to unsorted-yet objects.
Output
  Objects in PtrBuffer are sorted by name.
Error
  -
See also
  ShellSort.
Invoked by
  PfpeExportCreate PgmListGlobals PgmOrderSymbols

    EaBufferSort Procedure PtrBuffer
         BufferRetrieve [%PtrBuffer]
         SAR ECX,2        ; PtrBuffer contains DWORD pointers. ECX is now the number of sorted objects.
         JZ .90:
         ShellSort ESI,ECX,4,.CmpObjNames

    .CmpObjNames PROC1     ; Callback subprocedure to compare-by-name two objects,
                          ;     whose pointers are pointed to with ESI and EDI.
         PUSH EBX,ECX     ; ShellSort needs those registers preserved.
          MOV EBX,[ESI]   ; Pointer to the object 1.
          MOV EDX,[EDI]   ; Pointer to the object 2.
          TEST EBX
          JZ .C9:
          TEST EDX
          JZ .C9:
          MOV ECX,[EBX+4] ; Size of the .Name 1.
          CMP ECX,[EDX+4] ; Size of the .Name 2.
          JBE .C2:
          MOV ECX,[EDX+4]
     .C2: CLC             ; ECX is now the shorter size of both names.
          JECXZ .C9:      ; No swap if the names are empty.
          MOV EBX,[EBX]   ; Pointer to the .Name 1.
          MOV EDX,[EDX]   ; Pointer to the .Name 2.
          TEST EBX
          JZ .C9:
          TEST EDX
          JZ .C9:
     .C3: MOV AL,[EBX]    ; Load a character from .Name 1.
          MOV AH,[EDX]    ; Load a character from .Name 2.
          INC EBX         ; Prepare pointer to the next character.
          INC EDX         ; Prepare pointer to the next character.
          PUSH EAX        ; First compare case-insensitively.
            OR AX,0x2020  ; Simplified conversion to lowercase.
            CMP AH,AL     ; Compare case-insensitive first (C-I).
          POP EAX         ; Restore case.
          JB .C5:         ; If the C-I order requires swapping.
          JA .C9:         ; If the C-I order is compliant, return with CF=0.
          CMP AH,AL       ; Otherwise compare case-sensitively (C-S).
          JB .C5:         ; If the C-S order requires swapping.
          JA .C9:         ; If the C-S order is compliant, return with CF=0.
          LOOP .C3:       ; If not decided yet, go check the next characters.
          ; The shorter part of the name matched exactly.
          MOV EBX,[ESI]   ; Pointer to the object 1.
          MOV EDX,[EDI]   ; Pointer to the object 2.
          MOV ECX,[EBX+4] ; Name 1 size.
          CMP [EDX+4],ECX ; Compare with Name 2 size.
          JB .C5:         ; If the order requires swapping.
          JA  .C9:        ; If the order is compliant, return with CF=0.
          ; Both objects have identical names. This happens only when sorting global symbols. Compare by scope.
          MOV EAX,[EBX+SYM.Status]
          MOV ECX,[EDX+SYM.Status]
          AND EAX,symScopeMask
          AND ECX,symScopeMask
          CMP ECX,EAX
          JAE .C9:        ; If the order is compliant, return with CF=0.
     .C5: MOV EAX,[ESI]   ; Object names are not in ascending order, swap them.
          XCHG EAX,[EDI]
          MOV [ESI],EAX
          STC             ; Signalize to the caller that objects were swapped.
     .C9:POP ECX,EBX
         RET
         ENDP1 .CmpObjNames

    .90:EndProcedure EaBufferSort

↑ EaBufferAlign Buffer, Alignment
  EaBufferAlign keeps storing NULL bytes to Buffer until its contents size is aligned.
Input
  Buffer is a pointer to BUFFER to align.
  Alignment is required alignment. 0..1=no alignment, 2=WORD, 4=DWORD etc.
  Forced to 0 when the Aligment is not a power of two.
Output
  EAX= number of NULL bytes stored to Buffer.
Error
  -
Invokes
  ExpAlign
Invoked by
  PfDrectveCreate PfmzCompile PfpeBaserelocFixup PfpeCompile PfpeImportCreate PfrsrcLoadIconFile PfrsrcLoadPgm

    EaBufferAlign Procedure Buffer, Alignment
         MOV EBX,[%Buffer]
         BufferRetrieve EBX
         Invoke ExpAlign::,ECX,[%Alignment],0
         MOV [%ReturnEAX],ECX                        ; Number of stored NULL bytes.
         XOR EDX,EDX
         CMP ECX,EDX
         JZ .90:
         SHR ECX,1
         JNC .20:
         BufferStoreByte EBX,EDX
    .20: SHR ECX,1
         JNC .40:
         BufferStoreWord EBX,EDX
    .40: JECXZ .90:
    .50: BufferStoreDword EBX,EDX
         LOOP .50:
    .90:EndProcedure EaBufferAlign

↑ EaStreamAlign Stream, Alignment, Stuff
  EaStreamAlign keeps storing Stuff bytes to Stream until its contents size is aligned.
Input
  Stream is a pointer to STREAM to align.
  Alignment is required alignment. 0..1=no alignment, 2=WORD, 4=DWORD etc. 0 when the Aligment is not a power of two.
  Stuff is a DWORD value whose four bytes will be used as aligment stuff. Usually 0 or 0x90909090.
Output
  EAX= number of stuff bytes stored to Stream.
Error
  -
Invokes
  ExpAlign
Invoked by
  PfelfHdrsStream PflibomfCompile

    EaStreamAlign Procedure Stream, Alignment, Stuff
         MOV EBX,[%Stream]
         StreamGetSize EBX
         Invoke ExpAlign::,EAX,[%Alignment],0  ; Returns ECX=stuff size.
         MOV [%ReturnEAX],ECX                  ; Number of stored stuff bytes.
         JECXZ .90:                            ; Done when %Stream is already aligned.
         MOV EDX,[%Stuff]
         SHR ECX,1
         JNC .20:
         StreamStoreByte EBX,DL
    .20: SHR ECX,1
         JNC .40:
         StreamStoreWord EBX,DX
    .40: JECXZ .90:
    .50: StreamStoreDword EBX,EDX
         LOOP .50:
    .90:EndProcedure EaStreamAlign

↑ EaId2Fs IdNamePtr, IdNameSize, OutBuffer
  EaId2Fs converts an €ASM identifier to a string which can be used as filename.
  Question mark `?` is replaced with underscore `_`.
Input
  IdNamePtr Pointer to identifier.
  IdNameSize Number of characters in the identifier.
  OutBuffer ^BUFFER allocated by caller, where the filename will be written to.
Output
  Result is written to OutBuffer.
Error
  -
See also
  EaFs2Id.
Invoked by
  PgmoptSetDefaults

    EaId2Fs Procedure IdNamePtr, IdNameSize, OutBuffer
        MOV ECX,[%IdNameSize]
        MOV ESI,[%IdNamePtr]
        JECXZ .90:
    .10:LODSB
        CMP AL,'?'
        JNE .20:
        MOV AL,"_" ; Replace question mark with underscore.
    .20:BufferStoreByte [%OutBuffer],EAX
        LOOP .10:
    .90:EndProcedure EaId2Fs

↑ EaFs2Id FsNamePtr, FsNameSize, OutBuffer
  EaFs2Id converts a name with filesystem-permitted characters to a valid €ASM identifier.
  Nonalphanumeric characters are replaced with underscore `_` and if the filename does not start with a letter, grave ``` is prefixed to the name.
Input
  FsNamePtr Pointer to file name.
  FsNameSize Number of characters in the name.
  OutBuffer ^BUFFER allocated by caller, where the identifier will be written to.
Output
  Result is written to OutBuffer.
Error
  -
See also
  EaId2Fs.
Invoked by
  PfcoffLoadPgm PfelfLoadPgm SrcCreate

    EaFs2Id Procedure FsNamePtr, FsNameSize, OutBuffer
        MOV ECX,[%FsNameSize]
        MOV ESI,[%FsNamePtr]
        MOV EDI,[%OutBuffer]
        JECXZ .90:
        LEA EDX,[ESI+ECX]
        ExpClassify [ESI]
        TEST AH,expLetter|expFullstop
        JNZ .30:                                     ; Go and store a valid character from AL.
        TEST AH,expDigit                             ; Test if the filename begins with a digit '0'..'9'.
        JZ .30:
        MOV AL,"`"                                   ; Prefix the digit with leading letter (grave).
    .20:BufferStoreByte EDI,EAX
    .30:CMP ESI,EDX
        JNB .90:
        LODSB
        ExpClassify AL
        TEST AH,expLetter|expDigit|expFullstop
        JNZ .40:
        MOV AL,"_"                                   ; Replace unacceptable character with underscore.
    .40:BufferStoreByte EDI,EAX
        JMP .30:
    .90:EndProcedure EaFs2Id

↑ EaIniAssemble IniPtr, IniEnd, Eaopt, Pgmopt
  EaIniAssemble will assemble contents of euroasm.ini file to EAOPT and PGMOPT structures.
Input
  IniPtr Pointer to the start of text of unassembled contents of euroasm.ini mapped in memory.
  IniEnd Pointer to the end of text.
  Eaopt Pointer to the target EAOPT object.
  Pgmopt Pointer to the target PGMOPT object.
Output
  EAOPT and PGMOPT are modified with assembled options.
Error
  Warnings W3701,W3705,W3720,W3730 are reported with macro Msg.
Invokes
  DictLookup EaoptAssemble ExpParseKeyName ExpParseKeyValue PgmoptAssemble StmCreate StmDestroy
Invoked by
  EaCreate EaIniGlobal EaMain SrcCreate

    EaIniAssemble Procedure IniPtr, IniEnd, Eaopt, Pgmopt
    ErrPar       LocalVar Size=8                     ; Parameter for error message.
    EaIniStm     LocalVar Size=SIZE#STM              ; Temporary fake statement to provide position of error in ini file.
          EaStackCheck
          RstSt [Ea.Status],eaIniSectEUROASM | eaIniSectPROGRAM
          LEA ESI,[%EaIniStm]
          Invoke StmCreate::,ESI
          PUSHD [Src.CurrentStm::]                   ; Save the current pointer to statement in source and
          MOV [Src.CurrentStm::],ESI                 ;   replace it with a temporary one.
    .10:  MOV EDI,[%IniPtr]
          LEA ESI,[%EaIniStm]
          MOV [ESI+STM.LinePtr],EDI                  ; Provide the line position for error message.
          MOV ECX,[%IniEnd]
          MOV ESI,EDI
          MOV AL,10
          SUB ECX,EDI
          JNA .90:
          REPNE SCASB
          MOV [%IniPtr],EDI                          ; ESI..EDI is the current line. %IniPtr specifies the start of the next line.
          LEA EDX,[%ErrPar]
          MOV EAX,EDI
          SUB EAX,ESI
          StripSpaces ESI,EAX
          MOV [EDX+0],ESI                            ; Prepare error message parameter.
          MOV [EDX+4],EAX
          TEST EAX
          JZ .10:
          CMP ESI,EDI                                ; The line at ESI can be a comment, [EUROASM], [PROGRAM], or Identifier=value.
          JNB .10:                                   ; Skipt empty line.
          LODSB
          CMP AL,'['
          JNE .50:
          RstSt [Ea.Status],eaIniSectEUROASM + eaIniSectPROGRAM
          MOV EDX,ESI                                ; Start of section name.
    .30:  CMP ESI,EDI
          JBE .40:
    .W3701:LEA ECX,[%ErrPar]
          Msg '3701',ECX                             ; Unknown section "!1S" in "euroasm.ini" file.
          JMP .10:
    .40:  LODSB
          CMP AL,']'
          JNE .30:
          LEA EBX,[ESI-1]                            ; End of section name.
          SUB EBX,EDX                                ; String EDX..EBX is section name (PROGRAM or EUROASM).
          StripSpaces EDX,EBX
          LEA ECX,[%ErrPar]
          MOV [ECX+0],EDX
          MOV [ECX+4],EBX
          Invoke DictLookup::, DictIniSect::, EDX,EBX
          JC .W3701:
          SetSt [Ea.Status],EAX                      ; EAX is eaIniSectEUROASM or eaIniSectPROGRAM.
          JMP .10:
    .50:  CMP AL,';'
          JE .10:
          CMP AL,'#'                                 ; Comment line in euroasm.ini may begin with ; or #.
          JE .10:
          LEA EDX,[ESI-1]                            ; EDX points to "ident= value".
          Invoke ExpParseKeyName::,EDX,EDI           ; Returns EAX behind the equal sign.
          JNC .60:
    .W3705:LEA ECX,[%ErrPar]
          Msg '3705',ECX                             ; Unexpected text "!1S" in "euroasm.ini" file.
          JMP .10:
    .60:  Invoke ExpParseKeyValue::,EAX,EDI          ; Returns ESI,ECX value string.
          JC .W3705:
          DEC EAX
          SUB EAX,EDX                                ; EDX,EAX is now key name. ESI,ECX is key value.
          JSt [Ea.Status],eaIniSectEUROASM, .70:
          JSt [Ea.Status],eaIniSectPROGRAM, .80:
          LEA ECX,[%ErrPar]
          Msg '3710',ECX                             ; Option "!1S" is in undefined section of "euroasm.ini" file.
          JMP .10:
    .70:  Invoke EaoptAssemble::,[%Eaopt],EDX,EAX,ESI,ECX
          JMP .10:                                   ; The next line.
    .80:  Invoke DictLookup::, DictPgmopt::, EDX,EAX
          LEA EDX,[%ErrPar]
          Msg cc=C,'3730',EDX                        ; "!1S" is unknown option in [PROGRAM] section.
          JC .10:
          Invoke PgmoptAssemble::, [%Pgmopt],EAX,ESI,ECX,
          JMP .10:
    .90:  LEA ESI,[%EaIniStm]
          Invoke StmDestroy::,ESI
          POPD [Src.CurrentStm::]                    ; Restore the current statement in source.
        EndProcedure EaIniAssemble

↑ EaIniGlobal
  EaIniGlobal will update Ea.Eaopt from global euroasm.ini and create this file if it didn't exist.
  Global euroasm.ini has a fixed name `%AppData%\eurotool\euroasm.ini` in MS Windows, or `/etc/eurotool/euroasm.ini` in Linux.
Input
  -
Output
  CF=0 Ea.Eaopt updated, copied to Ea.EaoptIni. Global file created.
Error
  CF=1 Errors are reported with macro Msg.
Invokes
  EaBufferRelease EaBufferReserve EaIniAssemble
Invoked by
  EaMain

    EaIniGlobal Procedure
        Invoke EaBufferReserve::,%^PROC
        MOV EBX,EAX                                  ; Temporary buffer for the name of configuration file.
        %IF "%eaos" === "win"
          SysGetEnvironment =B"AppData",7,EBX
          BufferStore EBX,=B"\eurotool\euroasm.ini",22
        %ELSE
          BufferStore EBX,=B"/etc/eurotool/euroasm.ini",26
        %ENDIF
        BufferRetrieve EBX
        Invoke EaBufferRelease::,EBX
        MOV EBX,ESI
        SysMkDir Ea.IniFile
        SysOpenFileMap Ea.IniFile,EBX                ; Open the file with name in EBX.
        JC .50:
        Msg '0070',EBX                               ; Assembling global option file "!1$".
        ADD EAX,ESI
        Invoke EaIniAssemble,ESI,EAX, Ea.Eaopt, Ea.Pgmopt
        SysCloseFile Ea.IniFile
        JMP   .70:
    .50:SysCreateFile Ea.IniFile,EBX                 ; Global euroasm.ini was not found, lets try to create it.
        JC .60:
        MOV ESI,EaIniFileDefault                     ; Factory-default.
        MOV ECX,EaIniFileDefaultEnd
        MOV EBX,Ea.IniFile
        SUB ECX,ESI
        SysWriteFile EBX,ESI,ECX                     ; Returns CF if the creation of global "euroasm.ini" failed.
        LEA EBX,[EBX+FILE.Name]
        Msg cc=NC,'0050',EBX                         ; Global option file "!1$" was created.
    .60:Msg cc=C, '0060',EBX                         ; Global option file "!1$" could not be created.
        SysCloseFile Ea.IniFile
    .70:CopyTo Ea.EaoptIni,Ea.Eaopt,Size=SIZE#EAOPT
       EndProcedure EaIniGlobal

    ; The following are ad hoc debug subprograms. Not to be released.

↑ EaDisplayPosition ProcName$Ptr, SourceName$Ptr, SourceLineNr
  Diagnostic runtime procedure for debugging of EuroAssembler itself. It will be assembled only when `EUROASM DEBUG=ENABLED`.
Input
  ProcName$Ptr is pointer to ASCIIZ name of current procedure where the procedure EaDisplayPosition was invoked. Use literal `=B"%^Proc"` at invocation.
  SourceName$Ptr is pointer to ASCIIZ filename of source where the procedure EaDisplayPosition was invoked. Use literal `=B"%^SourceName"` at invocation.
  SourceLineNr is physical line number of source where the procedure EaDisplayPosition was invoked. Use `%^SourceLine"` at invocation.
Example
  `Invoke EaDisplayPosition::, =B"%^Proc", =B"%^SourceName", %^SourceLine`

    EaDisplayPosition Procedure ProcName$Ptr,SourceName$Ptr,SourceLineNr
       Msg '1900',[%ProcName$Ptr],[%SourceName$Ptr],[%SourceLineNr] ; Position "!1$" at "!2$"{!3D}
      EndProcedure EaDisplayPosition

↑ EaDisplayPgm Pgm, SourceName$Ptr, SourceLineNr
  Diagnostic runtime procedure for debugging of EuroAssembler itself. It will be assembled only when `EUROASM DEBUG=ENABLED`.
Input
  Pgm is pointer to the displayed program.
  SourceName$Ptr is pointer to ASCIIZ filename of source where was the procedure EaDisplayPgm invoked. Use literal `=B"%^SourceName"` at invocation.
  SourceLineNr is physical line number of source where was the procedure EaDisplayPgm invoked. Use `%^SourceLine"` at invocation.
Example
  `Invoke EaDisplayPgm::, EBX, =B"%^SourceName", %^SourceLine`

    DebugInternal %IF %^DEBUG  ; Internal EuroAssembler debugging.
    EaDisplayPgm Procedure Pgm  ,SourceName$Ptr,SourceLineNr ; Display program objects PGM,SYM,SSS,RELOC.
    RelocTop LocalVar          ; End of RELOC array in current segment.
    SssRange LocalVar Size=44  ; Va000000..FFFFFF(0123),Fa000000,Rva000000
                               ; 0....5...10...15...20...25...30...35...40..
        Msg '1000' ; Separator.
        MOV EBX,[%Pgm]
           ; 1920 PGM^!1H:St=!2H, base program ******** !3S ********   EaDisplayPgm at "!4$"{!5D}',0
        Msg '1920',EBX,[EBX+PGM.Status],EBX,[%SourceName$Ptr],[%SourceLineNr] ; Display the base program EBX.
        CALL .PgmDisplay:
        ListGetFirst [EBX+PGM.ModulePgmList]
        JZ .90:
    .10:MOV EBX,EAX
           ; 1921 PGM^!1H:St=!2H,module **** !3S ****',0
        Msg '1921',EBX,[EBX+PGM.Status],EBX ; Display the module program EBX.
        CALL .PgmDisplay:
        ListGetNext EBX
        JNZ .10:
    .90:EndProcedure EaDisplayPgm

    EaDisplayPgm.PgmDisplay PROC ; Display program EBX.
        ListGetFirst [EBX+PGM.SymList]
        JZ .30:
    .20:MOV ESI,[EAX+SYM.Section]                    ; Display the symbol EAX.
        MOV ECX,[EAX+SYM.Status]
        MOV DL,'X'
        JSt ECX,symExport,.25:
        MOV DL,'P'
        JSt ECX,symPublic,.25:
        MOV DL,'I'
        JSt ECX,symImport,.25:
        MOV DL,'E'
        JSt ECX,symExtern,.25:
        MOV DL,'G'
        JSt ECX,symGlobal | symGlobalRef,.25:
        MOV DL,'S'
    .25:; LEA ECX,[EAX+SYM.DllNamePtr]
        MOV CL,[EAX+SYM.NameDynIndex]
        MOV CH,[EAX+SYM.NameIndex]
           ; 1922  SYM^!1H:Sc''!2Z'',St!3H,Se!4H,Sy!5H,Di!6W,!7S,[!8S]:!9H
        Msg '1922',EAX,EDX,[EAX+SYM.Status],ESI,[EAX+SYM.SymbPtr],ECX,EAX,ESI,[EAX+SYM.OffsetLow]
        ListGetNext EAX
        JNZ .20:                                     ; The next symbol.
    .30:LEA EDI,[%SssRange]                          ; Preformat %SssRange.
        MOVW [EDI+00],'Va'
        MOVW [EDI+08],'..'
        MOVB [EDI+16],'('
        MOVD [EDI+21],'),Fa'
        MOVD [EDI+31],',Sva'
        MOVB [EDI+41],0
        ListGetFirst [EBX+PGM.SssList]
        JZ .80:
    .40:PUSH EAX                                     ; Display the SSS object EAX.
          MOV ESI,EAX                                ; Prepare D1923 Bottom..Top(size),Fa in %SssRange.
          MOV EAX,[ESI+SSS.BottomLow]
          LEA EDI,[%SssRange+02]
          StoH EDI,Size=6
          MOV EAX,[ESI+SSS.TopLow]
          LEA EDI,[%SssRange+10]
          StoH EDI,Size=6
          MOV EAX,[ESI+SSS.TopLow]
          MOV EDX,[ESI+SSS.TopHigh]
          SUB EAX,[ESI+SSS.BottomLow]
          SBB EDX,[ESI+SSS.BottomHigh]
          LEA EDI,[%SssRange+17]
          StoH EDI,Size=4
          MOV EAX,[ESI+SSS.BottomFA]
          LEA EDI,[%SssRange+25]
          StoH EDI,Size=6
          LEA EDI,[%SssRange+35]
          MOV EAX,[ESI+SSS.SVA]
          StoH EDI,Size=6
        POP EAX
        LEA EDI,[%SssRange]
          ; '1923  SSS^!1H:St!2H,!3$,Sy!4H,Ni!5D,Si!6D,Sg!7H,Gr!8H',[!9S]
        Msg '1923',EAX,[EAX+SSS.Status],EDI,[EAX+SSS.SymPtr],[EAX+SSS.NameIndex],\
                      [EAX+SSS.SegmIndex],[EAX+SSS.SegmPtr],[EAX+SSS.GroupPtr],EAX
        BufferRetrieve [EAX+SSS.RelocBuffer]         ; Display RELOC objects of the segment EAX.
        LEA EDX,[ESI+ECX]
        MOV [%RelocTop],EDX
    .50:CMP ESI,[%RelocTop]
        JNB .75:
        MOV EDX,ESI
        BufferRetrieve [EAX+SSS.EmitBuffer]          ; ESI,ECX=emitted contents.
        XCHG EDX,ESI                                 ; Restore ESI=^RELOC, EDX=^1st emitted byte.
        ADD EDX,[ESI+RELOC.OrgLow]
        MOV EDI,[EDX]                                ; EDI=relocated storage unit in emitted data (WORD|DWORD).
        MOV ECX,[ESI+RELOC.Status]
     type %FOR Para,AbsVA,AbsRVA,Rel,Far,Sym,Dyn,PLT,GOT,GOToff,GOTrel
             LEA EDX,[=B"%type"]
             JSt ECX,reloc%type,.60:
          %ENDFOR type
             LEA EDX,[=B"None"]
    .60:JNSt ECX,relocWidth16,.65:
           ; RELOC^!1H:St!2H,Org!3H:!4H,Ad=!5H,Ob=!6W,Sym:!7H,!8S:!9$
        Msg '1924',ESI,[ESI+RELOC.Status],[ESI+RELOC.Section],[ESI+RELOC.OrgLow], \ 16bit
             [ESI+RELOC.AddendLow],EDI,[ESI+RELOC.Symbol],[ESI+RELOC.Symbol],EDX
        JMP .70:
    .65:   ; RELOC^!1H:St!2H,Org!3H:!4H,Ad=!5H,Ob=!6H,Sym:!7H,!8S:!9$
        Msg '1925',ESI,[ESI+RELOC.Status],[ESI+RELOC.Section],[ESI+RELOC.OrgLow], \ 32bit
             [ESI+RELOC.AddendLow],EDI,[ESI+RELOC.Symbol],[ESI+RELOC.Symbol],EDX
    .70:ADD ESI,SIZE# RELOC
        JMP .50:                                     ; The next RELOC.
    .75:ListGetNext EAX
        JNZ .40:                                     ; The next SSS object.
    .80:RET
       ENDPROC EaDisplayPgm.PgmDisplay:

    EaPoolDisplay:: Procedure aPool,LinePtr ; Display pool blocks.
        MOV EAX,[%LinePtr]
    ; 1912 Allocated memory pool at source line {!1D}:
        Msg '1912',EAX
        MOV EBX,[%aPool]
        SUB ECX,ECX
        MOV ESI,[EBX+POOL.Last]
    .10:TEST ESI
        JZ .20:
        ADD ECX,[ESI]
        MOV ESI,[ESI+4]
        JMP .10:
    .20:
    ; 1913 Pool=!1H, Gran=!2K, Total=!3H=!3K, Size=!4H=!4K
       Msg '1913',EBX,[EBX+POOL.Gran],ECX,[EBX-8]
       MOV EAX,[EBX-8]
       LEA EAX,[EBX+EAX-8]
    ; 1914 Pool.Prev=!1H, Last=!2H, Ptr=!3H, Top=!4H.
       Msg '1914',[EBX-4],[EBX+POOL.Last],[EBX+POOL.Ptr],EAX
       MOV EAX,[EBX+POOL.Last]
    .50:TEST EAX
       JZ .90:
       MOV ESI,[EAX]   ; Size.
       LEA EDI,[EAX+4] ; Prev.
       LEA EDX,[EAX+4+ECX]
    ; 1915   Poolblock=!1H, Prev=!2H, bottom=!3H, top=!4H.
       Msg '1915',EAX,ESI,EDI,EDX
       MOV EAX,ESI
       JMP .50:
     .90:
       EndProcedure EaPoolDisplay
     %ENDIF DebugInternal

↑ @RTprocedures

  Semiinline macros hired in EuroAssembler are for the first time dummy-expanded here in the module ea.htm. Their @RTprocedures are declared as PUBLIC in this module and they are declared as EXTERN in all other modules.

  This prevents the runtime code from being repeatedly emitted in each separately assembled module, which would unnecessarily blow up the final PE size.

See also
  %@RTprocedureList.

       ; Dummy expansion of semiinline macros creates their runtime procedures here.
       BufferCreate 0,0,0
       BufferNew 0,0
       BufferResize 0,0,0
       BufferStore  0,0,0
       BufferStoreByte 0,0
       BufferStoreDword 0,0
       BufferStorePascalString 0,0
       BufferStoreQword 0,0
       BufferStoreWord 0,0
       Clear 0
       Compare 0,0,0
       CopyTo 0,0
       FileAssign 0,0
       FileClose 0
       FileCreate 0
       FileEach 0,0
       FileMapOpen 0
       FileMkDir 0
       FileNameParse 0
       FileWrite 0
       GetArg 0
       GetLength$ 0
       IiAbort 0
       IiAbortIfNotST0
       IiAllowLocking Operand1
       IiDataSize Operand1
       IiDispatchFormat
       IiDispatchLocation 0
       IiDispSize Operand1
       IiEmitImm Operand1,BYTE
       IiEmitImm2 Operand1
       IiEmitOpcode
       IiImmSize Operand1
       IiStringDestination Operand1
       IiStringSource Operand1
       ListCreate 0,0
       ListInsert 0,0,0
       ListNew 0
       ListRemove 0,0
       ListStore 0,0
       LodD
       PoolCreate Size=%EaPoolSize
       PoolDestroy 0
       PoolNew 0,0
       ShellSort 0,0,0,0
       StackCreate 0,0
       StackPush 0,0
       StoD
       StoH Align=left
       StoQD Align=left
       StreamCreate 0
       StreamDump 0,0
       StreamStore 0,
       SysGetFileSize 0
       SysGetFileTime 0
       SysGetEnvironment 0,0,0

     ENDPROGRAM ea

▲Back to the top▲