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

# viewmain.htm
Data
Data
Procedures
AutodetectFileFormat
ByLevel
ExpandRem
IndexUpdate
ViewCreate
ViewDataCreate
Formating
FormatBIN
FormatBMP
FormatCUR
FormatCOFF16
FormatCOFF32
FormatCOFF64
FormatDLL32
FormatDLL64
FormatELF32
FormatELF64
FormatELFSO32
FormatELFSO64
FormatELFX32
FormatELFX64
FormatGIF
FormatICO
FormatJPG
FormatLIBCOF
FormatLIBOMF
FormatMIDI
FormatMP3
FormatMZ
FormatOMF
FormatPE32
FormatPE64
FormatPNG
FormatWAV
Detection of file format
DetectBMP
DetectCOFF16
DetectCOFF32
DetectCOFF64
DetectCUR
DetectDLL32
DetectDLL64
DetectELF32
DetectELF64
DetectELFSO32
DetectELFSO64
DetectELFX32
DetectELFX64
DetectGIF
DetectICO
DetectJPG
DetectLIBCOF
DetectLIBOMF
DetectMIDI
DetectMP3
DetectMZ
DetectOMF
DetectPE32
DetectPE64
DetectPNG
DetectWAV
Analyzing procedures
AnalyzeCOFF
AnalyzeCoffFileHeader
AnalyzeCoffRawData
AnalyzeCoffRelocations
AnalyzeCoffSectionHeader
AnalyzeCoffStringTable
AnalyzeCoffSymbolTable
AnalyzeElfDynamic
AnalyzeElfHash
AnalyzeElfFileHeader
AnalyzeElfNote
AnalyzeElfProgramHeader
AnalyzeElfRel
AnalyzeElfRela
AnalyzeElfSectionHeader32
AnalyzeElfSectionHeader64
AnalyzeElfSymbols
AnalyzeLibcofFileHeader
AnalyzeLibcofMemberHeader
AnalyzeMzProgram
AnalyzeOmfRecord
AnalyzeOptionalHeader
AnalyzePE
Helper functions
Fn00$CoffMachine
Fn01$CoffCharacteristics
Fn02$CoffSectionName
Fn03$CoffSectionFlags
Fn04$CoffSymbolName
Fn05$CoffSymbolSection
Fn06$CoffSymbolType
Fn07$CoffSymbolIndexStore
Fn08$CoffSymbolByIndex
Fn09$CoffSectionsIndexStore
Fn09$CoffSectionsIndexStore
Fn10$MajorMinorVersion1
Fn11$MajorMinorVersion2
Fn12$WinSubsystem
Fn13$DataDirName
Fn14$FileName
Fn15$SaveMemberSize
Fn16$DisplayName
Fn17$DisplaySymbolName
Fn18$MemberNumber
Fn19$OmfModuleName
Fn20$ElfSectionName
Fn21$ElfSymbolName
Fn22$ElfProgramSections
Fn23$GifColorTableSize
Fn24$FileSize
Fn24$Override
FnStoreSectionName

This is a module of EuroTool program EuroView.

             EUROASM CPU=X64,SIMD=Off,AutoAlign=yes,DumpWidth=38,Unicode=no,Debug=no
    viewmain PROGRAM Format=COFF,Width=64
               %DROPMACRO *
               INCLUDEHEAD argument.htm
               INCLUDE1 memory64.htm, cpuext64.htm, cpuext.htm, sort64.htm, string64.htm,
               INCLUDE1 status32.htm, time.htm
               EXTERN BufferCreate@RT

    HEAD                         ; What will the listing line start with:
    ;Level0   = 0x0000_0000      ; |
    Level1    = 0x1000_0000      ; |#
    Level2    = 0x2000_0000      ; |##
    Level3    = 0x3000_0000      ; |###
    Level4    = 0x4000_0000      ; |####
    LevelMask = Level1|Level2|Level3|Level4

    VIEW_INDEX STRUC             ; A structure which describes one viewed element. Used in Phase One.
    .Rem     D QWORD             ; Pointer to the remark (in EuroView memory). It may contain !x variables.
    .FA      D DWORD             ; Zero-based FileAddress of the element.
    .Size    D DWORD             ; Size of the element in bits 0..27 and level in bits 28..31.
            ENDSTRUC VIEW_INDEX

    LST_INDEX STRUC              ; A structure which describes one line of the output (listing) file. Used in Phase Two.
    .FA      D DWORD             ; Offset of the line from OutputPtr.
    .Size    D DWORD             ; Size of the line in bytes minus LF at the end.
            ENDSTRUC LST_INDEX
    ENDHEAD

    [.rodata]        ; Constant text data.
    EuroView::       DB "EuroView",0
    Version::        DB " %^Date",0

    [.data]
    FormatTable::
    FF %FOR %FileFormats         ; Enumeration %FileFormats is set in argument.htm.
         DQ Format%FF            ; Address of the formating procedure.
       %ENDFOR FF
    FnTable:                     ; Functions used by ExpandRem.
     DQ Fn00$CoffMachine
     DQ Fn01$CoffCharacteristics
     DQ Fn02$CoffSectionName
     DQ Fn03$CoffSectionFlags
     DQ Fn04$CoffSymbolName
     DQ Fn05$CoffSymbolSection
     DQ Fn06$CoffSymbolType
     DQ Fn07$CoffSymbolIndexStore
     DQ Fn08$CoffSymbolByIndex
     DQ Fn09$CoffSectionIndexStore
     DQ Fn10$MajorMinorVersion1
     DQ Fn11$MajorMinorVersion2
     DQ Fn12$WinSubsystem
     DQ Fn13$DataDirName
     DQ Fn14$FileName
     DQ Fn15$SaveMemberSize
     DQ Fn16$DisplayName
     DQ Fn17$DisplaySymbolName
     DQ Fn18$MemberNumber
     DQ Fn19$OmfModuleName
     DQ Fn20$ElfSectionName
     DQ Fn21$ElfSymbolName
     DQ Fn22$ElfProgramSections
     DQ Fn23$GifColorTableSize
     DQ Fn24$FileSize
     DQ Fn25$Override
    AddressDigits::     DD 4 ; Number of address digits in listing (4..8).
    OldStatus           DD 0
    MP3frame            DD 0
    MP3SamplerateTable: DD 44100, 48000, 32000                                 ; Used in FormatMP3.
    MP3BitrateTable:    DW 0,32,40,48,56,64,80,96,112,128,160,192,224,256,320  ; Used in FormatMP3.
    MP3report:          DB "MPEG1, Layer3, "
    MP3bitrate:         DB "xxx000 bit/s, "
    MP3freq:            DB "yyyyy Hz, "
    MP3channel:         DB "joint stereo.",0
    ElfSegmentTypes:    DB "null",0,"progbits",0,"symtab",0,"strtab",0,"rela",0,"hash",0,"dynamic",0,"note",0, \
                           "nobits",0,"rel",0,"shlib",0,"dynsym",0
    ElfDynamic: DB "NULL (ignored)",0,"NEEDED (required library)",0,"PLTRELSZ (size of PLT relocations)",0, \
                   "PLTGOT (PLT address)",0,"HASH (.hash address)",0,"STRTAB (.dynstr address)",0, \
                   "SYMTAB (.dynsym address)",0,"RELA (.rela.* address)",0,"RELASZ (.rela.* size)",0, \
                   "RELAENT (one RELA size)",0,"STRSZ (.strtab size)",0,"SYMENT (one symbol size)",0, \
                   "INIT (address of init function)",0,"FINI (address of termination function)",0, \
                   "SONAME (FA of this SO name)",0,"RPATH (offset of RPATH in .dynstr)",0, \
                   "SYMBOLIC",0,"REL (.rel.* address)",0,"RELSZ (.rel.* size)",0,"RELENT (one REL size)",0, \
                   "PLTREL (PLT relocation type)",0,"DEBUG",0,"TEXTREL (relocations for RO)",0, \
                   "JMPREL (.rela.plt address)",0,"BIND_NOW",0,"INIT_ARRAY (pointers to an array of pointers)",0, \
                   "FINI_ARRAY (pointers to an array of pointers)",0,"INIT_ARRAYSZ (size of the array)",0, \
                   "FINI_ARRAYSZ (size of the array)",0,"RUNPATH (offset of RUNPATH in .dynstr)",0,"FLAGS",0
    DataDirNames:
     DB 'EXPORT',0
     DB 'IMPORT',0
     DB 'RESOURCE',0
     DB 'EXCEPTION',0
     DB 'CERTIFICATE',0
     DB 'BASE_RELOC',0
     DB 'DEBUG',0
     DB 'ARCHITECTURE',0
     DB 'GLOBAL_POINTER',0
     DB 'TLS',0
     DB 'LOAD_CONFIGURATION',0
     DB 'BOUND_IMPORT',0
     DB 'IAT',0
     DB 'DELAY_IMPORT',0
     DB 'CLI_HEADER',0
     DB 'RESERVERD',0

    [.bss]                                 ; Working memory variables.
    ViewIndex::           DS VIEW_INDEX
    FileWriteOutputProc:: D QWORD ; Pointer to FileWrite in Windows or in Linux.
    FileIndexReopenProc:: D QWORD ; Pointer to FileClose and FileMapCreate in Windows or in Linux.
    InputPtr::            D QWORD ; Pointer to the contents of FileInput loaded in memory.
    InputSize::           D QWORD ; Input file size.
    InputEnd::            D QWORD ; Pointer to the end of contents of FileInput loaded in memory.
    OutputPtr::           D QWORD ; Pointer to the listing (in ASCII) in memory.
    OutputSize::          D QWORD ; Size of the listing.
    OutputEnd::           D QWORD ; Pointer to the end of listing in memory.
    IndexPtr::            D QWORD ; Pointer to the contents of FileIndex loaded in memory (1st VIEW_INDEX).
    IndexEnd::            D QWORD ; Pointer to the end contens of FileIndex loaded in memory.
    FormatNamePtr::       D QWORD ; Pointer to ASCIIZ string with uppercase format name.
    FormatProcPtr::       D QWORD ; Pointer to the file format function (FormatMZ, FormatCOFF32 etc)
    ArgNr::               D DWORD ; Binary number of the current cmd-line argument.
    ListingLines::        D DWORD ; Number of lines in FileOutput. Also Lines in viewwing.htm.
    Level0Buffer::        D QWORD ; Pointer to BUFFER for Level0.
    Level1Buffer::        D QWORD ; Pointer to BUFFER for Level1.
    Level2Buffer::        D QWORD ; Pointer to BUFFER for Level2.
    Level3Buffer::        D QWORD ; Pointer to BUFFER for Level3.
    Level4Buffer::        D QWORD ; Pointer to BUFFER for Level4.
    FaOfArchiveStrings    D DWORD
    FaOfDataDirs          D DWORD
    FaOfDynamicEnd        D DWORD
    FaOfElfProgramHeaders D DWORD
    FaOfElfSectionHeaders D DWORD
    FaOfHashEnd           D DWORD
    FaOfMembersTable      D DWORD
    FaOfNoteEnd           D DWORD
    FaOfPeSignature       D DWORD
    FaOfRelaEnd           D DWORD
    FaOfRelEnd            D DWORD
    FaOfRelocations       D DWORD
    FaOfSectionHeaders    D DWORD
    FaOfShstrtabData      D DWORD
    FaOfStringTable       D DWORD
    FaOfSymbolEnd         D DWORD
    FaOfSymbolsEnd        D DWORD
    FaOfSymbolTable       D DWORD
    FaOfThisSectionHeader D DWORD
    FaOfSoundStart        D DWORD
    FaOfSoundEnd          D DWORD
    Fn13Index             D DWORD
    LastOmfRecord         D DWORD
    MemberNumber          D DWORD
    MemberSize            D DWORD
    MzBytesFileSize       D DWORD
    MzEntry               D DWORD
    MzHeaderSize          D DWORD
    NrOfDataDirectories   D DWORD
    NrOfElfProgramHeaders D DWORD
    NrOfElfSectionHeaders D DWORD
    NrOfRelocations       D DWORD
    NrOfSections          D DWORD
    NrOfSymbols           D DWORD
    PaletteSize           D DWORD
    RecordSize            D DWORD
    SectionIndex          D DWORD
    SectionNumber         D DWORD
    SizeOfColorTable      D DWORD
    SizeOfStringTable     D DWORD  ; Including DWORD size value.
    ID3size               D DWORD  ; Size of the entire ID3 tag in MP3 file, without 10 bytes.
    SymbolIndex           D DWORD
    SymbolNumber          D DWORD
    ACharacter            D BYTE
    Number                D 16*BYTE
    WorkMemory::          D 800*BYTE
    [.text]

↑ AutodetectFileFormat
  Find a file format of the viewed file. Unrecognized formats will return as a binary file.
  The list of available declared formats is in argument.htm .AutodetectFileFormat never fails; at least it ends with RAX=^FormatBIN:: and RDX=^'BIN',0.
Input
  InputPtr= pointer to the start of memory-mapped input file.
  InputEnd= pointer to the end of input file in memory.
Output
  RAX=address of a global Format%FF procedure, where %FF is the detected file format, e.g. `^FormatCOFF32`.
  RCX= ordinal number of file format. Greater than 0.
Called by
  ViewPrologue (Windows) or ViewPrologue (Linux).
Calls
  Detect%FF

    AutodetectFileFormat:: PROC
         MOV RSI,[InputPtr::]
         MOV RCX,[InputEnd::]
         SUB RCX,RSI
         JA .20:
         LEA RAX,[FormatBIN::]             ; FileInput size=0 implies format BIN.
         MOV EAX,ArgFileFormatBIN
         JMP .Found:
    .20:
    FF %FOR %FileFormats
         MOV RSI,[InputPtr::]
         MOV RCX,[InputEnd::]
         CALL Detect%FF                    ; Return CF=0 when %FF detected.
         LEA RAX,[Format%FF:]
         MOV ECX,ArgFileFormat%FF
         JNC .Found
       %ENDFOR FF
    .Found:
        RET
       ENDP AutodetectFileFormat

ByLevel
  Callback procedure for sorting VIEW_INDEX records in FileIndex by
  1. VIEW_INDEX.FA
  2. Level
  3. VIEW_INDEX.Size
Input
  RSI,RDI are pointers to VIEW_INDEX structures to compare.
Output
  Record at RSI,RDI are swapped and CF=1 when they were in wrong order.
Clobbers
  RAX,RDX

    ByLevel:: PROC
        MOV EAX,[RSI+VIEW_INDEX.FA]
        MOV EDX,[RDI+VIEW_INDEX.FA]
        CMP EDX,EAX
        JB .SW:
        JA .OK:
        MOV EAX,[RSI+VIEW_INDEX.Size]
        MOV EDX,[RDI+VIEW_INDEX.Size]
        SHR EAX,28
        SHR RDX,28
        CMP EAX,EDX
        JB .SW:
        JA .OK:
        MOV EAX,[RSI+VIEW_INDEX.Size]
        MOV EDX,[RDI+VIEW_INDEX.Size]
        CMP EDX,EAX
        JNB .OK:
    .SW:MOV RAX,[RSI+0]
        MOV RDX,[RSI+8]
        XCHG RAX,[RDI+0]
        XCHG RDX,[RDI+8]
        MOV [RSI+0],RAX
        MOV [RSI+8],RDX
        STC
    .OK:RET
       ENDP ByLevel

ExpandRem

  ExpandRem copies bytes addressed by `[RBX+VIEW_INDEX.Rem]` to RDI and expands escaped parameters.
  When the remark is empty, ExpandRem only stores CR+LF.

  Exclamation `!` is the escape character. If a decimal number immediately follows the exclamation, this many bytes will be used from the inspected file, otherwise `VIEW_INDEX.Size` bytes will be used.
  Address of the inspected file is specified by the current FA in R14, the input file is mapped at R8.
  The number R13=`VIEW_INDEX.Size` may be above 16, in this case each listing line is max.16 dumped bytes long and it is repeated with file address R14=`VIEW_INDEX.FA` increased.

  Table of escaped symbols: (`n` represents a decimal number)

  !n$ | Helper `n`-th function from FnTable::, e. g. `Fn12WinSubsystem`.
  !1A | `1` Low nibble from 2nd character converted to '0'..'F'.
  !2B | `2` 2 bytes as a hexadecimal number in big endian.
  !2b | `2` 2 bytes as a decimal number in big endian.
  !1C | `1` PNG color type.
  !nD | `n` bytes as a decimal number.
  !4d | `4` bytes as a decimal number in big endian.
  !4E | 4 bytes from FA+0..FA+3 as ASCII (PNG chunk identifier).
  !4F | 2+2 bytes as a hexadecimal segment:offset.
  !2G | ELF file type.
  !nH | `n` bytes as a hexadecimal number.
  !4h | `4` bytes as a hexadecimal number in big endian.
  !2I | Interpreted as import type in LIBCOF format.
  !12L | 12 decimal digits interpreted as 1970 datetime (seconds since 1.1.1970).
  !2M | ELF machine type.
  !4N | ELF section name.
  !1O | OMF record type.
  !4P | ELF program type.
  !4Q | ELF program flags.
  !4q | ELF section flags.
  !1R | ELF section number.
  !1r | ELF symbol number.
  !4S | ELF section type.
  !1s | ELF symbol info.
  !4T | Dword interpreted as 1970 datetime (seconds since 1.1.1970).
  !2U | Symbol's section number|type.
  !v | Disassemble block of code, width=16. Used for DOS-stub in PECOFF file.
  !V | Disassemble block of code, width is specified by ArgCodeWidth.
  !nX | `n` bytes as a text (ASCII characters 20..127 only, otherwise spaces).
  !8y | ELF32 dynamic
  !4Z | ELF relocation type.

Input
  RDI=pointer inside the line in FileOutput where the text will be expanded.
  RBX=pointer to VIEW_INDEX variable whose .Rem will be expanded to RDI.
  R12=pointer to the text of remark (usually `VIEW_INDEX.Rem`).
  R13=current remaining size of data in this VIEW_INDEX. If R13>16, more listing lines will be generated. May have level bits.
  R14=file address of data in this VIEW_INDEX. If R13>16, R14 is increased in each listing line.
  R8=InputPtr (begining of the contents of the input file mapped in memory).
Output
  RDI=pointer is increased by the expanded size.
Called by
  ViewCreate
Depends on
  Macro Time1970.

    ExpandRem: PROC
         PUSH R8,R9
          MOV R8,[InputPtr]                ; Start of input file mapped in memory.
          MOV RSI,R12                      ; Text of the remark.
          TEST RSI
          JZ .0x00:
          AND R13D,0x0FFF_FFFF             ; Get rid of level bits.
    .Dispatched:                           ; Return point from dispatching.
          LODSB
          CMP AL,0
          JE .0x00:                        ; End of remark.
          CMP AL,'!'
          JE .20:
          STOSB                            ; Copy nonescaped bytes from .Rem to RDI.
          JMP .Dispatched:
    .20:  CMPB [RSI],'0'
          JB .25:
          CMPB [RSI],'9'
          JA .25:
          LodD RSI                         ; Load the decimal number following '!'.
          JNC .30:
    .25:  MOV ECX,R13D                     ; If it's missing, use R13 instead.
          TEST ECX
          JZ .0x00:
          MOV EAX,ECX
    .30:  MOV ECX,EAX                      ; ECX=The number|char following ! or !number (VIEW_INDEX.Size).
          CMPB [RSI],'$'                   ; !n$ is not a number of expansion but a fn number.
          JE .60:                          ; Do not load RAX when it's a function from FnTable.
          MOV EAX,[Status::]
          MOV [OldStatus],EAX
    .33:  CMP ECX,16                       ; Do some preparation of registers before dispatching.
          JBE .35:
          MOV ECX,16
    .35:  MOV R11,RCX                      ; Temporary store RCX=R11 the number of loaded bytes from FA.
          MOV EDX,R14D
          XOR R9,R9                        ; Load R9 from the data of viewed file.
          JRCXZ .50:
          ADD RDX,R8
    .40:  MOV AL,[RDX+RCX-1]
          SHL R9,8
          OR R9L,AL
          LOOP .40:
    .50:  MOV RAX,R9                       ; R9=RAX is 0..8 bytes loaded from FA mapped in memory.
          MOV RCX,R11                      ; Restore number of bytes loaded from FA or Fn number.
          MOV EDX,R14D
    .60:  LODSB                            ; The next character after !n
          PUSHQ .Dispatched:               ; Where to continue after dispatching. This enables RET for return from dispatching.
          Dispatch AL,'$','A','B','b','C','D','d','E','F','G','H','h','I','L','M','N','O','P','Q','q', \
                      'R','r','S','s','T','U','X','y','Z',0x00
          STOSB                            ; Nonmatched character store as is.
          RET
    .X:   JRCXZ .X9:                       ; Store the ECX (max.16) bytes of the text dump as ASCII characters.
          PUSH R14                         ; R14 is FA of the line.
    .X1:    MOV AL,[R14+R8]
            CMP AL,0x7F
            JA .X5:
            CMP AL,0x20
            JA .X6:
    .X5:    MOV AL,' '
    .X6:    STOSB
            INC R14
            LOOP .X1:
          POP R14
    .X9:  RET
    .A:   MOV RAX,R9                       ; Low nibble from 2nd character converted to '0'..'F'.
          SHR EAX,8
          AND AL,0x0F
          OR AL,'0'
          CMP AL,':'
          JB .A5:
          ADD AL,'A'-':'
    .A5:  STOSB
          RET
    .C:   MOV RAX,R9                       ; PNG color type.
          PUSH RSI
           Dispatch AL,0n0,0n2,0n3,0n4,0n6
           StoD RDI
          POP RSI
          RET
    .0n0: LEA RSI,[=B'grayscale']
          JMP .M5:
    .0n2: LEA RSI,[=B'truecolor']
          JMP .M5:
    .0n3: LEA RSI,[=B'indexed']
          JMP .M5:
    .0n4: LEA RSI,[=B'grayscale+aplha']
          JMP .M5
    .0n6: LEA RSI,[=B'truecolor+aplha']
          JMP .M5
    .b:   MOVZXW EAX,R9W                   ; 2 bytes as a decimal number in big endian.
          XCHG AH,AL
          StoD RDI
          RET
    .B:   MOVZXW EAX,R9W                   ; 2 bytes as a hexadecimal number in big endian.
          XCHG AH,AL
          StoH RDI,Size=4
          RET
    .D:   MOV RAX,R9                       ; Store RAX decimal.
          StoD RDI
          RET
    .d:   MOV RAX,R9                       ; 4 bytes as a decimal number in big endian.
          BSWAP EAX
          StoD RDI
          RET
    .H:   MOV RAX,R9                       ; Store RAX hexadecimal.
          ADD ECX,ECX
          StoH RDI,Size=RCX
          RET
    .h:   MOV RAX,R9                       ; 4 bytes as a hexadecimal number in big endian.
          ADD ECX,ECX
          BSWAP EAX
          StoH RDI,Size=RCX
          RET
    .E:   PUSH RSI                         ; 4 bytes from FA+0..FA+3 as ASCII (PNG chunk identifier).
           MOV EDX,[RBX+VIEW_INDEX.FA]     ; Store four ASCII characters from FA+4...FA+7.
           LEA RSI,[RDX+R8+4]
           MOV ECX,4
    .E1:   LODSB
           CMP AL,20
           JB .E2:
           CMP AL,128
           JNA .E3:
    .E2:   MOV AL,' '
    .E3:   STOSB
           LOOP .E1:
          POP RSI
          RET
    .F:   MOV RAX,R9                       ; Store EAX as FAR pointer segment:offset hexadecimal.
          StoH RDI,Size=8
          SUB RDI,4
          MOV ECX,[RDI]
          MOV AL,':'
          STOSB
          MOV EAX,ECX
          STOSD
    .F9:  RET
    .N:   MOV RAX,R9                       ; Offset of the name in .shstrtab.
          ADD EAX,[FaOfShstrtabData]
          CMP RAX,[InputSize]
          JNB .F9:
          PUSH RSI
          LEA RSI,[R8+RAX]
          JMP .M5:
    .R:   MOV EAX,[SectionNumber]          ; ELF section number.
          StoD RDI
          INCD [SectionNumber]
          RET
    .r:   MOV EAX,[SymbolNumber]           ; ELF symbol number.
          StoD RDI
          INCD [SymbolNumber]
          RET
    .G:   MOV RAX,R9                       ; ELF file type.
          PUSH RSI
          Dispatch AX,0N1,0N2,0N3
          StoD RDI
          JMP .M8:
    .0N1: LEA RSI,[=B'relocatable, linkable']
          JMP .M5:
    .0N2: LEA RSI,[=B'executable']
          JMP .M5:
    .0N3: LEA RSI,[=B'shared object']
          JMP .M5:
    .U:   MOV RAX,R9                       ; Symbol's section number | type.
          PUSH RSI
           LEA RSI,[=B'absolute']
           CMP AX,0xFFF1
           JE .M5:
           LEA RSI,[=B'common']
           CMP AX,0xFFF2
           JE .M5:
          POP RSI
          MOVB [RDI],'#'
          INC RDI
          StoD RDI
          RET
    .M:   MOV RAX,R9                       ; ELF machine type.
          PUSH RSI
          Dispatch AX,0n03,0n62
          StoD RDI
          JMP .M8:
    .0n03:LEA RSI,[=B'I386']
          JMP .M5:
    .0n62:LEA RSI,[=B'AMD64']
    .M5:  LODSB
          CMP AL,0
          JE .M8:
          STOSB
          JMP .M5:
    .M8:  POP RSI
          RET
    .Z:   PUSH RSI                         ; ELF relocation type.
          MOV AL,R9L
          Dispatch AL,00,01,02,05,06,07,08,10
          PUSH RAX
           MOV EAX,'Type'
           STOSD
           MOV AL,' '
           STOSB
          POP RAX
          StoD
          POP RSI
          RET
    .01:  LEA RSI,[=B'Absolute QWORD']
          JSt [Status::],ArgWidth64,.M5:
          LEA RSI,[=B'Absolute DWORD']
          JMP .M5:
    .02:  LEA RSI,[=B'Relative DWORD']
          JMP .M5:
    .08:  LEA RSI,[=B'Relative QWORD']
          JSt [Status::],ArgWidth64,.M5:
          JMP .02:
    .10:  LEA RSI,[=B'Absolute DWORD']
          JSt [Status::],ArgWidth64,.M5:
          LEA RSI,[=B'GOTPC DWORD']
          JMP .M5:
    .00:
    .05:  LEA RSI,[=B'Copy']
          JMP .M5:
    .06:
    .07:  LEA RSI,[=B'JMP_SLOT']
          JMP .M5:
    .P:   MOV RAX,R9                       ; ELF "program" type.
          PUSH RSI
          Dispatch EAX,0d,1d,2d,3d,4d,6d
          JMP .M8:
    .0d:  LEA RSI,[=B'null']
          JMP .P5:
    .1d:  LEA RSI,[=B'load']
          JMP .P5:
    .2d:  LEA RSI,[=B'dynamic']
          JMP .P5:
    .3d:  LEA RSI,[=B'interpreter']
          JMP .P5:
    .4d:  LEA RSI,[=B'note']
          JMP .P5:
    .6d:  LEA RSI,[=B'program header']
          ;JMP .P5:
    .P5:  JMP .M5:
    .S:   PUSH RSI                         ; ELF section type.
          PUSH RDI
          LEA RDI,[ElfSegmentTypes]
          XOR EAX,EAX
          MOV ECX,-1
    .S2:  CMP R9L,0
          JBE .S3:
          DEC R9D
          REPNE SCASB
          JMP .S2:
    .S3:  MOV RSI,RDI
          POP RDI
          JMP .M5:
    .s:   PUSH RSI                         ; ELF symbol info.
          MOV AL,R9L
          SHR AL,4
          LEA RSI,[=B'Global ']
          CMP AL,1
          JE .s2:
          LEA RSI,[=B'Weak ']
          CMP AL,2
          JE .s2:
          LEA RSI,[=B'Local ']
    .s2:  LODSB
          CMP AL,0
          JE .s3:
          STOSB
          JMP .s2:
    .s3:  MOV AL,R9L
          AND AL,0x0F
          LEA RSI,[=B'dataobject']
          CMP AL,1
          JE .M5:
          LEA RSI,[=B'function']
          CMP AL,2
          JE .M5:
          LEA RSI,[=B'section']
          CMP AL,3
          JE .M5:
          LEA RSI,[=B'file']
          CMP AL,4
          JE .M5:
          LEA RSI,[=B'pointer']
          JMP .M5:
    .Q:   TEST R9L,4                       ; ELF program flags.
          JZ .Q2:
          MOV EAX,'read'
          STOSD
          MOV AL,'|'
          STOSB
    .Q2:  TEST R9L,2
          JZ .Q3:
          MOV EAX,'writ'
          STOSD
          MOV AX,'e|'
          STOSW
    .Q3:  TEST R9L,1
          JZ .Q4:
          MOV EAX,'exec'
          STOSD
          MOV EAX,'ute|'
          STOSD
    .Q4:  DEC RDI                          ; Rollback the final '|'.
          RET
    .q:   CMP R9L,0                        ; ELF section flags.
          JNE .q1:
          MOV EAX,'none'
          STOSD
          RET
    .q1:  TEST R9L,2
          JZ .q2:
          MOV EAX,'read'
          STOSD
          MOV AL,'|'
          STOSB
    .q2:  TEST R9L,1
          JZ .q3:
          MOV EAX,'writ'
          STOSD
          MOV AX,'e|'
          STOSW
    .q3:  TEST R9L,4
          JZ .q4:
          MOV EAX,'exec'
          STOSD
          MOV EAX,'ute|'
          STOSD
    .q4:  DEC RDI
          RET
    .y:   PUSH RSI                         ; ELF32 dynamic.
          MOV EAX,R9D
          CMP EAX,0x6FFF_FFFA
          LEA RSI,[=B'RELCOUNT (number of REL)']
          JE .y3:
          CMP EAX,0x6FFF_FFF9
          LEA RSI,[=B'RELACOUNT (number of RELA)']
          JE .y3:
          CMP EAX,0x6FFF_FFFB
          LEA RSI,[=B'FLAGS_1']
          JE .y3:
          CMP EAX,0x6FFF_FEF5
          LEA RSI,[=B'GNU_HASH']
          JE .y3:
          CMP EAX,31
          JAE .y4:
          MOV EDX,EAX
          MOV RCX,-1
          XOR EAX,EAX
          PUSH RDI
            LEA RDI,[ElfDynamic::]
    .y1:    TEST EDX
            JZ .y2:
            REPNE SCASB
            DEC EDX
            JMP .y1:
    .y2:    MOV RSI,RDI
          POP RDI
    .y3:  LODSB
          CMP AL,0
          JE .y5:
          STOSB
          JMP .y3:
    .y4:  MOVD [RDI],'Tag '
          ADD RDI,4
          StoH RDI,Size=8
          MOV AL,'h'
          STOSB
    .y5:  MOV AX,': '
          STOSW
          JSt [Status::],ArgWidth64,.y6:
          MOV RAX,R9
          SHR RAX,32
          StoH RDI,Size=8
          JMP .y7:
    .y6:  MOV EDX,[RBX+VIEW_INDEX.FA]
          MOV RAX,[R8+RDX+8]
          StoH RDI,Size=16
    .y7:  MOV AX,'h='
          STOSW
          JSt [Status::],ArgWidth64,.y8:
          MOV RAX,R9
          SHR RAX,32
          JMP .y9:
    .y8:  MOV EDX,[RBX+VIEW_INDEX.FA]
          MOV RAX,[R8+RDX+8]
    .y9:  StoD
          POP RSI
          RET
    .T:   MOV RAX,R9                       ; Store datetime as yyyy/mm/dd hh:mm:ss.
    .T1:  Time1970 RAX,RDI                 ; Use macro from time.htm.
          ADD RDI,19
          RET
    .L:   PUSH RSI
            LEA RSI,[R8+RDX]
            LodD
          POP RSI
          JMP .T1:
    .I:   MOV RAX,R9                       ; LIBCOF import type.
          SHR EAX,2
          PUSH RSI
            LEA RSI,[=B'BY_ORDINAL']
            CMP AL,0
            JE .I5:
            LEA RSI,[=B'Import name=public name']
            CMP AL,1
            JE .I5:
            LEA RSI,[=B'Import name=public name without prefix']
            CMP AL,2
            JE .I5:
            LEA RSI,[=B'Import name=public name undecorated']
            CMP AL,3
            JNE .I8:
    .I5:    LODSB
            CMP AL,0
            JE .I8:
            STOSB
            JMP .I5:
    .I8:  POP RSI
          RET
    .O:   PUSH RSI                         ; OMF record type.
          MOV RAX,R9
          Dispatch AL,0F0h,0F1h
          SHR EAX,1
          Dispatch AL,40h,41h,44h,45h,46h,47h,48h,4Ah,4Bh,4Ch,4Dh,4Eh, \
                      50h,51h,58h,59h,5Ah,5Bh,5Ch,5Eh,61h,62h,63h,64h,65h
          MOVZXB EAX,R9L                   ; Restore AL with record name and
          StoH,Size=2                      ;  display it as hexadecimal byte,
          MOV AL,'h'                       ;  when it was unrecognized.
          STOSB
          POP RSI
          RET
    .40h: LEA RSI,[=B'THEADR']
          JMP .O2:
    .41h: LEA RSI,[=B'LHEADR']
          JMP .O2:
    .44h: LEA RSI,[=B'COMENT']
          JMP .O2:
    .45h: LEA RSI,[=B'MODEND']
          JMP .O2:
    .46h: LEA RSI,[=B'EXTDEF']
          JMP .O2:
    .47h: LEA RSI,[=B'TYPDEF']
          JMP .O2:
    .48h: LEA RSI,[=B'PUBDEF']
          JMP .O2:
    .4Ah: LEA RSI,[=B'LINNUM']
          JMP .O2:
    .4Bh: LEA RSI,[=B'LNAMES']
          JMP .O2:
    .4Ch: LEA RSI,[=B'SEGDEF']
          JMP .O2:
    .4Dh: LEA RSI,[=B'GRPDEF']
          JMP .O2:
    .4Eh: LEA RSI,[=B'FIXUPP']
          JMP .O2:
    .50h: LEA RSI,[=B'LEDATA']
          JMP .O2:
    .51h: LEA RSI,[=B'LIDATA']
          JMP .O2:
    .58h: LEA RSI,[=B'COMDEF']
          JMP .O2:
    .59h: LEA RSI,[=B'BAKPAT']
          JMP .O2:
    .5Ah: LEA RSI,[=B'LEXTDEF']
          JMP .O2:
    .5Bh: LEA RSI,[=B'LPUBDEF']
          JMP .O2:
    .5Ch: LEA RSI,[=B'LCOMDEF']
          JMP .O2:
    .5Eh: LEA RSI,[=B'CEXTDEF']
          JMP .O2:
    .61h: LEA RSI,[=B'COMDAT']
          JMP .O2:
    .62h: LEA RSI,[=B'LINSYM']
          JMP .O2:
    .63h: LEA RSI,[=B'ALIAS']
          JMP .O2:
    .64h: LEA RSI,[=B'NBKPAT']
          JMP .O2:
    .65h: LEA RSI,[=B'LLNAMES']
          JMP .O2:
    .0F0h:LEA RSI,[=B'LIBHDR']
          JMP .O2:
    .0F1h:LEA RSI,[=B'LIBEND']
          ;JMP .O2:
    .O2:  LODSB
          CMP AL,0
          JE .O3:
          STOSB
          JMP .O2:
    .O3:  TEST R9L,1
          JZ .O9:
          MOV AX,'32'
          STOSW
    .O9:  POP RSI
          RET
    .$:   MOV RAX,[8*RCX+FnTable]          ; RCX is nn number in !nn$ escape code. Call the function from FnTable.
          MOV RCX,R9
          PUSH RSI
            CALL RAX
          POP RSI
          RET
    .0x00:MOV EAX,0x0A0D
          STOSD
         POP R9,R8
         RET
       ENDP ExpandRem

IndexUpdate
  Updates records with indexes in FileIndex mapped in memory, depending on CodeBegin+CodeEnd and|or DataBegin+DataEnd.
  The last four records have .Size=0 and may be rewritten.

  1. 1. first record.
  2. ...
  3. n. n-th record, the last.
  4. E. record End with 0-size.
  5. C1.record Code for inserted code block.
  6. C2.Code duplicate in case of code block is overlapped by a record.
  7. D1.record Data for inserted data block.
  8. D2.Data duplicate in case of data block is overlapped by a record.
Input
  [Status::]Flag ArgUpdateCode is set when (ArgCodeEnd-ArgCodeBegin)>0. The code block should be disassembled. This procedure IndexUpdate is called again with flag ArgUpdateCode reset when (ArgDataEnd-ArgDataBegin)>0. This data block will not be disassembled.
  IndexPtr..IndexEnd address of the array of VIEW_INDEX n records plus five additionals, sorted by level+size.
  RAX FA of the updated block begin.
  RCX FA of the updated block end.
Output
  The array of VIEW_INDEX records at RDI,RAX is updated. Its size is not changed.
Called by
  ViewCreate

    IndexUpdate PROC
        MOV RDI,[IndexPtr]                 ; Pointer to the array of VIEW_INDEXEs.
        MOV RDX,[IndexEnd]                 ; End of the array.
        JSt [Status::],ArgUpdateCode::,.10:
        LEA RBX,[RDX-2*SIZE# VIEW_INDEX]   ; RBX=address of Record D1.
        LEA RSI,[="!X"]                    ; !V tells to disassemble; !X tells to dump as data.
        JMP .15:
    .10:LEA RBX,[RDX-4*SIZE# VIEW_INDEX]   ; RBX=address of Record C1.
        LEA RSI,[="!V"]                    ; !V tells to disassemble; !X tells to dump as data.
    .15:CMP RBX,RDI
        JBE .80:
        MOV [RBX+VIEW_INDEX.FA],EAX
        SUB ECX,EAX
        AND ECX,0x0FFF_FFFF                ; Size must not overlap level bits 28..31.
        MOV [RBX+VIEW_INDEX.Size],ECX      ; RBX points at record C1 or D1.
        MOV [RBX+VIEW_INDEX.Rem],RSI       ; Record C1 will be disassembled.
        LEA EDX,[EAX+ECX]                  ; FA of end of the C1|D1 record (CodeEnd or DataEnd).

    .20:; Find a record which overlaps CodeBegin|DataBegin (its End is not below CodeBegin|DataBegin).
        MOV EAX,[RDI+VIEW_INDEX.Size]      ; Start with record RDI.
        TEST EAX,LevelMask
        JZ .25:                            ; Skip colorful records.
    .22:ADD RDI,SIZE# VIEW_INDEX           ; The next record.
        CMP RDI,[IndexEnd::]
        JNB .80:
        JMP .20:
    .25:ADD EAX,[RDI+VIEW_INDEX.FA]        ; EAX=End of level0 record RDI.
        CMP EAX,[RBX+VIEW_INDEX.FA]        ; Compare end of this record RDI with FA of CodeBegin|DataBegin.
        JB .22:                            ; Leave this record RDI unchanged if below. Try the next record.

        ; Found record RDI whose end is above  CodeBegin|DataBegin. Make this record shorter.
        MOV R11,RDI                        ; Remember position of the soon-to-be-shorten record in R11.
        MOV R12,[RDI+VIEW_INDEX.Rem]       ; Remember Remark of the soon-to-be-shorten record in R12.
        MOV R13D,[RDI+VIEW_INDEX.FA]       ; Remember FA of the soon-to-be-shorten record in R13.
        MOV R14D,[RDI+VIEW_INDEX.Size]     ; Remember Size of the soon-to-be-shorten record in R14.
        ADD R14D,R13D                      ; Let R14 be FA of the End.
        MOV EAX,[RBX+VIEW_INDEX.FA]        ; CodeBegin|DataBegin.
        SUB EAX,R13D
        MOV [RDI+VIEW_INDEX.Size],EAX      ; Shorten this record RDI.
    .30: ; Find a record, starting with RDI, whose FA was below EDX=CodeEnd|DataEnd and whose End was above EDX=CodeEnd|DataEnd.
        CMP R13D,EDX
        JNB .50:
        CMP R14D,EDX
        JNA .50:
        ; CodeBegin..End overlaps the same record RDI which was shortened. Make a copy of shortened record RDI to position C2.
        MOV RDI,[IndexEnd::]
        SUB RDI,3*SIZE# VIEW_INDEX
        MOV [RDI+VIEW_INDEX.Rem],R12
        MOV [RDI+VIEW_INDEX.FA],EDX
        SUB R14D,EDX
        MOV [RDI+VIEW_INDEX.Size],R14D
        JMP .80:                           ; Other records are unchanged.

    .40:MOVD [RDI+VIEW_INDEX.Size],0       ; Invalidate record RDI.
        XOR EAX,EAX
        MOV [RDI+VIEW_INDEX.FA],EAX
        MOV [RDI+VIEW_INDEX.Rem],RAX
    .50:ADD RDI,SIZE# VIEW_INDEX           ; Try the next record.
        CMP RDI,[IndexEnd::]
        JNB .80:
        MOV EAX,[RDI+VIEW_INDEX.Size]
        TEST EAX,LevelMask
        JNZ .50:                           ; Skip colorful records.

        ADD EAX,[RDI+VIEW_INDEX.FA]        ; EAX is End of record RDI.
        SUB EAX,EDX
        JB .40:
        MOV [RDI+VIEW_INDEX.FA],EDX
        MOV [RDI+VIEW_INDEX.Size],EAX
    .80:                                   ; Other records are unchanged.
        RET
     ENDP IndexUpdate

ViewCreate

  The input file loaded to memory and mapped between [InputPtr]..[InputEnd] is analyzed by one of Format*** procedures (its address is stored in [FormatProcPtr]).
  In Phase One this OS-independent procedure converts the input to VIEW_INDEX structures, which will be written to FileIndex using `CALL SaveViewIndex::`.
  SaveViewIndex:: is a global procedure defined in modules for Windows or for Linux.

  FileIndex it then reopend and sorted by file address.

  In Phase Two the procedure ViewCreate uses the sorted indexes to generate an output listing in OutputFile (plain text).

  Caller of this procedure then calls ViewEpilogue for Windows or Linux which should close+reopen IndexFile and OutputFile again.

Input
  R15= number of address bytes 4..12 displayed in listing as FA, depending on the input file size.
  ArgInputFile, ArgOutputFile, ArgFileFormat.
  FileOutput and FileIndex are created and memory-mapped to OutputPtr..OutputEnd and IndexPtr..IndexEnd.
Called by
  WndProc
Calls
  [FormatProcPtr], ExpandRem, Disasm

    ViewCreate:: PROC
        MOV EDX,[ArgFileFormat::]          ; Nonzero ordinal.
    ff  %FOR %FileFormats                  ; Enumeration declared in argument.htm.
         LEA RAX,[Format%ff]
         CMP EDX,ArgFileFormat%ff
         JE .01:
        %ENDFOR ff
        LEA RAX,[FormatBIN]
    .01:MOV [FormatProcPtr],RAX
        MOV ECX,[ArgCodeWidth::]           ; Explicitly specified width for disassembly. Zero to autodetect.
        TEST ECX                           ; If ArgCodeWidth=0, adopt the width from Status:ArgWidthXX.
        JNZ .02:                           ; Otherwise leave ArgCodeWith as specified.
        MOV ECX,[Status::]                 ; Use autodetected width, if any.
        AND ECX,ArgWidthMask::
        SHR ECX,16                         ; ECX=0|16|32|64.
        JNZ .02:
        MOV CL,16                          ; Default if not specified.
    .02:MOV [ArgCodeWidth::],ECX           ; Specify code with 16|32|64 for disassembly.
        ; Phase One begins. Create FileIndex with VIEW_INDEX records.
        MOV R8,[InputPtr]                  ; Start of input file loaded in memory.
        CALL [FormatProcPtr]               ; Call FormatMZ, FormatCOFF32 etc. to write the index file. Set width to Status::.
    .04:LEA RBX,[ViewIndex]                ; Add one padding record at the end of VIEW_INDEX array
        MOV [RBX+VIEW_INDEX.Rem],=B'!X'    ; Store one record for the case of alignment bytes at the end of input file.
        MOV EAX,[InputSize]                ; Size of the viewed file.
        MOV [RBX+VIEW_INDEX.FA],EAX
        MOV [RBX+VIEW_INDEX.Size],0
        CALL SaveViewIndex::               ; E: One more record to terminate the dump.
        CALL SaveViewIndex::               ; C1:One more record reserved for the case of nonzero CodeSize.
        CALL SaveViewIndex::               ; C2:One more record reserved for duplication of long override by Code.
        CALL SaveViewIndex::               ; D1:One more record reserved for the case of nonzero DataSize.
        CALL SaveViewIndex::               ; D2:One more record reserved for duplication of long override by Data.
        CALL [FileIndexReopenProc]         ; Procedure from viewwing.htm or from viewling.htm. Returns the contents in RDI,RAX.
        MOV [IndexPtr],RDI                 ; Beginning of array of indexes VIEW_INDEX.
        LEA RCX,[RDI+RAX]                  ; End of the array.
        MOV [IndexEnd],RCX
        SHR EAX,4                          ; SIZE# VIEW_INDEX=16. RAX is now the number of indexes.
        ShellSort RDI,RAX,16,ByLevel       ; Sorting indexes by level and file address.
        MOV RAX,[InputSize]
        MOV ECX,[ArgCodeEnd::]
        CMP ECX,EAX
        JBE .05:
        MOV ECX,EAX                        ; FA of end of code must not exceed file size.
        MOV [ArgCodeEnd::],ECX
    .05:MOV EAX,[ArgCodeBegin::]
        CMP ECX,EAX
        JNA .06:
        SetSt [Status::],ArgUpdateCode::   ; Update code, not data.
        CALL IndexUpdate
        CALL [FileIndexReopenProc]         ; Procedure from viewwing.htm or from viewling.htm. Returns the contents in RDI,RAX.
        MOV EAX,[IndexEnd]
        SUB EAX,[IndexPtr]
        SHR EAX,4                          ; SIZE# VIEW_INDEX=16. RAX is now the number of indexes.
        ShellSort RDI,RAX,16,ByLevel       ; Sorting indexes by level and file address.
    .06:MOV RAX,[InputSize]
        MOV ECX,[ArgDataEnd::]
        CMP ECX,EAX
        JBE .07:
        MOV ECX,EAX                        ; FA of end of data must not exceed file size.
        MOV [ArgDataEnd::],ECX
    .07:MOV EAX,[ArgDataBegin::]
        CMP ECX,EAX
        JNA .08:
        RstSt [Status::],ArgUpdateCode::   ; Update data, not code.
        CALL IndexUpdate
        CALL [FileIndexReopenProc]         ; Procedure from viewwing.htm or from viewling.htm. Returns the contents in RDI,RAX.
        MOV EAX,[IndexEnd]
        SUB EAX,[IndexPtr]
        SHR EAX,4                          ; SIZE# VIEW_INDEX=16. RAX is now the number of indexes.
        ShellSort RDI,RAX,16,ByLevel       ; Sorting indexes by level and file address.
    .08:MOV RBX,RDI                        ; Pointer to an array of VIEW_INDEXes is now in RBX. Array ends at [IndexEnd].

    .10:; Phase Two. Convert each VIEW_INDEX record RBX to a listing line(s) and write it to the listing in FileOutput.
        MOV R15D,[AddressDigits]           ; R15=number of address bytes 4..15.
        CMP RBX,[IndexEnd]
        JNB .90:                           ; Jump when all VIEW_INDEX are converted.
        ; Look at the previous VIEW_INDEX if there's a gap.
        LEA RDI,[RBX-SIZE# VIEW_INDEX]     ; RDI=Previous index.
        CMP RDI,[IndexPtr]
        JB  .50:                           ; Skip at the beginning of VIEW_INDEX block.
        MOV EDX,[RDI+VIEW_INDEX.Size]
        AND EDX,0x3FFF_FFFF                ; Size of previous object.
        ADD EDX,[RDI+VIEW_INDEX.FA]        ; EDX=FA of the end of the previous object.
        MOV ECX,[RBX+VIEW_INDEX.FA]        ; ECX=FA of the beginning of this object RBX.
        SUB ECX,EDX
        JBE .50:                           ; No gap between VIEW_INDEXes.
        ; There is a gap of ECX bytes of unassigned alignment between objects. Create listing lines for them with Rem="Alignment".
        MOV R13,RCX                        ; Amount of alignment bytes (at least 1, may be > 16).
        MOV R14,RDX                        ; FA of alignment bytes.
    .12:TEST R13
        JZ .50:
        LEA RDI,[WorkMemory]               ; Print |FileAddress:max_16_bytes_of_code  |
        MOV AL,'|'
        STOSB
        MOV RAX,R14
        StoH RDI,Size=R15                  ; File address.
        MOV AL,':'
        STOSB
        XOR EAX,EAX
        XOR EDX,EDX
        MOV R8,[InputPtr]
        LEA RSI,[R8+R14]
        MOV RCX,R13                        ; How many alignment bytes is left.
        CMP ECX,16
        JBE .15:                           ; Jump to the last incomplete line.
        MOV ECX,16                         ; Otherwise display 16 bytes.
    .15:JRCXZ .22:                         ; Display ECX=max 16 bytes of code at RSI.
    .18:TEST DL,0000_0011b
        JNZ .21:
        TEST EDX
        JZ .21:
        MOV AL,' '
        STOSB                              ; Insert space every 4-th byte.
    .21:LODSB
        StoH RDI,Size=2
        INC EDX
        LOOP .18:
    .22:LEA RCX,[WorkMemory+37]            ; Fixed end of hexadecimal data.
        ADD RCX,R15                        ; Respect the variable number of address digits in R15.
        SUB RCX,RDI
        JNA .24:
        MOV AL,' '
        REP STOSB
    .24:MOV AX,'| '                        ; End of dump column.
        STOSW
        LEA RSI,[R8+R14]                   ; Address of data again.
        MOV RCX,R13                        ; Size of data.
        CMP ECX,16                         ; Number of alignment bytes, may be > 16.
        JB .30:                            ; Jump if the last <16 alignment line.
        MOV ECX,4                          ; Otherwise display as four DD.
        MOV AX,'DD'
        STOSW
        MOV AL,' '
        STOSB
    .27:MOV AX,'0x'
        STOSW
        MOV DL,[RSI+3]
        CALL StoDL
        MOV DL,[RSI+2]
        CALL StoDL
        MOV DL,[RSI+1]
        CALL StoDL
        MOV DL,[RSI+0]
        CALL StoDL
        MOV AL,','
        STOSB
        ADD RSI,4
        LOOP .27:
        DEC RDI                            ; Omit the last comma.
        JMP .40:                           ; Go to print " ; Alignment."
    .30: ; The last alignment line, ECX<16
        MOV AX,'DB'
        STOSW
        MOV AL,' '
        STOSB
    .33:MOV AX,'0x'
        STOSW
        MOV DL,[RSI+0]
        CALL StoDL
        MOV AL,','
        STOSB
        INC RSI
        LOOP .33:
        DEC RDI                             ; Omit the last comma.
    .40:LEA RSI,[=B' ; Alignment.']
    .43:LODSB
        CMP AL,0
        JE .46:
        STOSB
        JMP .43:
    .46:MOV EAX,0x0A0D
        STOSD
        LEA RSI,[WorkMemory]
        GetLength$ RSI                     ; Get the size of the entire line to RCX.
        CALL [FileWriteOutputProc]         ; Call the procedure from viewwing.htm or from viewling.htm.
        MOV RCX,R13
        CMP ECX,16
        JBE .49:
        MOV ECX,16
    .49:ADD R14,RCX
        SUB R13,RCX
        JMP .12:

    .50:; There is no gap. Continue.
        MOV R15D,[AddressDigits]           ; 4..12 depending on the input file size.
        MOV R14D,[RBX+VIEW_INDEX.FA]
        MOV R13D,[RBX+VIEW_INDEX.Size]
        MOV EDX,R13D
        SHR EDX,28                         ; EDX=level 0..4.
        JZ .Level0:

        ; VIEW_INDEX at RBX represents a colourful LevelX line (X=1,2,3,4).
        LEA RDI,[WorkMemory]               ; Listing line will be constructed in WorkMemory.
        MOV AL,'|'                         ; The first character in each listing line.
        STOSB
        MOV AL,'#'                         ; # is the level marker.
        MOV ECX,EDX
        REP STOSB
        NEG RDX
        LEA RCX,[RDX+13]                   ; Let ECX=number of separating spaces in the colourful listing line.
        MOV AL,' '
        REP STOSB
        MOV EAX,R14D                       ; VIEW_INDEX.FA
        StoH RDI,Size=R15                  ; Store file-address range.
        MOV AX,'..'
        STOSW
        MOV ECX,0x0FFF_FFFF                ; VIEW_INDEX.Size mask.
        AND ECX,R13D
        LEA RAX,[R14+RCX-1]
        StoH RDI,Size=R15
        MOV AL,' '
        STOSB
        LEA RCX,[R15+WorkMemory+38]        ; Fixed position in the line where the remark begins.
        SUB RCX,RDI
        JNA .56:
        CMP ECX,64
        JA .90:
        MOV AL,'#'
        REP STOSB                          ; Fill the gap with variable number of #.
        MOV AL,' '
        STOSB
        MOV ESI,[RBX+VIEW_INDEX.Rem]
        PUSH RSI,RDI                       ; A hack for ELF section contents.
          LEA RDI,[=B'Contents of section #']
          MOV ECX,21
          REPE CMPSB
          JNE .53:
          MOVD [SymbolNumber::],0          ; Clear the symbol number counter when a new section begins.
    .53:POP RDI,RSI
    .56:MOV R12,[RBX+VIEW_INDEX.Rem]
        CALL ExpandRem:                    ; Expand !-escaped parameters, add CR+LF+NULL.
        LEA RSI,[WorkMemory]
        GetLength$ RSI
        CALL [FileWriteOutputProc]         ; Call the procedure from viewwing.htm or from viewling.htm.
        ADD RBX,SIZE# VIEW_INDEX
        JMP .10:                           ; The next listing line.

    .Level0:                               ; RBX=^VIEW_INDEX which represents a gray Level0 line(s),
        MOV R12,[RBX+VIEW_INDEX.Rem]       ; R12=Pointer to the remark.
        MOV R13D,[RBX+VIEW_INDEX.Size]     ; R13=Size of the element. Perhaps more Level0 lines when R13=RBX+VIEW_INDEX.Size is above 16.
        MOV R14D,[RBX+VIEW_INDEX.FA]       ; R14=File address of the element.
        TEST R13                           ; R15=[AddressDigits] 4..12 depending on the input file size.
        JZ .86:
        CMPW [R12],'!V'                    ; VIEW_INDEX.Rem="!V" is expanded here instead of in ExpandRem.
        JE .59:
        CMPW [R12],'!v'                    ; Disassemble 16-bit format MZ?
        JNE .65:
        MOV EDX,[ArgCodeWidth::]
        PUSH RDX
          MOVD [ArgCodeWidth::],16
          CALL Disasm::
        POP RDX
        MOV [ArgCodeWidth::],EDX
        JMP .62:
    .59:CALL Disasm::
    .62:ADD RBX,SIZE# VIEW_INDEX
        JMP .10:

    .65:LEA RDI,[WorkMemory]               ; Print |file_address: from R14 at the beginning of WorkMemory.
        MOV AL,'|'
        STOSB
        MOV RAX,R14
        StoH RDI,Size=R15
        MOV AL,':'
        STOSB
        XOR EAX,EAX                        ; Print hexa dump of max.16 bytes at FA R14.
        XOR EDX,EDX
        MOV R8,[InputPtr]
        LEA RSI,[R8+R14]
        MOV ECX,R13D
        CMP ECX,16                         ; Number of displayed hexadecimal bytes.
        JBE .68:
        MOV ECX,16
    .68:JRCXZ .78:
    .71:TEST DL,0000_0011b
        JNZ .74:
        TEST EDX
        JZ .74:
        MOV AL,' '
        STOSB                              ; Insert a space after each four hexa bytes.
    .74:LODSB
        StoH RDI,Size=2
        INC EDX
        LOOP .71:
    .78:LEA RCX,[WorkMemory+37]            ; Fixed address of the end of hexadecimal data in dump column.
        ADD RCX,R15                        ; Respect the variable number of address digits in R15.
        SUB RCX,RDI
        JNA .80:
        MOV AL,' '
        REP STOSB                          ; Padding.
    .80:MOV AX,'| '
        STOSW                              ; Terminate the dump column.
        CALL ViewDataCreate                ; Print 'DB 0x11 '  or 'DD 0x11223344 ' etc.
        MOV AX,'; '
        STOSW                              ; The remark will be printed as line comment.
        CALL ExpandRem                     ; Print the remark, if any, with expanded !variables.
        LEA RSI,[WorkMemory]
        GetLength$ RSI                     ; Get the size of the entire line in WorkMemory to RCX.
        CALL [FileWriteOutputProc]         ; Call the procedure from viewwing.htm or from viewling.htm.
        MOV ECX,R13D
        JRCXZ .86:
        CMP ECX,16
        JBE .83:
        MOV ECX,16
    .83:ADD R14,RCX
        SUB R13,RCX
        JNZ .65:
    .86:ADD RBX,SIZE# VIEW_INDEX            ; The next element.
        JMP .10:
    .90:RET
      ENDP ViewCreate

ViewDataCreate

  Display the disassembled data as D statement depending on their size.

  Data size | Disassemble as
  --- | ---
  1 | DB 0x11 ; Expanded Rem
  2 | DW 0x2211 ; Expanded Rem
  3 | DB 0x11,0x22,0x33 ; Expanded Rem
  4 | DD 0x44332211 ; Expanded Rem
  5..7 | DB 0x11,0x22,0x33,0x44,0x55,0x66,0x77 ; Expanded Rem
  8 | DD 0x44332211,0x88776655 ; Expanded Rem
  9..15 | DB 0x11,0x22,0x33...0xFF ; Expanded Rem
  16 | DD 0x44332211,0x88776655,0xCCBBAA99,0x00FFEEDD ; Expanded Rem

Input
  RDI=pointer to the output where are the disassembled data expanded.
  R8=InputPtr (begining of the contents of the input file mapped in memory),
  R13=size of the data,
  R14=file address of the data.
Output
  RDI=increased.
Called by
  ViewCreate
Clobbers

    ViewDataCreate PROC
        MOV AL,'D'
        STOSB
        MOV ECX,R13D
        CMP ECX,16
        JBE .10:
        MOV ECX,16
    .10:MOV AL,'D'
        CMP CL,16
        JE .20:
        CMP CL,8
        JE .20:
        CMP CL,4
        JE .20:
        MOV AL,'W'
        CMP CL,2
        JE .20:
        MOV AL,'B'
    .20:STOSB
        MOV DH,AL                ; Remember 'B','W' or 'D'.
        MOV AL,' '
        STOSB
    .30:LEA RSI,[R8+R14]         ; ECX is 1..16.
        Dispatch DH,'B','W','D'
        JMP .99:
    .B: MOV AX,'0x'
        STOSW
        MOV DL,[RSI+0]
        CALL StoDL::
        MOV AL,','
        STOSB
        INC RSI
        SUB ECX,1
        JA .B:
        JMP .90:
    .W: MOV AX,'0x'
        STOSW
        MOV DL,[RSI+1]
        CALL StoDL::
        MOV DL,[RSI+0]
        CALL StoDL::
        MOV AL,','
        STOSB
        JMP .90:
    .D: MOV AX,'0x'
        STOSW
        MOV DL,[RSI+3]
        CALL StoDL::
        MOV DL,[RSI+2]
        CALL StoDL::
        MOV DL,[RSI+1]
        CALL StoDL::
        MOV DL,[RSI+0]
        CALL StoDL::
        MOV AL,','
        STOSB
        ADD RSI,4
        SUB CL,4
        JA .D:
        ; JMP .90:
    .90:
        DEC RDI                  ; Erase the last comma.
        MOV EAX,'    '
        CMP DH,'W'
        JNE .95:
        STOSD
    .95:STOSB
    .99:RET
      ENDP ViewDataCreate

↑ FormatBIN

  Undetected binary file format which EuroView does not know. It will be displayed as hexadecimal dump.

Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    FormatBIN:: PROC
        MOV [RBX+VIEW_INDEX.Rem],=B'Format BIN "!14$" size=!24$ !25$'
        MOV [RBX+VIEW_INDEX.FA],0
        MOV RCX,[InputSize::]
        OR ECX,Level4
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'!X'
        CALL SaveViewIndex::
        RET
      ENDP FormatBIN

↑ FormatBMP

  Image file format.

Extension
  .bmp
Documentation
  BMP file format
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    FormatBMP  PROC
        MOV [RBX+VIEW_INDEX.Rem],=B'Format BMP "!14$" size=!24$ !25$'
        MOV [RBX+VIEW_INDEX.FA],0
        MOV RCX,[InputSize::]
        OR ECX,Level4
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"BMP file header"
        MOV [RBX+VIEW_INDEX.Size],14+Level2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Signature !2X"
        MOV [RBX+VIEW_INDEX.Size],2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Size of the file: !4Hh=!4D"
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Application specific data"
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"FA of bitmap data: !4Hh=!4D"
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOV EAX,[R8+RDX]
        SUB EAX,36h
        JB .20:
        MOV [PaletteSize],EAX
    .20:CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"DIB header"
        MOV [RBX+VIEW_INDEX.Size],4+Level2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Size of DIB header:!4Hh=!4D"
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Width:  !4Hh=!4D px"
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Height: !4Hh=!4D px"
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Number of color planes: !2D"
        MOV [RBX+VIEW_INDEX.Size],2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Number of bits per pixel: !2D"
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Compression: !4D"
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Size of data: !4Hh=!4D"
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Horizontal print resolution: !4Hh=!4D px/m"
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Vertical print resolution: !4Hh=!4D px/m"
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Number of colors in the palette: !4D"
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Important colors (0=all): !4D"
        CALL SaveViewIndex::
        MOV ECX,[PaletteSize]
        JRCXZ .50:
        MOV [RBX+VIEW_INDEX.Rem],=B"Palette"
        OR ECX,Level2
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        CALL SaveViewIndex::
    .50:MOV [RBX+VIEW_INDEX.Rem],=B"Bitmap data"
        MOV RCX,[InputSize::]
        SUB ECX,[PaletteSize]
        ADD ECX,Level1-36h
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        CALL SaveViewIndex::
        RET
      ENDP FormatBMP

↑ FormatCUR

  Cursor file format.

Extension
  .cur
Documentation
  CUR (file format)
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    FormatCUR  PROC
        MOV [RBX+VIEW_INDEX.Rem],=B'Format CUR "!14$" size=!24$ !25$'
        MOV [RBX+VIEW_INDEX.FA],0
        MOV RCX,[InputSize::]
        OR ECX,Level4
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Icon directory"
        MOV [RBX+VIEW_INDEX.Size],6+Level3
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Cursor file signature"
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Number of images: !2D"
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOVZXW ECX,[R8+RDX]
        MOV [RBX+VIEW_INDEX.Size],2
        CALL SaveViewIndex::
        TEST RCX
        JZ .90:
    .30:PUSH RCX
         MOV [RBX+VIEW_INDEX.Rem],=B"Image #!18$"
         MOV [RBX+VIEW_INDEX.Size],16+Level2
         CALL SaveViewIndex::
         MOV [RBX+VIEW_INDEX.Rem],=B"Image width: !1D"
         MOV [RBX+VIEW_INDEX.Size],1
         CALL SaveViewIndex::
         MOV [RBX+VIEW_INDEX.Rem],=B"Image height: !1D"
         CALL SaveViewIndex::
         MOV [RBX+VIEW_INDEX.Rem],=B"Number of colors in palette: !1D"
         CALL SaveViewIndex::
         MOV [RBX+VIEW_INDEX.Rem],=B"Unused"
         CALL SaveViewIndex::
         MOV [RBX+VIEW_INDEX.Rem],=B"Horizontal position of hotspot: !1D"
         MOV [RBX+VIEW_INDEX.Size],2
         CALL SaveViewIndex::
         MOV [RBX+VIEW_INDEX.Rem],=B"Vertical position of hotpost: !1D"
         CALL SaveViewIndex::
         MOV [RBX+VIEW_INDEX.Rem],=B"Image data size: !4Hh=!4D"
         MOV [RBX+VIEW_INDEX.Size],4
         CALL SaveViewIndex::
         MOV [RBX+VIEW_INDEX.Rem],=B"FA of image data: !4Hh=!4D"
         CALL SaveViewIndex::
        POP RCX
        DEC RCX
        JNZ .30:
        MOV [RBX+VIEW_INDEX.Rem],=B"Data of images"
        MOV RAX,[InputSize::]
        MOV EDX,[RBX+VIEW_INDEX.FA]
        SUB EAX,EDX
        JNA .90:
        OR EAX,Level1
        MOV [RBX+VIEW_INDEX.Size],EAX
        CALL SaveViewIndex::
        CALL SaveViewIndex::
    .90:RET
      ENDP FormatCUR

↑ FormatCOFF16

  16bit linkable file format.

Structure
  PFCOFF_FILE_HEADER PFCOFF_SECTION_HEADER PFCOFF_RELOCATION PFCOFF_LINENUMBER PFCOFF_SYMBOL
Extension
  .obj
Manual
  [MS_PECOFF]
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    FormatCOFF16: PROC
        SetSt [Status::],ArgWidth16
        JMP AnalyzeCOFF
       ENDP FormatCOFF16

↑ FormatCOFF32

  32-bit linkable file format.

Structure
  PFCOFF_FILE_HEADER PFCOFF_SECTION_HEADER PFCOFF_RELOCATION PFCOFF_LINENUMBER PFCOFF_SYMBOL
Extension
  .obj
Manual
  [MS_PECOFF]
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    FormatCOFF32: PROC
        SetSt [Status::],ArgWidth32
        JMP AnalyzeCOFF
       ENDP FormatCOFF32

↑ FormatCOFF64

  64-bit linkable file format.

Structure
  PFCOFF_FILE_HEADER PFCOFF_SECTION_HEADER PFCOFF_RELOCATION PFCOFF_LINENUMBER PFCOFF_SYMBOL
Extension
  .obj
Manual
  [MS_PECOFF]
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    FormatCOFF64 PROC
        SetSt [Status::],ArgWidth64
        JMP AnalyzeCOFF
       ENDP FormatCOFF64

↑ FormatDLL32

  32-bit dynamic library file format.

Structure
  PFCOFF_FILE_HEADER PFCOFF_SECTION_HEADER PFCOFF_RELOCATION PFCOFF_LINENUMBER PFCOFF_SYMBOL
Extension
  .dll
Manual
  [MS_PECOFF]
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    FormatDLL32  PROC
        SetSt [Status::],ArgWidth32+ArgDynamicLibrary
        JMP  AnalyzePE
       ENDP FormatDLL32

↑ FormatDLL64

  64-bit dynamic library file format.

Structure
  PFCOFF_FILE_HEADER PFCOFF_SECTION_HEADER PFCOFF_RELOCATION PFCOFF_LINENUMBER PFCOFF_SYMBOL
Extension
  .dll
Manual
  [MS_PECOFF]
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    FormatDLL64  PROC
        SetSt [Status::],ArgWidth64+ArgDynamicLibrary
        JMP  AnalyzePE
       ENDP FormatDLL64

↑ FormatELF32

  32-bit linkable module format.

Extension
  .o
Manual
  [ELF32]
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    FormatELF32  PROC
        SetSt [Status::],ArgWidth32
        MOV [RBX+VIEW_INDEX.Rem],=B'Format ELF32 "!14$" size=!24$ !25$'
    .Common:
        MOV [RBX+VIEW_INDEX.FA],0
        MOV RCX,[InputSize::]
        OR ECX,Level4
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        CALL AnalyzeElfFileHeader
        MOV ECX,[NrOfElfProgramHeaders]
        JRCXZ .20:
        CMP ECX,32
        JNBE .90:
        MOV EAX,[FaOfElfProgramHeaders]
        CMP RAX,[InputSize::]
        JNB .90:
        MOV [RBX+VIEW_INDEX.FA],EAX
    .10:PUSH RCX
          CALL AnalyzeElfProgramHeader
        POP RCX
        LOOP .10:
    .20:MOV ECX,[NrOfElfSectionHeaders]
        JRCXZ .90:
        CMP ECX,64
        JNB .90:
        MOV EAX,[FaOfElfSectionHeaders]
        CMP RAX,[InputSize::]
        JNB .90:
        MOV [RBX+VIEW_INDEX.FA],EAX
    .30:PUSH RCX
          JSt [Status::],ArgWidth64, .40:
          CALL AnalyzeElfSectionHeader32
          JMP .50:
    .40:  CALL AnalyzeElfSectionHeader64
    .50:POP RCX
        LOOP .30:
    .90:RET
      ENDP FormatELF32

↑ FormatELF64

  64-bit linkable module format.

Extension
  .o
Manual
  [ELF64]
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    FormatELF64  PROC
        SetSt [Status::],ArgWidth64
        MOV [RBX+VIEW_INDEX.Rem],=B'Format ELF64 "!14$" size=!24$ !25$'
        JMP FormatELF32.Common:
      ENDP FormatELF64

↑ FormatELFSO32

  32-bit shared object library format.

Extension
  .so
Manual
  [ELF32]
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    FormatELFSO32  PROC
        SetSt [Status::],ArgWidth32+ArgDynamicLibrary
        MOV [RBX+VIEW_INDEX.Rem],=B'Format ELFSO32 "!14$" size=!24$ !25$'
        JMP FormatELF32.Common:
      ENDP FormatELFSO32

↑ Format ELFSO64

  64bit shared object library format.

Extension
  .so
Manual
  [ELF64]
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    FormatELFSO64  PROC
        SetSt [Status::],ArgWidth64+ArgDynamicLibrary
        MOV [RBX+VIEW_INDEX.Rem],=B'Format ELFSO64 "!14$" size=!24$ !25$'
        JMP FormatELF32.Common:
      ENDP FormatELFSO64

↑ FormatELFX32

  32-bit executable file format.

Extension
Manual
  [ELF32]
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    FormatELFX32  PROC
        SetSt [Status::],ArgWidth32
        MOV [RBX+VIEW_INDEX.Rem],=B'Format ELFX32 "!14$" size=!24$ !25$'
        JMP FormatELF32.Common:
      ENDP FormatELFX32

↑ FormatELFX64

  64-bit executable file format.

Extension
Manual
  [ELF64]
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    FormatELFX64  PROC
        SetSt [Status::],ArgWidth64
        MOV [RBX+VIEW_INDEX.Rem],=B'Format ELFX64 "!14$" size=!24$ !25$'
        JMP FormatELF32.Common:
      ENDP FormatELFX64

↑ FormatGIF

  Image file format.

Extension
  .gif
Documentation
  GIF (file format)
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    FormatGIF  PROC
        MOV [RBX+VIEW_INDEX.Rem],=B'Format GIF "!14$" size=!24$ !25$'
        MOV [RBX+VIEW_INDEX.FA],0
        MOV RCX,[InputSize::]
        OR ECX,Level4
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"GIF Signature"
        MOV [RBX+VIEW_INDEX.Size],6+Level3
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"!6X"
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Screen description"
        MOV [RBX+VIEW_INDEX.Size],7+Level3
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Screen width: !2D"
        MOV [RBX+VIEW_INDEX.Size],2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Screen height: !2D"
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Global color table size: !23$"
        MOV [RBX+VIEW_INDEX.Size],1
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOV CL,[R8+RDX]
        XOR EAX,EAX
        TEST CL,0x80
        JZ .20:
        AND CL,0x07
        INC CL
        INC EAX
        SHL EAX,CL
        LEA EAX,[EAX+2*EAX]
    .20:MOV [SizeOfColorTable],EAX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Background color: !1Hh"
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Pixel aspect ratio: !1D"
        CALL SaveViewIndex::
        MOV ECX,[SizeOfColorTable]
        JRCXZ .30:
        MOV [RBX+VIEW_INDEX.Rem],=B"Global color table RGB"
        OR ECX,Level3
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        CALL SaveViewIndex::
    .30:MOV EDX,[RBX+VIEW_INDEX.FA]
        MOV AX,[R8+RDX]
        CMP AL,0x2C
        JE .0x2C:
        Dispatch AX,0xFF21,0xFE21,0xF921
        JMP .80:
    .0x2C:
        MOV [RBX+VIEW_INDEX.Rem],=B"Image descriptor"
        MOV [RBX+VIEW_INDEX.Size],1+Level2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Descriptor identifier"
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Image left position: !2Hh=!2D"
        MOV [RBX+VIEW_INDEX.Size],2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Image top position: !2Hh=!2D"
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Image width: !2Hh=!2D"
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Image height: !2Hh=!2D"
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Color table size: !23$"
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOV CL,[R8+RDX]
        XOR EAX,EAX
        TEST CL,0x80
        JZ .35:
        AND CL,0x07
        INC CL
        INC EAX
        SHL EAX,CL
        LEA EAX,[EAX+2*EAX]
    .35:MOV [SizeOfColorTable],EAX
        MOV [RBX+VIEW_INDEX.Size],1
        CALL SaveViewIndex::
        MOV ECX,[SizeOfColorTable]
        TEST ECX
        JZ .30:
        MOV [RBX+VIEW_INDEX.Rem],=B"Color table RGB"
        OR ECX,Level2
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        CALL SaveViewIndex::
        JMP .30:
    .0xFF21:
        MOV [RBX+VIEW_INDEX.Rem],=B"Application extension"
        MOV [RBX+VIEW_INDEX.Size],2+Level2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Extension identifier"
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Application owner: !12X"
        MOV [RBX+VIEW_INDEX.Size],12
        CALL SaveViewIndex::
    .40:MOV EDX,[RBX+VIEW_INDEX.FA]
        MOVZXB ECX,[R8+RDX]          ; Data subblock size.
        JRCXZ .45:
        MOV [RBX+VIEW_INDEX.Rem],=B"Data block size: !1D"
        MOV [RBX+VIEW_INDEX.Size],1
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Data block body"
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        JMP .40:
    .45:MOV [RBX+VIEW_INDEX.Rem],=B"Data block terminator"
        MOV [RBX+VIEW_INDEX.Size],1
        CALL SaveViewIndex::
        JMP .30:
    .0xF921:
        MOV [RBX+VIEW_INDEX.Rem],=B"Graphic control extension"
        MOV [RBX+VIEW_INDEX.Size],2+Level2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Extension identifier"
        CALL SaveViewIndex::
    .50:MOV EDX,[RBX+VIEW_INDEX.FA]
        MOVZXB ECX,[R8+RDX]          ; Data subblock size.
        JRCXZ .55:
        MOV [RBX+VIEW_INDEX.Rem],=B"Data block size: !1D"
        MOV [RBX+VIEW_INDEX.Size],1
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Data block body"
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        JMP .50:
    .55:MOV [RBX+VIEW_INDEX.Rem],=B"Data block terminator"
        MOV [RBX+VIEW_INDEX.Size],1
        CALL SaveViewIndex::
        JMP .30:
    .0xFE21:
        MOV [RBX+VIEW_INDEX.Rem],=B"Comment extension"
        MOV [RBX+VIEW_INDEX.Size],2+Level2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Extension identifier"
        CALL SaveViewIndex::
    .60:MOV EDX,[RBX+VIEW_INDEX.FA]
        MOVZXB ECX,[R8+RDX]          ; Data subblock size.
        JRCXZ .65:
        MOV [RBX+VIEW_INDEX.Rem],=B"Data block size: !1D"
        MOV [RBX+VIEW_INDEX.Size],1
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"!X"
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        JMP .60:
    .65:MOV [RBX+VIEW_INDEX.Rem],=B"Data block terminator"
        MOV [RBX+VIEW_INDEX.Size],1
        CALL SaveViewIndex::
        JMP .30:
    .80:MOV [RBX+VIEW_INDEX.Rem],=B"Image data"
        MOV RCX,[InputSize::]
        MOV EDX,[RBX+VIEW_INDEX.FA]
        SUB ECX,EDX
        OR ECX,Level1
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"!X"
        CALL SaveViewIndex::
        RET
      ENDP FormatGIF

↑ FormatICO

  Image file format.

Extension
  .ico
Documentation
  ICO (file format)
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    FormatICO  PROC
        MOV [RBX+VIEW_INDEX.Rem],=B'Format ICO "!14$" size=!24$ !25$'
        MOV [RBX+VIEW_INDEX.FA],0
        MOV RCX,[InputSize::]
        OR ECX,Level4
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Icon directory"
        MOV [RBX+VIEW_INDEX.Size],6+Level3
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Icon file signature"
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B"Number of images: !2D"
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOVZXW ECX,[R8+RDX]
      ; MOV [NrOfSections],ECX
        MOV [RBX+VIEW_INDEX.Size],2
        CALL SaveViewIndex::
        TEST RCX
        JZ .90:
    .30:PUSH RCX
         MOV [RBX+VIEW_INDEX.Rem],=B"Image #!18$"
         MOV [RBX+VIEW_INDEX.Size],16+Level2
         CALL SaveViewIndex::
         MOV [RBX+VIEW_INDEX.Rem],=B"Image width: !1D"
         MOV [RBX+VIEW_INDEX.Size],1
         CALL SaveViewIndex::
         MOV [RBX+VIEW_INDEX.Rem],=B"Image height: !1D"
         CALL SaveViewIndex::
         MOV [RBX+VIEW_INDEX.Rem],=B"Number of colors in palette: !1D"
         CALL SaveViewIndex::
         MOV [RBX+VIEW_INDEX.Rem],=B"Unused"
         CALL SaveViewIndex::
         MOV [RBX+VIEW_INDEX.Rem],=B"Number of color planes: !1D"
         MOV [RBX+VIEW_INDEX.Size],2
         CALL SaveViewIndex::
         MOV [RBX+VIEW_INDEX.Rem],=B"Bits per pixel: !1D"
         CALL SaveViewIndex::
         MOV [RBX+VIEW_INDEX.Rem],=B"Image data size: !4Hh=!4D"
         MOV [RBX+VIEW_INDEX.Size],4
         CALL SaveViewIndex::
         MOV [RBX+VIEW_INDEX.Rem],=B"FA of image data: !4Hh=!4D"
         CALL SaveViewIndex::
        POP RCX
        DEC RCX
        JNZ .30:
        MOV [RBX+VIEW_INDEX.Rem],=B"Data of images"
        MOV RAX,[InputSize::]
        MOV EDX,[RBX+VIEW_INDEX.FA]
        SUB EAX,EDX
        JNA .90:
        OR EAX,Level1
        MOV [RBX+VIEW_INDEX.Size],EAX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'!X'
        CALL SaveViewIndex::
    .90:RET
      ENDP FormatICO

↑ FormatJPG

  Image file format.

Extension
  .jpg, .jpeg
Documentation
  JPEG PNG file format
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    FormatJPG: PROC
        MOV [RBX+VIEW_INDEX.Rem],=B'Format JPG "!14$" size=!24$ !25$'
        MOV [RBX+VIEW_INDEX.FA],0
        MOV RCX,[InputSize]
        MOV EDX,ECX
        OR ECX,Level4
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Segment EOI: End of image'
        SUB EDX,2
        MOV [RBX+VIEW_INDEX.FA],EDX
        MOV [RBX+VIEW_INDEX.Size],2+Level2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Marker !2B'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.FA],0
    .10:MOV EDX,[RBX+VIEW_INDEX.FA]
        ADD RDX,R8
        LEA RAX,[RDX+2]
        CMP RAX,[InputEnd]
        JNB .90:
        MOVZXW EAX,[RDX]                   ; Load the marker.
        CMP AL,0xFF
        JE .20:
        MOV [RBX+VIEW_INDEX.Rem],=B'!X'    ; It was not a marker. Dump until EOI.
        MOV RCX,[InputEnd]
        SUB RCX,2
        SUB RCX,RDX
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        JMP .90:
    .20:MOVZX EDX,AH                       ; AL=0xFF, DL=marker identifier.
        Dispatch DL,0xD8,0xD9              ; Markers FFD0..FFD9 are without payload. Their size is 0.
        CMP DL,0xD0
        JB .30:
        CMP DL,0xD7
        JA .30:
        AND DL,0x07                        ; Marker 0xFFDn - restart n
        OR DL,'0'
        MOV [ACharacter],DL
        MOV [RBX+VIEW_INDEX.Rem],=B'Segment RST!1A: Restart'
        MOV [RBX+VIEW_INDEX.Size],2+Level2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Marker !2B'
        CALL SaveViewIndex::
        JMP .10:
    .0xD8:MOV [RBX+VIEW_INDEX.Rem],=B'Segment SOI: Start of image'
        MOV [RBX+VIEW_INDEX.Size],2+Level2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Marker !2B'
        CALL SaveViewIndex::
        JMP .10:
    .0xD9:MOV [RBX+VIEW_INDEX.Rem],=B'Segment EOI: End of image'
        MOV [RBX+VIEW_INDEX.Size],2+Level2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Marker !2B'
        CALL SaveViewIndex::
        JMP .10:
    .30: ; Other markers are followed by variable size in two big endian bytes. DL=marker identifier.
        CMP DL,0xE0
        JB .40:
        CMP DL,0xEF
        JA .40:
        ; FFE0..FFEF are application-specific segment markers.
        MOV [RBX+VIEW_INDEX.Rem],=B'Segment APP!2A: Application-specific'
        JMP .50:
    .40:Dispatch DL,0xC0,0xC2,0xC4,0xDA,0xDB,0xDD,0xFE
        MOV [RBX+VIEW_INDEX.Rem],=B'Marker !2B'
        JMP .50:
    .0xC0:MOV [RBX+VIEW_INDEX.Rem],=B'Segment SOF0: Start of frame baseline transform'
        JMP .50:
    .0xC2:MOV [RBX+VIEW_INDEX.Rem],=B'Segment SOF2: Start of frame progressive transform'
        JMP .50:
    .0xC4:MOV [RBX+VIEW_INDEX.Rem],=B'Segment DHT: Define Huffman tables'
        JMP .50:
    .0xDA:MOV [RBX+VIEW_INDEX.Rem],=B'Segment SOS: Start of scan'
        JMP .50:
    .0xDB:MOV [RBX+VIEW_INDEX.Rem],=B'Segment DQT: Define quantization tables'
        JMP .50:
    .0xDD:MOV [RBX+VIEW_INDEX.Rem],=B'Segment DRI: Define restart interval'
        JMP .50:
    .0xFE:MOV [RBX+VIEW_INDEX.Rem],=B'Segment COM: Comment'
        ;JMP .50:
    .50:MOV EDX,[RBX+VIEW_INDEX.FA]
        MOVZXW ECX,[R8+RDX+2]
        XCHG CH,CL
        LEA EDX,[RCX-2]                    ; Keep netto size in EDX.
        ADD ECX,2
        OR ECX,Level2
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Marker !2B'
        MOV [RBX+VIEW_INDEX.Size],2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Size !2Bh=!2b'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'!X'
        MOV [RBX+VIEW_INDEX.Size],EDX
        CALL SaveViewIndex::
        JMP .10:
    .90:RET
      ENDP FormatJPG

↑ FormatLIBCOF

  Library of COFF modules file format.

Structure
  PFLIBCOF_ARCHIVE_MEMBER PFLIBCOF_IMPORT_OBJECTHEADER PFCOFF_FILE_HEADER
Extension
  .lib
Manual
  [MS_PECOFF]
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    FormatLIBCOF:  PROC
        MOV [RBX+VIEW_INDEX.Rem],=B'Format LIBCOF "!14$" size=!24$ !25$'
        MOV [RBX+VIEW_INDEX.FA],0
        MOV RCX,[InputSize::]
        OR ECX,Level4
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Archive signature !7X'
        MOV [RBX+VIEW_INDEX.Size],8
        CALL SaveViewIndex::
        CALL AnalyzeLibcofMemberHeader
        MOV [RBX+VIEW_INDEX.Rem],=B'Linker 1st header'
        MOV EAX,[MemberSize]
        OR EAX,Level2
        MOV [RBX+VIEW_INDEX.Size],EAX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'!X'
        CALL SaveViewIndex::
        CALL AnalyzeLibcofMemberHeader
        MOV [RBX+VIEW_INDEX.Rem],=B'Linker 2nd header'
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOV EAX,[MemberSize]
        MOV ECX,EAX
        ADD ECX,EDX
        MOV [FaOfSymbolEnd],ECX
        OR EAX,Level2
        MOV [RBX+VIEW_INDEX.Size],EAX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'File addresses of !4D members'
        MOV EDX,[RBX+VIEW_INDEX.FA]
        CMP RDX,[InputSize::]
        JNB .90:
        MOV EAX,[R8+RDX]
        LEA EAX,[4*EAX+4+Level1]
        MOV [RBX+VIEW_INDEX.Size],EAX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Number of members: !4D'
        MOV [RBX+VIEW_INDEX.Size],4
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOV [FaOfMembersTable],EDX
        CMP RDX,[InputSize::]
        JNB .90:
        MOV ECX,[R8+RDX]
        CALL SaveViewIndex::
        CMP ECX,65000
        JNB .90:
        JRCXZ .30:
    .20:MOV [RBX+VIEW_INDEX.Rem],=B'Member #!18$ at !4Hh: !16$'
        CALL SaveViewIndex::
        LOOP .20:
    .30:MOV [RBX+VIEW_INDEX.Rem],=B'Indexes of !4D symbols'
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOV EAX,[R8+RDX]
        MOV ECX,EAX
        LEA EAX,[2*EAX+4]
        ADD EDX,EAX
        MOV [FaOfArchiveStrings],EDX
        ADD EAX,Level1
        MOV [RBX+VIEW_INDEX.Size],EAX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Number of symbols: !4D'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex::
        JRCXZ .50:
        MOV [RBX+VIEW_INDEX.Size],2
    .40:MOV [RBX+VIEW_INDEX.Rem],=B'Symbol in member #!2D: !17$' ; Fn17$DisplaySymbolName
        CALL SaveViewIndex::
        LOOP .40:
    .50:MOV [RBX+VIEW_INDEX.Rem],=B'String table'
        MOV EAX,[FaOfSymbolEnd]
        SUB EAX,[RBX+VIEW_INDEX.FA]
        OR  EAX,Level1
        MOV [RBX+VIEW_INDEX.Size],EAX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'!X'
        CALL SaveViewIndex::
        CALL AnalyzeLibcofMemberHeader
        MOV [RBX+VIEW_INDEX.Rem],=B'Longnames header'
        MOV EAX,[MemberSize]
        OR EAX,Level2
        MOV [RBX+VIEW_INDEX.Size],EAX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'!X'
        CALL SaveViewIndex::
        MOV EDX,[FaOfMembersTable]
        LEA RSI,[R8+RDX]
        LODSD          ; Number of members.
        MOV ECX,EAX
    .60:PUSH RCX
          LODSD
          PUSH RSI
           MOV [RBX+VIEW_INDEX.FA],EAX
           LEA EDX,[EAX+60]                ; FA of Short import header or COFF file header.
           MOV EAX,[R8+RDX]
           CMP EAX,0xFFFF_0000
           JNE .70:
           CALL AnalyzeLibcofMemberHeader
           CALL AnalyzeLibcofFileHeader
           MOV [RBX+VIEW_INDEX.Rem],=B'Short import body'
           JMP .80:
    .70:   CALL AnalyzeLibcofMemberHeader
           CALL AnalyzeCoffFileHeader
           MOV [RBX+VIEW_INDEX.Rem],=B'COFF module body'
    .80:   MOV EAX,[MemberSize]
           SUB EAX,20
           OR EAX,Level2
           MOV [RBX+VIEW_INDEX.Size],EAX
           CALL SaveViewIndex::
           MOV [RBX+VIEW_INDEX.Rem],=B'!X'
           CALL SaveViewIndex::
          POP RSI
        POP RCX
        LOOP .60:
    .90:RET
       ENDP FormatLIBCOF

↑ FormatLIBOMF

  LIBOMF module file format.

Extension
  .lib
Manual
  [OMF]
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    FormatLIBOMF:  PROC
        MOV [RBX+VIEW_INDEX.Rem],=B'Format LIBOMF "!14$" size=!24$ !25$'
        MOV [RBX+VIEW_INDEX.FA],0
        MOV RCX,[InputSize::]
        OR ECX,Level4
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
    .10:MOV EDX,[RBX+VIEW_INDEX.FA]
        CMP RDX,[InputSize]
        JNB .90:
        CALL AnalyzeOmfRecord
        JNZ .10:
        ; [LastOmfRecord]=LIBEND
        MOV [RBX+VIEW_INDEX.Rem],=B'Hashed dictionary'
        MOV RCX,[InputSize::]
        SUB ECX,[RBX+VIEW_INDEX.FA]
        OR ECX,Level3
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'!X'
        CALL SaveViewIndex::
    .90:RET
       ENDP FormatLIBOMF

↑ FormatMIDI

  Sound file format.

Extension
  .mid
Documentation
  Standard MIDI File Format
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    FormatMIDI::  PROC
        MOV [RBX+VIEW_INDEX.Rem],=B'Format MIDI" !14$" size=!24$ !25$'
        MOV [RBX+VIEW_INDEX.FA],0
        MOV RCX,[InputSize]
        OR ECX,Level4
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'MIDI header MThd'
        MOV [RBX+VIEW_INDEX.Size],14+Level2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Header marker "!4X"'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Header size !4hh=!4d'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Format !2b'
        MOV [RBX+VIEW_INDEX.Size],2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Number of tracks !2b'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Ticks per quarter note !2b'
        CALL SaveViewIndex::
    .30:MOV EDX,[RBX+VIEW_INDEX.FA]
        ADD RDX,R8
        CMP RDX,[InputEnd]
        JNB .90:
        CMPD [RDX],'MTrk'
        JNE .90:
        MOV [RBX+VIEW_INDEX.Rem],=B'MIDI track MTrk'
        MOV ECX,[RDX+4]
        BSWAP ECX
        MOV EDX,ECX
        ADD ECX,8
        OR ECX,Level2
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Track marker "!4X"'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Track size !4hh=!4d'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'MIDI data'
        MOV [RBX+VIEW_INDEX.Size],EDX
        CALL SaveViewIndex::
        JMP .30:
    .90:RET
      ENDP FormatMIDI

↑ FormatMP3

  Sound file format.

Extension
  .mp3
Documentation
  Inside MP3
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    FormatMP3::  PROC
        MOV [RBX+VIEW_INDEX.Rem],=B'Format MP3 "!14$" size=!24$ !25$'
        MOV [RBX+VIEW_INDEX.FA],0
        MOV RCX,[InputSize]
        MOV [FaOfSoundEnd],ECX
        OR ECX,Level4
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::               ; The entire file.
        CMPD [R8],0x03334449               ; ID3v2.
        JNE .40:                           ; ID3 missing, assume sound frames only.
        MOV [RBX+VIEW_INDEX.Rem],=B'ID3 TAG version 2'
        XOR EDX,EDX                        ; Compute size of ID3 tag to EDX.
        MOV ECX,4
        LEA RSI,[R8+6]                     ; MSB digit of tag size (big endian).
    .10:LODSB
        SHL EDX,7
        OR DL,AL
        LOOP .10:
        ADD EDX,10
        MOV [ID3size],EDX
        MOV [FaOfSoundStart],EDX
        OR EDX,Level3
        MOV [RBX+VIEW_INDEX.Size],EDX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'!3X'   ; ID3.
        MOV [RBX+VIEW_INDEX.Size],10
        CALL SaveViewIndex::               ; One ID3 header.
    .20:MOV EDX,[RBX+VIEW_INDEX.FA]
        MOV ECX,[R8+RDX+4]                 ; Size of one tag.
        BSWAP ECX
        TEST ECX
        JZ .30:
        ADD ECX,10+Level2
        MOV [RBX+VIEW_INDEX.Size],ECX
        MOV EAX,[R8+RDX+0]                 ; The tag (four letters).
        PUSH .Dispatched:                  ; Convert the tag from EAX to human-readable at RSI.
        Dispatch EAX,'TYER','TALB','TIT2','TPE1','TRCK','TENC','TCOP','TOPE','TCOM','TCON','COMM','WXXX'
        LEA RSI,[=B(0)]
        RET
    .TYER:LEA RSI,[=B'Year']
        RET
    .TALB:LEA RSI,[=B'Album']
        RET
    .TIT2:LEA RSI,[=B'Song name']
        RET
    .TPE1:LEA RSI,[=B'Artist']
        RET
    .TRCK:LEA RSI,[=B'Track number']
        RET
    .TENC:LEA RSI,[=B'Encoded by']
        RET
    .TCOP:LEA RSI,[=B'Frame identifier']
        RET
    .TOPE:LEA RSI,[=B'Original artist']
        RET
    .TCOM:LEA RSI,[=B'Composer']
        RET
    .TCON:LEA RSI,[=B'Genre']
        RET
    .COMM:LEA RSI,[=B'Comments']
        RET
    .WXXX:LEA RSI,[=B'URL']
        RET
    .Dispatched:
        MOV [RBX+VIEW_INDEX.Rem],RSI
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'!X'
        MOV [RBX+VIEW_INDEX.Size],11
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'!X'    ; Value of the tag.
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOVZXB ECX,[R8+RDX-4]
        JRCXZ .25:
        DEC ECX
    .25:MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        MOV EAX,[RBX+VIEW_INDEX.FA]
        CMP EAX,[ID3size]
        JB .20:                            ; The next ID3 tag.
    .30:MOV [RBX+VIEW_INDEX.Rem],=B'Not used'
        MOV ECX,[ID3size]
        SUB ECX,[RBX+VIEW_INDEX.FA]
        JB .90:
        OR ECX,Level2
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::               ; Not used.
        MOV [RBX+VIEW_INDEX.Rem],=B'!X'
        CALL SaveViewIndex::               ; Unused bytes in ID3.
        ; ID3v2 tag is completed.
    .40:; Try ID3v1 tag.
        MOV RSI,[InputEnd]
        SUB RSI,128
        MOV EAX,[RSI]
        AND EAX,0x00FFFFFF
        CMP EAX,'TAG'
        JNE .45:
        SUB [FaOfSoundEnd],128             ; ID3v1 exists at the last 128 bytes of the file.
        MOV [RBX+VIEW_INDEX.Rem],=B'ID3 TAG version 1'
        MOV [RBX+VIEW_INDEX.Size],128+Level3
        MOV RAX,RSI
        SUB RAX,R8
        MOV [RBX+VIEW_INDEX.FA],EAX
        CALL SaveViewIndex::               ; ID3 TAG version 1, Level2
        MOV [RBX+VIEW_INDEX.Rem],=B'TAG'
        MOV [RBX+VIEW_INDEX.Size],3
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Song name'
        MOV [RBX+VIEW_INDEX.Size],30+Level2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'!X'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Artist'
        MOV [RBX+VIEW_INDEX.Size],30+Level2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'!X'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Album'
        MOV [RBX+VIEW_INDEX.Size],30+Level2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'!X'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Year'
        MOV [RBX+VIEW_INDEX.Size],4+Level2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'!X'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Comment'
        MOV [RBX+VIEW_INDEX.Size],30+Level2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'!X'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Genre'
        MOV [RBX+VIEW_INDEX.Size],1+Level2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'!X'
        CALL SaveViewIndex::
    .45:MOV [RBX+VIEW_INDEX.Rem],=B'Entire sound content'
        MOV ECX,[FaOfSoundEnd]
        MOV EDX,[FaOfSoundStart]
        MOV [RBX+VIEW_INDEX.FA],EDX
        SUB ECX,EDX
        OR ECX,Level3
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::               ; Entire cound content. Level3.
        AND ECX,0x0FFF_FFFF
        LEA RDI,[R8+RDX]
    .50:MOV AL,0xFF
        REPNE SCASB
        JNE .90:
        LEA RDX,[RDI-1]
        SUB RDX,R8
        MOV [RBX+VIEW_INDEX.FA],EDX
        MOV AL,[RDI]
        AND AL,0xFA                       ; Accept frame header 0xFFFB or 0xFFFA.
        CMP AL,0xFA
        JNE .50:
        LEA RDX,[RDI-1]                   ; RDX points to the start of frame 0xFFFBxxyy.
        MOV EAX,[RDX]
        MOV [MP3frame],EAX                ; Store cache of the MP3 frame.
        SUB RDX,R8
        MOV [RBX+VIEW_INDEX.FA],EDX
    .60:MOV [RBX+VIEW_INDEX.Rem],=B'Sound frame 26 ms'
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOVZXB EAX,[R8+RDX+2]             ; The byte which follows 0xFFFB.
        MOV ECX,EAX
        SHR EAX,4                         ; Get bit rate.
        JZ .90:
        CMP AL,1111b
        JE .90:
        MOVZXW EDX,[2*EAX+MP3BitrateTable]
        MOV EAX,EDX
        LEA RDI,[MP3bitrate]
        StoD RDI,Size=3
        AND ECX,0000_1100b                 ; Get sample rate.
        CMP CL,0000_1100b
        JE .90:
        MOV EAX,[RCX+MP3SamplerateTable]
        MOV ECX,EAX
        LEA RDI,[MP3freq]
        StoD RDI,Size=5
        MOV EAX,144_000                    ; Calculate frame length * 1000.
        MUL RDX                            ; 144 * Bitrate in kbps.
        DIV RCX                            ; 144 * Bitrate / Samplerate
        MOV EDI,[RBX+VIEW_INDEX.FA]        ; FA of byte 0xFF.
        BTD [R8+RDI+2],1                   ; Query and add the padding bit.
        ADC EAX,0
        MOV R9D,EAX                        ; Remember the brutto size of one 26 ms sound frame in R9.
        MOV AL,[R8+RDI+3]                  ; Continue with the construction of MP3report.
        SHR AL,6
        Dispatch AL,0d,1d,2d
        LEA RSI,[=B'mono']
        JMPS .70:
    .0d:LEA RSI,[=B'stereo']
        JMPS .70:
    .1d:LEA RSI,[=B'joint stereo']
        JMPS .70:
    .2d:LEA RSI,[=B'dual sound']
    .70:LEA RDI,[MP3channel]
    .75:LODSB
        STOSB
        CMP AL,0
        JNZ .75:                           ; MP3report is constructed.
        ; Sound frame brutto size is in R9. Look if the last frame is not shorter (if it ends at FaOfSoundEnd).
        MOV EDX,[RBX+VIEW_INDEX.FA]        ; EDX is FA of the end of frame.
        ADD EDX,R9D
        SUB EDX,[FaOfSoundEnd]
        JBE .80:                           ; If below, the frame is not shorter. Its size is in R9.
        SUB R9D,EDX                        ; Otherwise decrement the last frame size.
    .80:MOV [RBX+VIEW_INDEX.Size],R9D
        OR  [RBX+VIEW_INDEX.Size],Level1
        CALL SaveViewIndex::               ; Level1 Sound frame 26 ms.
        LEA RSI,[MP3report]
        MOV [RBX+VIEW_INDEX.Rem],RSI       ; MP3report is used as remark.
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex::               ; MPEG1 Layer3 xxx bit/s, yyyy Hz, stereo.
        MOV [RBX+VIEW_INDEX.Rem],=B'!X'
        SUB R9D,4
        MOV [RBX+VIEW_INDEX.Size],R9D      ; Netto size of this sound frame.
        CALL SaveViewIndex::               ; Samples.
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOV AX,[R8+RDX]
        AND AH,0xFA
        CMP AX,0xFAFF
        JE .60:
    .90:RET
      ENDP FormatMP3

↑ FormatMZ

  16bit DOS executable file format.

Structure
  PFMZ_DOS_HEADER
Extension
  .exe
Manual
  [MZ]
  [MZEXE]
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    FormatMZ:: PROC
        MOV [RBX+VIEW_INDEX.Rem],=B'Format MZ "!14$" size=!24$ !25$'
        SetSt [Status::],ArgWidth16
        MOV [RBX+VIEW_INDEX.FA],0
        MOV RCX,[InputSize::]
        OR ECX,Level4
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        CALL AnalyzeMzProgram
        RET
       ENDP FormatMZ

↑ FormatOMF

  OMF module file format.

Extension
  .obj
Manual
  [OMF]
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    FormatOMF::  PROC
        MOV [RBX+VIEW_INDEX.Rem],=B'Format OMF "!14$" size=!24$ !25$'
        MOV [RBX+VIEW_INDEX.FA],0
        MOV RCX,[InputSize::]
        OR ECX,Level4
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
    .10:MOV EDX,[RBX+VIEW_INDEX.FA]
        CMP RDX,[InputSize::]
        JNB .90:
        CALL AnalyzeOmfRecord
        JMP .10:
    .90:RET
       ENDP FormatOMF

↑ FormatPE32

  32-bit executable file format.

Structure
  PFCOFF_FILE_HEADER PFCOFF_SECTION_HEADER PFCOFF_RELOCATION PFCOFF_LINENUMBER PFCOFF_SYMBOL
Extension
  .exe
Manual
  [MS_PECOFF]
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    FormatPE32  PROC
        SetSt [Status::],ArgWidth32
        JMP  AnalyzePE
       ENDP FormatPE32

↑ FormatPE64

  64-bit executable file format.

Structure
  PFCOFF_FILE_HEADER PFCOFF_SECTION_HEADER PFCOFF_RELOCATION PFCOFF_LINENUMBER PFCOFF_SYMBOL
Extension
  .exe
Manual
  [MS_PECOFF]
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    FormatPE64  PROC
        SetSt [Status::],ArgWidth64
        JMP  AnalyzePE
       ENDP FormatPE64

↑ FormatPNG

  Image file format.

Extension
  .png
Documentation
  PNG file format
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    FormatPNG: PROC
        MOV [RBX+VIEW_INDEX.Rem],=B'Format PNG "!14$" size=!24$ !25$'
        MOV [RBX+VIEW_INDEX.FA],0
        MOV RCX,[InputSize::]
        OR ECX,Level4
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'PNG signature'
        MOV [RBX+VIEW_INDEX.Size],8+Level3
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'!8X'
        MOV [RBX+VIEW_INDEX.Size],8
        CALL SaveViewIndex::
        MOV EDX,[RBX+VIEW_INDEX.FA]
        LEA RSI,[R8+RDX]                    ; A chunk is expected.
        CMP RSI,[InputEnd]
        JNB .90:
        MOV  EDI,[RSI]                     ; Chunk netto size (payload data only).
        BSWAP EDI                          ; Convert BE to LE.
        ADD EDI,4+4+4                      ; Chunk brutto size (size+id+data+CRC).
        CMP EDI,4+4+13+4
        JNE .30:
        CMPD [RSI+4],0x52444849            ; Chunk id="IHDR"?
        JNE .30:
        ; Chunk is IHDR.
        MOV [RBX+VIEW_INDEX.Rem],=B'Chunk !4E'
        ADD EDI,Level2
        MOV [RBX+VIEW_INDEX.Size],EDI
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'Chunk netto size !4hh=!4d'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'Chunk identifier "!4X"'
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'Image width !4hh=!4d'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Image height !4hh=!4d'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Bits per pixel !1D'
        MOV [RBX+VIEW_INDEX.Size],1
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Color type !1C'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Compression method !1D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Filter method !1D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Interlaced !1D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Size],4
        MOV [RBX+VIEW_INDEX.Rem],=B'CRC !4hh'
        CALL SaveViewIndex::
    .30:; Chunk is not IHDR.
        MOV EDX,[RBX+VIEW_INDEX.FA]
        LEA RSI,[R8+RDX]
        CMP RSI,[InputEnd]
        JNB .90:
        MOV EDI,[RSI]
        BSWAP EDI
        ADD EDI,4+4+4                      ; Chunk brutto size (size+id+data+CRC).
        MOV [RBX+VIEW_INDEX.Rem],=B'Chunk !4E'
        ADD EDI,Level2
        MOV [RBX+VIEW_INDEX.Size],EDI
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'Chunk netto size !4hh=!4d'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'Chunk identifier "!4X"'
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOV ECX,[R8+RDX]                   ; Chunk identifier.
        CALL SaveViewIndex
        OR ECX,0x20202020                  ; Convert to lowercase.
        CMP ECX,'text'
        JE .70:
        MOV [RBX+VIEW_INDEX.Rem],=B'Chunk data'
        JMP .80:
    .70:MOV [RBX+VIEW_INDEX.Rem],=B'!X'
    .80:SUB EDI,4+4+4+Level2
        MOV [RBX+VIEW_INDEX.Size],EDI
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'CRC !4hh'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex
        LEA RDI,[R8+RDI+4]
        CMP RDI,[InputEnd]
        JB .30:
    .90:RET
       ENDP FormatPNG

↑ FormatWAV

  Sound file format.

Extension
  .wav
Documentation
  WAV (file format)
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    FormatWAV  PROC
        MOV [RBX+VIEW_INDEX.Rem],=B'Format WAV "!14$" size=!24$ !25$'
        MOV [RBX+VIEW_INDEX.FA],0
        MOV RCX,[InputSize]
        OR ECX,Level4
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Master chunk RIFF'
        MOV [RBX+VIEW_INDEX.Size],12+Level2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'FileTypeBlocID "!4X"'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'FileSize !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'FileFormatID "!4X"'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Format chunk FMT'
        MOV [RBX+VIEW_INDEX.Size],24+Level2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'FormatBlocID "!4X"'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'BlocSize !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'AudioFormat !2D'
        MOV [RBX+VIEW_INDEX.Size],2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'NbrChannels !2D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Frequency !4Hh=!4D'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'BytePerSec !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'BytePerBloc !2D'
        MOV [RBX+VIEW_INDEX.Size],2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'BitsPerSample !2D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Samples chunk DATA'
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOV ECX,[R8+RDX+4]
        MOV EDX,ECX
        OR ECX,Level2
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'DataBlocID "!4X"'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'DataSize !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'!X'
        MOV [RBX+VIEW_INDEX.Size],EDX
        CALL SaveViewIndex::
        RET
      ENDP FormatWAV

↑ DetectBIN

  This procedure is the last in AutoDetectFileFormat, so it will always return the BIN format.

Input
  RSI=InputPtr (file loaded in memory)
Output
  CF=0, RAX=^FormatBIN
Clobbers
  -

    DetectBIN PROC
         LEA RAX,[FormatBIN]
         RET
       ENDP DetectBIN

↑ DetectBMP

  Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.

Input
  RSI=InputPtr (file loaded in memory)
Output
  CF=0 format is detected successfully.
Output
  CF= is set when this file format was not found.
Clobbers
  RAX,RCX,RDX

    DetectBMP: PROC
        CMPW [RSI],'BM'         ; Signature bitmap file?
        JNE .No:
        MOV  EAX,[RSI+2]
        CMP RAX,[InputSize:]
        JNE .No:
        CLC                     ; Detected.
        JMP .90:
    .No:STC                     ; Not detected.
    .90:RET
       ENDP DetectBMP

↑ DetectCOFF16

  Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.

Input
  RSI=InputPtr (file loaded in memory)
Output
  CF=0 format is detected successfully.
Output
  CF= is set when this file format was not found.
Clobbers
  RAX

    DetectCOFF16 PROC
        CMPW [RSI+0],0x014C      ; Machine I386?
        JNE .No:
        MOVZXW EAX,[RSI+0x0010]  ; Size of optional header should be 0 in COFF.
        TEST EAX
        JNZ .No:
        TESTW [RSI+0x0012],0x0040; 16-bit architecture (€ASM enhancement)?
        JZ .No:
        SetSt [Status::],ArgWidth16
        CLC                      ; Detected.
        JMP .90:
    .No:STC                      ; Not detected.
    .90:RET
       ENDP DetectCOFF16

↑ DetectCOFF32

  Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.

Input
  RSI=InputPtr (file loaded in memory)
Output
  CF= is set when this file format was not found.
Clobbers
  RAX

    DetectCOFF32 PROC
        CMPW [RSI+0],0x014C      ; Machine I386?
        JNE .No:
        MOVZXW EAX,[RSI+0x0010]  ; Size of optional header should be 0 in COFF.
        TEST EAX
        JNZ .No:
        SetSt [Status::],ArgWidth32
        CLC                      ; Machine I386 and not flag 0x0040 set COFF32.
        JMP .90:
    .No:STC                      ; Not detected.
    .90:RET
       ENDP DetectCOFF32

↑ DetectCOFF64

  Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.

Input
  RSI=InputPtr (file loaded in memory)
Output
  CF= is set when this file format was not found.
Clobbers
  RAX

    DetectCOFF64 PROC
        CMPW [RSI+0],0x8664      ; Machine AMD64?
        JNE .No:
        MOVZXW EAX,[RSI+0x0010]  ; Size of optional header should be 0 in COFF.
        TEST EAX
        JNZ .No:
        SetSt [Status::],ArgWidth64
        CLC
        JMP .90:
    .No:STC                      ; Not detected.
    .90:RET
       ENDP DetectCOFF64

↑ DetectCUR

  Test if the file memory-mapped between [InputPtr::] and [OutputEnd::] is in this file format.

Input
  RSI=InputPtr (file loaded in memory)
Output
  CF=0 format is detected successfully.
Output
  CF= is set when this file format was not found.
Clobbers
  RAX,RCX,RDX

    DetectCUR: PROC
        CMPW [RSI+0],0
        JNE .No:
        CMPW [RSI+2],2
        JNE .No:
        CMPW [RSI+4],64
        JA  .No:
        CLC                     ; Detected.
        JMP .90:
    .No:STC                     ; Not detected.
    .90:RET
       ENDP DetectCUR

↑ DetectDLL32

  Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.

Input
  RSI=InputPtr (file loaded in memory)
Output
  CF= is set when this file format was not found.
Clobbers
  RAX,RDX

    DetectDLL32 PROC
        CMPW [RSI+0],'MZ'                  ; MZ signature?
        JNE  .No:
        MOV EDX,[RSI+0x3C]
        CMP RDX,[InputSize::]
        JAE  .No:
        CMPD [RSI+RDX],0x00004550          ; PE signature?
        JNE .No:
        CMPW [RSI+RDX+4+0],0x014C          ; MACHINE_I386?
        JNE .No:
        CMPW [RSI+RDX+4+16],0x00E0         ; Size of optional header.
        JNE .No:
        TESTW [RSI+RDX+4+18],0x2000        ; FILE_DLL?
        JZ .No:
        SetSt [Status::],ArgWidth32
        CLC
        JMP .90:
    .No:STC
    .90:RET
      ENDP DetectDLL32

↑ DetectDLL64

  Test if the file memory-mapped between [InputPtr::] and [OutputEnd::] is in this file format.

Input
  RSI=InputPtr (file loaded in memory)
Output
  CF= is set when this file format was not found.
Clobbers
  RAX

    DetectDLL64: PROC
        CMPW [RSI+0],'MZ'                  ; MZ signature?
        JNE  .No:
        MOV EDX,[RSI+0x3C]
        CMP RDX,[InputSize::]
        JAE  .No:
        CMPD [RSI+RDX],0x00004550          ; PE signature?
        JNE .No:
        CMPW [RSI+RDX+4+0],0x8664          ; MACHINE_AMD64?
        JNE .No:
        CMPW [RSI+RDX+4+16],0x00F0         ; Size of optional header.
        JNE .No:
        TESTW [RSI+RDX+4+18],0x2000        ; FILE_DLL?
        JZ .No:
        SetSt [Status::],ArgWidth64
        CLC
        JMP .90:
    .No:STC
    .90:RET
      ENDP DetectDLL64

↑ DetectELF32

  Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.

Input
  RSI=InputPtr (file loaded in memory)
Output
  CF=0 format is detected successfully.
Output
  CF= is set when this file format was not found.
Clobbers
  RAX,RCX,RDX

    DetectELF32: PROC
        CMPD [RSI],0x464C457F    ; Signature ELF?
        JNE .No:
        CMPB [RSI+4],1
        JNE .No:
        CMPB [RSI+16],1
        JNE .No:
        SetSt [Status::],ArgWidth32
        CLC                     ; Detected.
        JMP .90:
    .No:STC                     ; Not detected.
    .90:RET
       ENDP DetectELF32

↑ DetectELF64

  Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.

Input
  RSI=InputPtr (file loaded in memory)
Output
  CF=0 format is detected successfully.
Output
  CF= is set when this file format was not found.
Clobbers
  RAX,RCX,RDX

    DetectELF64 PROC
        CMPD [RSI],0x464C457F    ; Signature ELF?
        JNE .No:
        CMPB [RSI+4],2
        JNE .No:
        CMPB [RSI+16],1
        JNE .No:
        SetSt [Status::],ArgWidth64
        CLC                     ; Detected.
        JMP .90:
    .No:STC                     ; Not detected.
    .90:RET
       ENDP DetectELF64

↑ DetectELFSO32

  Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.

Input
  RSI=InputPtr (file loaded in memory)
Output
  CF=0 format is detected successfully.
Output
  CF= is set when this file format was not found.
Clobbers
  RAX,RCX,RDX

    DetectELFSO32 PROC
        CMPD [RSI],0x464C457F    ; Signature ELF?
        JNE .No:
        CMPB [RSI+4],1
        JNE .No:
        CMPB [RSI+16],3
        JNE .No:
        SetSt [Status::],ArgWidth32
        CLC                     ; Detected.
        JMP .90:
    .No:STC                     ; Not detected.
    .90:RET
       ENDP DetectELFSO32

↑ DetectELFSO64

  Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.

Input
  RSI=InputPtr (file loaded in memory)
Output
  CF=0 format is detected successfully.
Output
  CF= is set when this file format was not found.
Clobbers
  RAX,RCX,RDX

    DetectELFSO64 PROC
        CMPD [RSI],0x464C457F    ; Signature ELF?
        JNE .No:
        CMPB [RSI+4],2
        JNE .No:
        CMPB [RSI+16],3
        JNE .No:
        SetSt [Status::],ArgWidth64
        CLC                     ; Detected.
        JMP .90:
    .No:STC                     ; Not detected.
    .90:RET
       ENDP DetectELFSO64

↑ DetectELFX32

  Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.

Input
  RSI=InputPtr (file loaded in memory)
Output
  CF=0 format is detected successfully.
Output
  CF= is set when this file format was not found.
Clobbers
  RAX,RCX,RDX

    DetectELFX32 PROC
        CMPD [RSI],0x464C457F    ; Signature ELF?
        JNE .No:
        CMPB [RSI+4],1
        JNE .No:
        CMPB [RSI+16],2
        JNE .No:
        SetSt [Status::],ArgWidth32
        CLC                     ; Detected.
        JMP .90:
    .No:STC                     ; Not detected.
    .90:RET
       ENDP DetectELFX32

↑ DetectELFX64

  Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.

Input
  RSI=InputPtr (file loaded in memory)
Output
  CF=0 format is detected successfully.
Output
  CF= is set when this file format was not found.
Clobbers
  RAX,RCX,RDX

    DetectELFX64 PROC
        CMPD [RSI],0x464C457F    ; Signature ELF?
        JNE .No:
        CMPB [RSI+4],2
        JNE .No:
        CMPB [RSI+16],2
        JNE .No:
        SetSt [Status::],ArgWidth64
        CLC                     ; Detected.
        JMP .90:
    .No:STC                     ; Not detected.
    .90:RET
       ENDP DetectELFX64

↑ DetectGIF

  Test if the file memory-mapped between [InputPtr::] and [InputEnd::] is in this file format.

Input
  RSI=InputPtr (file loaded in memory)
Output
  CF=0 format is detected successfully.
Output
  CF= is set when this file format was not found.
Clobbers
  RAX,RCX,RDX

    DetectGIF: PROC
        CMPD [RSI+0],'GIF8'
        JNE .No:
        CLC                     ; Detected.
        JMP .90:
    .No:STC                     ; Not detected.
    .90:RET
       ENDP DetectGIF

↑ DetectICO

  Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.

Input
  RSI=InputPtr (file loaded in memory)
Output
  CF=0 format is detected successfully.
Output
  CF= is set when this file format was not found.
Clobbers
  RAX,RCX,RDX

    DetectICO: PROC
        CMPW [RSI+0],0
        JNE .No:
        CMPW [RSI+2],1
        JNE .No:
        CMPW [RSI+4],64
        JA  .No:
        CLC                     ; Detected.
        JMP .90:
    .No:STC                     ; Not detected.
    .90:RET
       ENDP DetectICO

↑ DetectJPG

  Test if the file memory-mapped between [InputPtr::] and [InputEnd::] is in this file format.

Input
  RSI=InputPtr (file loaded in memory)
Output
  CF=0 format is detected successfully.
Output
  CF= is set when this file format was not found.
Clobbers
  RAX,RCX,RDX

    DetectJPG: PROC
        CMPW [RSI],0xD8FF
        JNE .No:
        MOV RDX,[InputEnd]
        CMPW [RDX-2],0xD9FF
        JE .90:
    .No:STC
    .90:RET
      ENDP DetectJPG:

↑ DetectLIBCOF

  Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.

Input
  RSI=InputPtr (file loaded in memory)
Output
  CF=0 format is detected successfully.
Output
  CF= is set when this file format was not found.
Clobbers
  RAX

    DetectLIBCOF: PROC
        CMPD [RSI+0],0x72613C21 ; !
        JNE .No:
        CMPD [RSI+4],0x0A3E6863
        JNE .No:
        CLC                     ; Detected.
        SetSt [Status::],ArgWidth32
        JMP .90:
    .No:STC                     ; Not detected.
    .90:RET
       ENDP DetectLIBCOF

↑ DetectLIBOMF

  Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.

Input
  RSI=InputPtr (file loaded in memory)
Output
  CF=0 format is detected successfully.
Output
  CF= is set when this file format was not found.
Clobbers
  RAX,RCX,RDX

    DetectLIBOMF: PROC
        PUSH RSI
        CMPB [RSI],0xF0         ; LIBHDR?
        JNE .No:
        MOVZXW ECX,[RSI+1]
        ADD ECX,3
        CMP RCX,[InputSize:]
        JNB .No:
        CMPB [RSI+RCX],0x82     ; LHEADR?
        JNE .No:
        ADD RSI,RCX
        MOVZXW ECX,[RSI+1]
        ADD ECX,3
        XOR EDX,EDX
    .10:LODSB
        ADD DL,AL
        LOOP .10:
        TEST DL
        JNZ .No:
        CLC                     ; Detected.
        SetSt [Status::],ArgWidth16
        JMP .90:
    .No:STC                     ; Not detected.
    .90:POP RSI
        RET
       ENDP DetectLIBOMF

↑ DetectMIDI

  Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.

Input
  RSI=InputPtr (file loaded in memory)
Output
CF=0 format is detected successfully.
Output
  CF= is set when this file format was not found.
Clobbers
  RAX,RCX,RDX

    DetectMIDI: PROC
        CMPD [RSI],'MThd'
        JNE .No:
        CMPD [RSI+4],0x06000000
        JNE .No:
        CLC                     ; Detected.
        JMP .90:
    .No:STC                     ; Not detected.
    .90:RET
       ENDP DetectMIDI

↑ DetectMP3

  Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.

Input
  RSI=InputPtr (file loaded in memory)
Output
CF=0 format is detected successfully.
Output
  CF= is set when this file format was not found.
Clobbers
  RAX,RCX,RDX

    DetectMP3: PROC
        CMPW [RSI],0xFBFF       ; MP3 frame?
        JE .90:
        CMPD [RSI],0x03334449 ; ID3?
        JE .90:
        STC                     ; Not detected.
    .90:RET
       ENDP DetectMP3

↑ DetectMZ

  Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.

Input
  RSI=InputPtr (file loaded in memory)
Output
  CF=0 format is detected successfully.
Output
  CF= is set when this file format was not found.
Clobbers
  RAX

    DetectMZ PROC
         CMPW [RSI+0],'MZ'       ; Size of optional header.
         JE  .90:
         STC                     ; Not detected.
    .90: RET
       ENDP DetectMZ

↑ DetectOMF

  Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.

Input
  RSI=InputPtr (file loaded in memory)
Output
  CF=0 format is detected successfully.
Output
  CF= is set when this file format was not found.
Clobbers
  RAX,RCX,RDX

    DetectOMF: PROC
         PUSH RSI
         CMPB [RSI],0x80         ; THEADR
         JNE .No:
         MOVZXW ECX,[RSI+1]
         ADD ECX,3
         CMP RCX,[InputSize::]
         JNB .No:
         CMPB [RSI+RCX-1],0
         JE .Yes:
         XOR EDX,EDX
    .10: LODSB
         ADD DL,AL
         LOOP .10:
         TEST DL
         JNZ .No:
    .Yes:SetSt [Status::],ArgWidth16
         CLC                     ; Detected.
         JMP .90:
    .No: STC                     ; Not detected.
    .90: POP RSI
         RET
       ENDP DetectOMF

↑ DetectPE32

  Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.

Input
  RSI=InputPtr (file loaded in memory)
Output
  CF= is set when this file format was not found.
Clobbers
  RAX,RDX

    DetectPE32 PROC
        CMPW [RSI+0],'MZ'                  ; MZ signature?
        JNE  .No:
        MOV EDX,[RSI+0x3C]
        CMP RDX,[InputSize::]
        JAE  .No:
        CMPD [RSI+RDX],0x00004550          ; PE signature?
        JNE .No:
        CMPW [RSI+RDX+4+0],0x014C          ; MACHINE_I386?
        JNE .No:
        CMPW [RSI+RDX+4+16],0x00E0         ; Size of optional header.
        JNE .No:
        TESTW [RSI+RDX+4+18],0x2000        ; FILE_DLL?
        JNZ .No:
        SetSt [Status::],ArgWidth32
        CLC
        JMP .90:
    .No:STC
    .90:RET
      ENDP DetectPE32

↑ DetectPE64

  Test if the file memory-mapped between [InputPtr::] and [OutputEnd::] is in this file format.

Input
  RSI=InputPtr (file loaded in memory)
Output
  CF= is set when this file format was not found.
Clobbers
  RAX

    DetectPE64: PROC
        CMPW [RSI+0],'MZ'                  ; MZ signature?
        JNE  .No:
        MOV EDX,[RSI+0x3C]
        CMP RDX,[InputSize::]
        JAE  .No:
        CMPD [RSI+RDX],0x00004550          ; PE signature?
        JNE .No:
        CMPW [RSI+RDX+4+0],0x8664          ; MACHINE_AMD64?
        JNE .No:
        CMPW [RSI+RDX+4+16],0x00F0         ; Size of optional header.
        JNE .No:
        TESTW [RSI+RDX+4+18],0x2000        ; FILE_DLL?
        JNZ .No:
        SetSt [Status::],ArgWidth64
        CLC
        JMP .90:
    .No:STC
    .90:RET
      ENDP DetectPE64

↑ DetectPNG

  Test if the file memory-mapped between [InputPtr::] and [InputEnd::] is in this file format.

Input
  RSI=InputPtr (file loaded in memory)
Output
  CF=0 format is detected successfully.
Output
  CF= is set when this file format was not found.
Clobbers
  RAX,RCX,RDX

    DetectPNG: PROC
        LODSD
        CMP AL,0x89
        JNE .No:
        SHR EAX,8
        CMP EAX,'PNG'
        JE .90:
    .No:STC
    .90:RET
      ENDP DetectPNG:

↑ DetectWAV

  Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.

Input
  RSI=InputPtr (file loaded in memory)
Output
CF=0 format is detected successfully.
Output
  CF= is set when this file format was not found.
Clobbers
  RAX,RCX,RDX

    DetectWAV: PROC
        CMPD [RSI],'RIFF'
        JNE .No:
        CMPD [RSI+8],'WAVE'
        JNE .No:
        CLC                     ; Detected.
        JMP .90:
    .No:STC                     ; Not detected.
    .90:RET
       ENDP DetectWAV

↑ AnalyzeCOFF

  Linkable file format.

Structure
  PFCOFF_FILE_HEADER PFCOFF_SECTION_HEADER PFCOFF_RELOCATION PFCOFF_LINENUMBER PFCOFF_SYMBOL
Extension
  .obj
Manual
  [MS_PECOFF]
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
  [Status::] ArgWidthMask specifies COFF16, COFF32, COFF64.
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    AnalyzeCOFF: PROC
        XOR EAX,EAX
        MOV [RBX+VIEW_INDEX.FA],EAX
        MOV RCX,[InputSize::]
        OR ECX,Level4
        MOV [RBX+VIEW_INDEX.Size],ECX
        MOV [RBX+VIEW_INDEX.Rem],=B'Format COFF64 "!14$" size=!24$ !25$'
        JSt [Status::],ArgWidth64,.10:
        MOV [RBX+VIEW_INDEX.Rem],=B'Format COFF32 "!14$" size=!24$ !25$'
        JSt [Status::],ArgWidth32,.10:
        MOV [RBX+VIEW_INDEX.Rem],=B'Format COFF16 "!14$" size=!24$ !25$'
        JSt [Status::],ArgWidth16,.10:
        MOV [RBX+VIEW_INDEX.Rem],=B'Format COFF "!14$" size=!24$ !25$'
    .10:CALL SaveViewIndex::
        MOV [FaOfSectionHeaders],20        ; Size of COFF file header.
        CALL AnalyzeCoffFileHeader
        MOV EAX,[NrOfSections]
        LEA EAX,[EAX+4*EAX]
        LEA EAX,[8*EAX]                    ; Multiply NrOfSections by section header size (40).
        MOV [RBX+VIEW_INDEX.Rem],=B'COFF section headers'
        OR EAX,Level2
        MOV [RBX+VIEW_INDEX.Size],EAX
        CALL SaveViewIndex::
        MOV ECX,[NrOfSymbols]
        LEA EAX,[ECX+8*ECX]
        LEA EDX,[2*EAX]                    ; Multiply NrOfSymbols by symbol size (18).
        ADD EDX,[FaOfSymbolTable]
        MOV [FaOfStringTable],EDX
        MOV ECX,[NrOfSections]
        JRCXZ .70:
    .50:PUSH RCX
          CALL AnalyzeCoffSectionHeader
        POP RCX
        LOOP .50:
    .70:
        CALL AnalyzeCoffRawData
        CALL AnalyzeCoffRelocations
        CALL AnalyzeCoffSymbolTable
        CALL AnalyzeCoffStringTable
        RET
       ENDP AnalyzeCOFF

↑ AnalyzeCoffFileHeader

  Linkable file format.

Structure
  PFCOFF_FILE_HEADER
Manual
  [MS_PECOFF]
Input
  RBX=^ViewIndex (working structure)
  R8=InputPtr (file loaded in memory)
Output
  Analyzed elements are stored as ViewIndex records to File_index.
Clobbers
  RAX,RCX
Calls
  SaveViewIndex

    AnalyzeCoffFileHeader PROC
       MOV [RBX+VIEW_INDEX.Rem],=B'COFF file header'
       MOV [RBX+VIEW_INDEX.Size],20+Level2
       CALL SaveViewIndex::
       MOV [RBX+VIEW_INDEX.Rem],=B'Machine !2Hh: !0$'
       MOV [RBX+VIEW_INDEX.Size],2
       CALL SaveViewIndex::
       MOV [RBX+VIEW_INDEX.Rem],=B'Number of sections: !2D'
       MOV EDX,[RBX+VIEW_INDEX.FA]
       CMP RDX,[InputSize::]
       JNB .90:
       MOVZXW EAX,[R8+RDX]
       MOV [NrOfSections],EAX
       CALL SaveViewIndex::
       MOV [RBX+VIEW_INDEX.Rem],=B'Time&Date stamp: !4T UTC'
       MOV [RBX+VIEW_INDEX.Size],4
       CALL SaveViewIndex::
       MOV [RBX+VIEW_INDEX.Rem],=B'FA of symbol table: !4Hh'
       MOV EDX,[RBX+VIEW_INDEX.FA]
       MOV EAX,[R8+RDX]
       MOV [FaOfSymbolTable],EAX
       CALL SaveViewIndex::
       MOV [RBX+VIEW_INDEX.Rem],=B'Number of symbols: !4Hh=!4D'
       MOV EDX,[RBX+VIEW_INDEX.FA]
       MOV EAX,[R8+RDX]
       MOV [NrOfSymbols],EAX
       CALL SaveViewIndex::
       MOV [RBX+VIEW_INDEX.Rem],=B'Size of optional header: !2Hh=!2D'
       MOV [RBX+VIEW_INDEX.Size],2
       CALL SaveViewIndex::
       MOV [RBX+VIEW_INDEX.Rem],=B'Characteristics !2Hh: !1$'
       CALL SaveViewIndex::
    .90:RET
      ENDP AnalyzeCoffFileHeader

↑ AnalyzeCoffRawData

Structure
  PFCOFF_SECTION_HEADER
Manual
  [MS_PECOFF]
Input
  RBX=^ViewIndex (working structure) with .FA set.
  R8=InputPtr (file loaded in memory)
Output
  Analyzed elements are stored as ViewIndex records to File_index.
Clobbers
  RAX,RCX
Calls
  SaveViewIndex

    AnalyzeCoffRawData PROC
        MOV ECX,[NrOfSections]
        TEST ECX
        JZ .90:
        MOV EDX,[FaOfSectionHeaders] ;Size of COFF file header, FA of 1st section header.
    .10:
        JSt [R8+RDX+8+7*4],0x0000_0020 | 0x2000_0000, .30: ; COFF_FILE_HEADER.Characteristics:CNT_CODE|MEM_EXECUTE
    .20:LEA RAX,[=B'Raw data in section !2$']
        JMP .40:
    .30:JNSt [Status::],ArgWidth16::,.33:
        LEA RAX,[=B'Raw 16-bit code in section !2$']
        JMP .40:
    .33:JNSt [Status::],ArgWidth32::,.36:
        LEA RAX,[=B'Raw 32-bit code in section !2$']
        JMP .40:
    .36:JNSt [Status::],ArgWidth64::,.20:
        LEA RAX,[=B'Raw 64-bit code in section !2$']
        ;JMP .40:
    .40:MOV [RBX+VIEW_INDEX.Rem],RAX
        CMP EDX,[InputSize::]
        JNB .90:
        MOV EAX,[R8+RDX+8+4+4+4] ; FA of FA of raw data.
        TEST EAX
        JZ .80:
        MOV [RBX+VIEW_INDEX.FA],EAX
        MOV EAX,[R8+RDX+8+4+4]   ; FA of FA of raw size.
        TEST EAX
        JZ .80:
        OR EAX,Level2
        MOV [RBX+VIEW_INDEX.Size],EAX
        CALL SaveViewIndex::

        JNSt [R8+RDX+8+7*4],0x0000_0020 | 0x2000_0000, .55: ; COFF_FILE_HEADER.Characteristics:CNT_CODE|MEM_EXECUTE
    .50: ; Section named .idata will be dumped as data although it might be flagged executable.
        MOV RAX,'.idata'
        CMP [R8+RDX+0],RAX
        JNE .60:
    .55:MOV [RBX+VIEW_INDEX.Rem],=B'!X'  ; Dump as data.
        JMP .70:
    .60:MOV [RBX+VIEW_INDEX.Rem],=B'!V'  ; Disassemble as code.
    .70:CALL SaveViewIndex::
    .80:ADD EDX,40               ; Size of section header.
        DEC ECX
        JNZ .10:                ; The next section header.
    .90:RET
       ENDP AnalyzeCoffRawData

↑ AnalyzeCoffRelocations

Structure
  PFCOFF_RELOCATION
Manual
  [MS_PECOFF]
Input
  RBX=^ViewIndex (working structure) with .FA set.
  R8=InputPtr (file loaded in memory)
Output
  Analyzed elements are stored as ViewIndex records to File_index.
Clobbers
  RAX,RCX
Calls
  SaveViewIndex

    AnalyzeCoffRelocations PROC
        MOV ECX,[NrOfSections]
        TEST ECX
        JZ .90:
        MOV EDX,[FaOfSectionHeaders]       ; Size of COFF file header, FA of 1st section header.
        CMP RDX,[InputSize::]
        JNB .90:
    .10:MOV R11,RDX                        ; Temprary save FaOfSectionHeaders to R11.
        MOV [SectionNumber],ECX            ; NrOfSections, NrOfSections-1, NrOfSections-2, ,,,
        MOV [RBX+VIEW_INDEX.Rem],=B'Relocations in section !2$'
        MOV EAX,[R8+RDX+8+4+4+4+4]         ; FA of FA of relocations.
        TEST EAX
        JZ .80:                            ; Skip if there are no relocations in this section.
        MOV [RBX+VIEW_INDEX.FA],EAX
        MOVZXW EAX,[R8+RDX+8+4+4+4+4+4+4]  ; Number of relocations.
        TEST EAX
        JZ .80:                            ; Skip if there are no relocations in this section.
        MOV ECX,EAX                        ; Number of relocations.
        LEA EAX,[EAX+4*EAX]
        ADD EAX,EAX                        ; Multiply the number by size of one relocation (10).
        OR EAX,Level2
        MOV [RBX+VIEW_INDEX.Size],EAX
        CALL SaveViewIndex::               ; Level 2.
    .50:MOV [RBX+VIEW_INDEX.Rem],=B'Relocation at !4Hh'
        MOV [RBX+VIEW_INDEX.Size],10+Level1
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Relative VA: !4Hh'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Symbol #!4D: !8$'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Size],2
        MOV EDX,[RBX+VIEW_INDEX.FA]
        CMP RDX,[InputSize::]
        JNB .90:
        MOVZXW EAX,[R8+RDX]
        JSt [Status::],ArgWidth64,.55:
        Dispatch AX,0x0006,0x0007,0x0014
        MOV [RBX+VIEW_INDEX.Rem],=B'Type: !2H'
        JMP .60:
    .0x0006:MOV [RBX+VIEW_INDEX.Rem],=B'Absolute DWORD VA'
        JMP .60:
    .0x0007:MOV [RBX+VIEW_INDEX.Rem],=B'Absolute DWORD RVA'
        JMP .60:
    .0x0014:MOV [RBX+VIEW_INDEX.Rem],=B'Relative DWORD'
        JMP .60:
    .55:Dispatch AX,0x0001,0x0002,0x0003,0x0004
        MOV [RBX+VIEW_INDEX.Rem],=B'Type: !2H'
        JMP .60:
    .0x0001:MOV [RBX+VIEW_INDEX.Rem],=B'Absolute QWORD VA'
        JMP .60:
    .0x0002:MOV [RBX+VIEW_INDEX.Rem],=B'Absolute DWORD VA'
        JMP .60:
    .0x0003:MOV [RBX+VIEW_INDEX.Rem],=B'Absolute DWORD RVA'
        JMP .60:
    .0x0004:MOV [RBX+VIEW_INDEX.Rem],=B'Relative DWORD'
        ;JMP .60:
    .60:CALL SaveViewIndex::
        DEC RCX
        JNZ .50:
    .80:MOV RDX,R11
        ADD EDX,40               ; Size of the next section header.
        MOV ECX,[SectionNumber]
        DEC ECX
        JNZ .10:
    .90:RET
       ENDP AnalyzeCoffRelocations

↑ AnalyzeCoffSectionHeader

  Linkable file format.

Structure
  PFCOFF_SECTION_HEADER
Manual
  [MS_PECOFF]
Input
  RBX=^ViewIndex (working structure) with .FA set.
  R8=InputPtr (file loaded in memory)
Output
  Analyzed elements are stored as ViewIndex records to File_index.
Clobbers
  RAX,RCX
Calls
  SaveViewIndex

    AnalyzeCoffSectionHeader: PROC
        MOV [SectionIndex],1
        MOV [RBX+VIEW_INDEX.Rem],=B'COFF Section header #!9$: !2$'
        MOV [RBX+VIEW_INDEX.Size],40+Level1
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Section name: !2$'
        MOV [RBX+VIEW_INDEX.Size],8
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Virtual size: !4Hh=!4D'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Virtual address: !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Size of raw data: !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'FA of raw data: !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'FA of relocations: !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'FA of line numbers: !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Number of relocations: !2D'
        MOV [RBX+VIEW_INDEX.Size],2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Number of line numbers: !2D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Flags: !3$'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex::
        RET
      ENDP AnalyzeCoffSectionHeader

↑ AnalyzeCoffStringTable

Structure
  PFCOFF_SECTION_HEADER
Manual
  [MS_PECOFF]
Input
  RBX=^ViewIndex (working structure) with .FA set.
  R8=InputPtr (file loaded in memory)
Output
  Analyzed elements are stored as ViewIndex records to File_index.
Clobbers
  RAX,RCX
Calls
  SaveViewIndex

    AnalyzeCoffStringTable PROC
         MOV [RBX+VIEW_INDEX.Rem],=B'Table of strings'
         MOV EDX,[RBX+VIEW_INDEX.FA]
         CMP EDX,[InputSize::]
         JNB .90:
         MOV EAX,[R8+RDX]                  ; Get string table size.
         MOV [SizeOfStringTable],EAX
         OR EAX,Level2
         MOV [RBX+VIEW_INDEX.Size],EAX
         CALL SaveViewIndex::
         MOV [RBX+VIEW_INDEX.Rem],=B'Size of string table: !4Hh=!4D'
         MOV [RBX+VIEW_INDEX.Size],4
         CALL SaveViewIndex::
         MOV [RBX+VIEW_INDEX.Rem],=B'Body of string table'
         MOV EAX,[SizeOfStringTable]
         SUB EAX,4
         OR EAX,Level1
         MOV [RBX+VIEW_INDEX.Size],EAX
         CALL SaveViewIndex::
         MOV [RBX+VIEW_INDEX.Rem],=B'!X'
         CALL SaveViewIndex::
    .90: RET
       ENDP AnalyzeCoffStringTable

↑ AnalyzeCoffSymbolTable

Structure
  PFCOFF_SECTION_HEADER
Manual
  [MS_PECOFF]
Input
  RBX=^ViewIndex (working structure) with .FA set.
  R8=InputPtr (file loaded in memory)
Output
  Analyzed elements are stored as ViewIndex records to File_index.
Clobbers
  RAX,RCX
Calls
  SaveViewIndex

    AnalyzeCoffSymbolTable: PROC
         MOV [RBX+VIEW_INDEX.Rem],=B'Table of symbols'
         MOV ECX,[NrOfSymbols]
         TEST ECX
         JZ .90:
         LEA EAX,[ECX+8*ECX]
         ADD EAX,EAX                       ; Multiply by symbol size (18).
         JZ .90:
         MOV ECX,EAX                       ; Size of symbol table.
         OR EAX,Level2
         MOV [RBX+VIEW_INDEX.Size],EAX
         MOV EAX,[FaOfSymbolTable]
         ADD ECX,EAX
         MOV [FaOfStringTable],ECX
         CMP RCX,[InputSize::]
         JNB .90:
         MOV [RBX+VIEW_INDEX.FA],EAX
         CALL SaveViewIndex::
         MOV ECX,[NrOfSymbols]
    .20: MOV [SymbolNumber],ECX             ; Total number of symbols.
         MOV [RBX+VIEW_INDEX.Rem],=B'Symbol #!7$: !4$'  ; Fn7$CoffSymbolIndexStore, Fn4$CoffIndexName
         MOV [RBX+VIEW_INDEX.Size],18+Level1
         CALL SaveViewIndex::
         MOV [RBX+VIEW_INDEX.Rem],=B'Name: !4$'
         MOV [RBX+VIEW_INDEX.Size],8
         CALL SaveViewIndex::
         MOV [RBX+VIEW_INDEX.Rem],=B'Value: !4Hh=!4D'
         MOV [RBX+VIEW_INDEX.Size],4
         CALL SaveViewIndex::
         MOV [RBX+VIEW_INDEX.Rem],=B'!5$'  ; Section by Fn5$CoffSymbolSection
         MOV [RBX+VIEW_INDEX.Size],2
         CALL SaveViewIndex::
         MOV [RBX+VIEW_INDEX.Rem],=B'!6$'  ; Fn6$CoffSymbolType
         MOV [RBX+VIEW_INDEX.Size],4
         CALL SaveViewIndex::
         MOV EDX,[RBX+VIEW_INDEX.FA]
         MOVZXB ECX,[R8+RDX+17-18]         ; Aux
         JRCXZ .30:
    .25: MOV [RBX+VIEW_INDEX.Rem],=B'!X'   ; Auxilliary symbol(s).
         MOV [RBX+VIEW_INDEX.Size],18
         CALL SaveViewIndex::
         DEC [SymbolNumber]
         LOOP .25:
    .30: MOV ECX,[SymbolNumber]
         TEST ECX
         JBE .90:
         DEC ECX
         JNZ .20:
    .90: RET
       ENDP AnalyzeCoffSymbolTable

↑ AnalyzeElfDynamic
Structure
  PFELF_DYN32 PFELF_DYN64
Manual
  [ELF32] [ELF64]
Input
  RBX=^ViewIndex pointing to dynamic section
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
  [Status::] ArgWidthMask specifies program width 32 or 64 bits.
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    AnalyzeElfDynamic: PROC
        MOV EAX,[RBX+VIEW_INDEX.Size]
        AND EAX,0x0FFF_FFFF
        ADD EAX,[RBX+VIEW_INDEX.FA]
        MOV [FaOfDynamicEnd],EAX
        JSt [Status::],ArgWidth64,.50:
    .20:MOV [RBX+VIEW_INDEX.Rem],=B'!8y'
        MOV [RBX+VIEW_INDEX.Size],8
        CALL SaveViewIndex::
        MOV EDX,[RBX+VIEW_INDEX.FA]
        CMP EDX,[FaOfDynamicEnd]
        JB .20:
        JMP .90:
    .50:MOV [RBX+VIEW_INDEX.Rem],=B'!16y'
        MOV [RBX+VIEW_INDEX.Size],16
        CALL SaveViewIndex::
        MOV EDX,[RBX+VIEW_INDEX.FA]
        CMP EDX,[FaOfDynamicEnd]
        JB .50:
    .90:RET
      ENDP AnalyzeElfDynamic

↑ AnalyzeElfHash
[ELF64]
Input
  RBX=^ViewIndex pointing to dynamic section
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    AnalyzeElfHash: PROC
        MOV EAX,[RBX+VIEW_INDEX.Size]
        AND EAX,0x0FFF_FFFF
        MOV EDX,EAX
        ADD EAX,[RBX+VIEW_INDEX.FA]
        MOV [FaOfHashEnd],EAX
        MOV [RBX+VIEW_INDEX.Rem],=B'Number of buckets: !4D'
        MOV [RBX+VIEW_INDEX.Size],4
        MOV EAX,[RBX+VIEW_INDEX.FA]
        CMP RAX,[InputSize::]
        JNB .90:
        MOV ECX,[R8+RAX]
        SHR EDX,2
        CMP ECX,EDX
        JB .10:
        MOV ECX,EDX
    .10:CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Number of symbols: !4D'
        CALL SaveViewIndex::
        CMP ECX,300
        JNB .90:
    .20:MOV [RBX+VIEW_INDEX.Rem],=B'Bucket !4D'
        CALL SaveViewIndex::
        LOOP .20:
    .30:MOV EDX,[RBX+VIEW_INDEX.FA]
        CMP EDX,[FaOfHashEnd]
        JNB .90:
        MOV [RBX+VIEW_INDEX.Rem],=B'Symbol #!4D'
        CALL SaveViewIndex::
        JMP .30:
    .90:RET
      ENDP AnalyzeElfHash

↑ AnalyzeElfFileHeader

  32-bit linkable module format.

Structure
  PFELF_EHDR32 PFELF_EHDR64
Extension
  .obj
Manual
  [ELF32] [ELF64]
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
  [Status::] ArgWidthMask specifies program width 32 or 64 bits.
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    AnalyzeElfFileHeader: PROC
        JSt [Status::],ArgWidth64,.50:
        MOV [RBX+VIEW_INDEX.Rem],=B'ELF32 file header'
        MOV [RBX+VIEW_INDEX.Size],52+Level2
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'Signature ELF32'
        MOV [RBX+VIEW_INDEX.Size],16
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'File type !2G'
        MOV [RBX+VIEW_INDEX.Size],2
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'Machine type !2M'
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'Version !4D'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'Entry: !4Hh=!4D'
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'FA of program headers: !4Hh=!4D'
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOV EAX,[R8+RDX]
        MOV [FaOfElfProgramHeaders],EAX
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'FA of section headers: !4Hh=!4D'
        MOV EDX,[RBX+VIEW_INDEX.FA]
        CMP EDX,[InputSize::]
        JNB .90:
        MOV EAX,[R8+RDX]
        MOV [FaOfElfSectionHeaders],EAX
        CMP RAX,[InputSize::]
        JNB .90:
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'CPU flags: !4D'
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'Size of file header: !2Hh=!2D'
        MOV [RBX+VIEW_INDEX.Size],2
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'Size of program header: !2Hh=!2D'
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'Number of program headers: !2D'
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOVZXW EAX,[R8+RDX]
        MOV [NrOfElfProgramHeaders],EAX
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'Size of section header: !2Hh=!2D'
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'Number of section headers: !2D'
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOVZXW EAX,[R8+RDX]
        MOV [NrOfElfSectionHeaders],EAX
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'String table section ordinal: !2D'
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOVZXW EAX,[R8+RDX]      ; shstrndx.
        MOV ECX,40               ; Size of 32-bit section header.
        MUL RCX
        MOV EDX,[R8+20h]         ; FA of section headers in 32-bit file header.
        LEA EAX,[EAX+EDX+10h]    ; FA of 32-bit section .shstrtab
        CMP RAX,[InputSize::]
        JNB .90
        MOV ECX,[R8+RAX]         ; FA of data in 32-bit section .shstrtab.
        MOV [FaOfShstrtabData],ECX
        CALL SaveViewIndex
        JMP .90:
    .50:MOV [RBX+VIEW_INDEX.Rem],=B'ELF64 file header'
        MOV [RBX+VIEW_INDEX.Size],64+Level2
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'Signature ELF64'
        MOV [RBX+VIEW_INDEX.Size],16
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'File type !2G'
        MOV [RBX+VIEW_INDEX.Size],2
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'Machine type !2M'
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'Version !4D'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'Entry: !8Hh=!8D'
        MOV [RBX+VIEW_INDEX.Size],8
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'FA of program headers: !8Hh=!8D'
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOV RAX,[R8+RDX]
        CMP RAX,[InputSize::]
        JNB .90:
        MOV [FaOfElfProgramHeaders],EAX
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'FA of section headers: !8Hh=!8D'
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOV RAX,[R8+RDX]
        MOV [FaOfElfSectionHeaders],EAX
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'CPU flags: !4D'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'Size of file header: !2Hh=!2D'
        MOV [RBX+VIEW_INDEX.Size],2
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'Size of program header: !2Hh=!2D'
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'Number of program headers: !2D'
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOVZXW EAX,[R8+RDX]
        MOV [NrOfElfProgramHeaders],EAX
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'Size of section header: !2Hh=!2D'
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'Number of section headers: !2D'
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOVZXW EAX,[R8+RDX]
        MOV [NrOfElfSectionHeaders],EAX
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'String table section ordinal: !2D'
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOVZXW EAX,[R8+RDX]      ; shstrndx.
        MOV ECX,64               ; Size of 64-bit section header.
        MUL RCX
        MOV RDX,[R8+28h]         ; FA of section headers in 64-bit file header.
        LEA EAX,[EAX+EDX+18h]    ; FA of 64-bit section .shstrtab data.
        CMP RAX,[InputSize::]
        JNB .90:
        MOV ECX,[R8+RAX]         ; FA of data in 64-bit section .shstrtab.
        MOV [FaOfShstrtabData],ECX
        CALL SaveViewIndex
    .90:RET
       ENDP AnalyzeElfFileHeader

↑ AnalyzeElfNote
[ELF32] [ELF64]
Input
  RBX=^ViewIndex pointing to dynamic section
  R8=InputPtr (file loaded in memory)
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    AnalyzeElfNote: PROC
        MOV EAX,[RBX+VIEW_INDEX.Size]
        AND EAX,0x0FFF_FFFF
        ADD EAX,[RBX+VIEW_INDEX.FA]
        MOV [FaOfNoteEnd],EAX
        MOV [RBX+VIEW_INDEX.Rem],=B'Vendor name size: !4D'
        MOV [RBX+VIEW_INDEX.Size],4
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOV ECX,[R8+RDX]
        ADD ECX,7
        AND ECX,0x0000_00F8      ; Round up vendor name size to 8.
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Data name size: !4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Data type: !4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Vendor: !X'
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'!X'
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOV ECX,[FaOfNoteEnd]
        SUB ECX,EDX
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        RET
      ENDP AnalyzeElfNote

↑ AnalyzeElfProgramHeader
Structure
  PFELF_PHDR32 PFELF_PHDR64
Extension
  .obj
Manual
  [ELF32] [ELF64]
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
  [Status::] ArgWidthMask specifies program width 32 or 64 bits.
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    AnalyzeElfProgramHeader: PROC
        JSt [Status::],ArgWidth64,.50:
        MOV [RBX+VIEW_INDEX.Rem],=B'Program header of sections !22$'
        MOV ECX,32+Level2
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Type: !4P'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'FA: !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'VA: !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'PA: !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Size  in  file: !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Size in memory: !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Flags: !4Q'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Alignment: !4Hh=!4D'
        CALL SaveViewIndex::
        JMP .90:
    .50:MOV [RBX+VIEW_INDEX.Rem],=B'Program header of sections !22$'
        MOV ECX,56+Level2
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Type: !4P'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Flags: !4Q'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Size],8
        MOV [RBX+VIEW_INDEX.Rem],=B'FA: !8Hh'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'VA: !8Hh'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'PA: !8Hh'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Size in file: !8Hh=!8D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Size in memory: !8Hh=!8D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Alignment: !8Hh=!8D'
        CALL SaveViewIndex::
    .90:RET
      ENDP AnalyzeElfProgramHeader

↑ AnalyzeElfRel
[ELF32] [ELF64]
Input
  RBX=^ViewIndex pointing to dynamic section
  R8=InputPtr (file loaded in memory)
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    AnalyzeElfRel PROC
        MOV EAX,[RBX+VIEW_INDEX.Size]
        AND EAX,0x0FFF_FFFF
        ADD EAX,[RBX+VIEW_INDEX.FA]
        MOV [FaOfRelEnd],EAX
        JSt [Status::],ArgWidth64,.50:
    .20:MOV EDX,[RBX+VIEW_INDEX.FA]
        CMP RDX,[InputSize::]
        JNB .90:
        CMP EDX,[FaOfRelEnd]
        JNB .90:
        MOV [RBX+VIEW_INDEX.Rem],=B'Relocation at !4Hh'
        MOV [RBX+VIEW_INDEX.Size],4+Level1
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'VA|offset: !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'!1Z'
        MOV [RBX+VIEW_INDEX.Size],1
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'by symbol #!3D'
        MOV [RBX+VIEW_INDEX.Size],3
        CALL SaveViewIndex::
        JMP .20:
    .50:MOV EDX,[RBX+VIEW_INDEX.FA]
        CMP RDX,[InputSize::]
        JNB .90:
        CMP EDX,[FaOfRelEnd]
        JB .90:
        MOV [RBX+VIEW_INDEX.Rem],=B'Relocation at !8Hh'
        MOV [RBX+VIEW_INDEX.Size],8+Level1
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'VA|offset: !8Hh=!8D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'!4Z'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'by symbol #!4D'
        CALL SaveViewIndex::
        JMP .50:
    .90:RET
      ENDP AnalyzeElfRel

↑ AnalyzeElfRela
[ELF32] [ELF64]
Input
  RBX=^ViewIndex pointing to dynamic section
  R8=InputPtr (file loaded in memory)
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    AnalyzeElfRela PROC
        MOV EAX,[RBX+VIEW_INDEX.Size]
        AND EAX,0x0FFF_FFFF
        ADD EAX,[RBX+VIEW_INDEX.FA]
        MOV [FaOfRelaEnd],EAX
        JSt [Status::],ArgWidth64,.50:
    .20:MOV EDX,[RBX+VIEW_INDEX.FA]
        CMP RDX,[InputSize::]
        JNB .90:
        CMP EDX,[FaOfRelaEnd]
        JNB .90:
        MOV [RBX+VIEW_INDEX.Rem],=B'Relocation at !4Hh'
        MOV [RBX+VIEW_INDEX.Size],4+Level1
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'VA|offset: !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'!1Z'
        MOV [RBX+VIEW_INDEX.Size],1
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'by symbol #!3D'
        MOV [RBX+VIEW_INDEX.Size],3
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Addend: !4Hh=!4D'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex::
        JMP .20:
    .50:MOV EDX,[RBX+VIEW_INDEX.FA]
        CMP RDX,[InputSize::]
        JNB .90:
        CMP EDX,[FaOfRelaEnd]
        JNB .90:
        MOV [RBX+VIEW_INDEX.Rem],=B'Relocation at !8Hh'
        MOV [RBX+VIEW_INDEX.Size],8+Level1
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'VA|offset: !8Hh=!8D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'!4Z'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'by symbol #!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Addend: !8Hh=!8D'
        MOV [RBX+VIEW_INDEX.Size],8
        CALL SaveViewIndex::
        JMP .50:
    .90:RET
      ENDP AnalyzeElfRela

↑ AnalyzeElfSectionHeader32
Structure
  PFELF_SHDR32 PFELF_SHDR64
Extension
  .obj
Manual
  [ELF32] [ELF64]
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
  [Status::] ArgWidthMask specifies program width 32 or 64 bits.
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    AnalyzeElfSectionHeader32: PROC
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOV [FaOfThisSectionHeader],EDX
        MOV [RBX+VIEW_INDEX.Rem],=B'Section header #!1R !4N'
        MOV [RBX+VIEW_INDEX.Size],40+Level2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Size],4
        MOV [RBX+VIEW_INDEX.Rem],=B'Name: !4N'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Type: !4S'
        MOV EDX,[RBX+VIEW_INDEX.FA]
        CMP RDX,[InputSize::]
        JNB .90:
        MOV ECX,[R8+RDX]         ; RCX=section type.
        CMP ECX,256
        JA .90:
        CALL SaveViewIndex::
        ; Analyze of section will be temporary suspended
        ;  and section types "progbits","strtab" etc analyzed now.
        Dispatch CL,1d,3d,5d,2d,11d,6d,7d,4d,9d
        JMP .40:
    .1d:                         ; progbits
    .2d:                         ; symtab
    .3d:                         ; strtab
    .4d:                         ; rela
    .5d:                         ; hash
    .6d:                         ; dynamic
    .7d:                         ; note
    .9d:                         ; rel
    .11d:                        ; dynsym
        PUSHQ [RBX+VIEW_INDEX.FA]; FA and Size which pointed to SHDR32.sh_flags
         MOV EDX,[RBX+VIEW_INDEX.FA]
         CMP RDX,[InputSize::]
         JNB .90:
         MOV EAX,[R8+RDX-8+10h]    ; SHDR32.sh_offset.
         CMP RAX,[InputSize::]
         JNB .90:
         MOV [RBX+VIEW_INDEX.FA],EAX
         MOV EAX,[R8+RDX-8+14h]    ; SHDR32.sh_size.
         OR EAX,Level2
         MOV [RBX+VIEW_INDEX.Size],EAX
         MOV [RBX+VIEW_INDEX.Rem],=B'Contents of section #!20$'
         CALL SaveViewIndex::
         Dispatch CL,1D,3D,5D,2D,11D,6D,4D,9D,7D ; Test section type again.
    .1D:                         ; progbits
    .3D:                         ; strtab
         MOV EAX,[R8+RDX-8+8]    ; Flags.
         JNSt EAX,4,.3H:         ; Executable section?
         JNSt EAX,2,.3H:         ; Readable section?
         MOV [RBX+VIEW_INDEX.Rem],=B'!V' ; Disassemble raw contents of the section.
         JMP .3J:
    .3H: MOV [RBX+VIEW_INDEX.Rem],=B'!X' ; Hexadump raw contents of the section.
    .3J: CALL SaveViewIndex::
         JMP .30:
    .5D:                         ; hash
         CALL AnalyzeElfHash
         JMP .30:
    .7D: CALL AnalyzeElfNote
         JMP .30:
    .4D: CALL AnalyzeElfRela
         JMP .30:
    .9D: CALL AnalyzeElfRel
         JMP .30:
    .2D:                         ; symtab
    .11D:                        ; dynsym
         CALL AnalyzeElfSymbols
         JMP .30:
    .6D:                         ; dynamic
         MOV ECX,[RBX+VIEW_INDEX.Size]
         AND ECX,0x0FFF_FFFF
         ADD ECX,[RBX+VIEW_INDEX.FA]
         MOV [FaOfDynamicEnd],ECX
         MOV [RBX+VIEW_INDEX.Size],4+4
    .20: MOV EDX,[RBX+VIEW_INDEX.FA]
         CMP RDX,[InputSize::]
         JNB .90:
         CMP EDX,[FaOfDynamicEnd]
         JNB .30:
         MOV [RBX+VIEW_INDEX.Rem],=B'!8y'
         CALL SaveViewIndex::
         JMP .20:
    .30:POPQ [RBX+VIEW_INDEX.FA]
    .40:MOV [RBX+VIEW_INDEX.Rem],=B'Flags: !4q' ; Continue with analyzing section header.
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'VA: !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'FA: !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Section size: !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Link to section: #!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Info of this section: !4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Alignment: !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Size of one entry: !4D'
        CALL SaveViewIndex::
    .90:RET
      ENDP AnalyzeElfSectionHeader32

↑ AnalyzeElfSectionHeader64
Structure
  PFELF_SHDR32 PFELF_SHDR64
Extension
  .obj
Manual
  [ELF32] [ELF64]
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
  [Status::] ArgWidthMask specifies program width 32 or 64 bits.
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    AnalyzeElfSectionHeader64: PROC
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOV [FaOfThisSectionHeader],EDX
        MOV [RBX+VIEW_INDEX.Rem],=B'Section header #!1R !4N'
        MOV [RBX+VIEW_INDEX.Size],64+Level2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Size],4
        MOV [RBX+VIEW_INDEX.Rem],=B'Name: !4N'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Type: !4S'
        MOV EDX,[RBX+VIEW_INDEX.FA]
        CMP RDX,[InputSize::]
        JNB .90:
        MOV ECX,[R8+RDX]         ; RCX=section type.
        CMP ECX,256
        JA .90:
        CALL SaveViewIndex::
        ; Analyze of section will be temporarily suspended
        ;  and section types "progbits","strtab" etc analyzed now.
        Dispatch CL,1d,2d,3d,4d,5d,6d,7d,9d,11d
        JMP .40:                 ; Do nothing for sections 0="null", 8="nobits" etc.
    .1d:                         ; progbits
    .2d:                         ; symtab
    .3d:                         ; strtab
    .4d:                         ; rela
    .5d:                         ; hash
    .6d:                         ; dynamic
    .7d:                         ; note
    .9d:                         ; rel
    .11d:                        ; dynsym
        PUSHQ [RBX+VIEW_INDEX.FA]; .FA and .Size which pointed to SHDR32.sh_flags
         MOV EDX,[RBX+VIEW_INDEX.FA]
         MOV RAX,[R8+RDX-4-4+18h]; SHDR64.sh_offset.
         MOV [RBX+VIEW_INDEX.FA],EAX
         MOV RAX,[R8+RDX-4-4+20h]; SHDR64.sh_size.
         OR EAX,Level2
         MOV [RBX+VIEW_INDEX.Size],EAX
         MOV [RBX+VIEW_INDEX.Rem],=B'Contents of section #!20$'
         CALL SaveViewIndex::
         Dispatch CL,1D,3D,5D,2D,11D,6D,4D,9D,7D
    .1D:                         ; progbits
    .3D:                         ; strtab
         MOV RAX,[R8+RDX-4-4+8]  ; Flags.
         JNSt EAX,4,.3H:         ; Executable section?
         JNSt EAX,2,.3H:         ; Readable section?
         MOV [RBX+VIEW_INDEX.Rem],=B'!V' ; Disassemble raw contents of the section.
         JMP .3J:
    .3H: MOV [RBX+VIEW_INDEX.Rem],=B'!X' ; Hexadump raw contents of the section.
    .3J: CALL SaveViewIndex::
         JMP .30:
    .2D:                         ; symtab
    .11D:                        ; dynsym
         CALL AnalyzeElfSymbols
         JMP .30:
    .5D: CALL AnalyzeElfHash
         JMP .30:
    .7D: CALL AnalyzeElfNote
         JMP .30:
    .4D: CALL AnalyzeElfRela
         JMP .30:
    .9D: CALL AnalyzeElfRel
         JMP .30:
    .6D:                         ; dynamic
         MOV ECX,[RBX+VIEW_INDEX.Size]
         AND ECX,0x0FFF_FFFF
         ADD ECX,[RBX+VIEW_INDEX.FA]
         MOV [FaOfDynamicEnd],ECX
         MOV [RBX+VIEW_INDEX.Size],8+8
    .20: MOV EDX,[RBX+VIEW_INDEX.FA]
         CMP RDX,[InputSize::]
         JNB .90:
         CMP EDX,[FaOfDynamicEnd]
         JNB .30:
         MOV [RBX+VIEW_INDEX.Rem],=B'!16y'
         CALL SaveViewIndex::
         JMP .20:
    .30:POPQ [RBX+VIEW_INDEX.FA]
    .40:MOV [RBX+VIEW_INDEX.Rem],=B'Flags: !8q'
        MOV [RBX+VIEW_INDEX.Size],8
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'VA: !8Hh=!8D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'FA: !8Hh=!8D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Section size: !8Hh=!8D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Link to section: #!4D'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Info of this section: !4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Alignment: !8Hh=!8D'
        MOV [RBX+VIEW_INDEX.Size],8
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Size of one entry: !8D'
        CALL SaveViewIndex::
    .90:RET
      ENDP AnalyzeElfSectionHeader64

↑ AnalyzeElfSymbols
Structure
  PFELF_SYM2 PFELF_SYM64
Manual
  [ELF32] [ELF64]
Input
  RBX=^ViewIndex pointing to symbol table (.symtab or .dynsym).
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
  [Status::] ArgWidthMask specifies program width 32 or 64 bits.
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    AnalyzeElfSymbols: PROC
        MOV EAX,[RBX+VIEW_INDEX.Size]
        AND EAX,0x0FFF_FFFF
        ADD EAX,[RBX+VIEW_INDEX.FA]
        MOV [FaOfSymbolsEnd],EAX
        JSt [Status::],ArgWidth64,.50:
    .20:MOV [RBX+VIEW_INDEX.Rem],=B'Symbol #!1r !21$'
        MOV [RBX+VIEW_INDEX.Size],16+Level1
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Name: !21$'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Value: !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Size: !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Type: !1s'
        MOV [RBX+VIEW_INDEX.Size],2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'In section !2U'
        CALL SaveViewIndex::
        MOV EDX,[RBX+VIEW_INDEX.FA]
        CMP EDX,[FaOfSymbolsEnd]
        JB .20:
        JMP .90:
    .50:MOV [RBX+VIEW_INDEX.Rem],=B'Symbol #!1r !21$'
        MOV [RBX+VIEW_INDEX.Size],24+Level1
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Name: !21$'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Type: !1s'
        MOV [RBX+VIEW_INDEX.Size],2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'In section !2U'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Value: !8Hh=!8D'
        MOV [RBX+VIEW_INDEX.Size],8
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Size: !8Hh=!8D'
        CALL SaveViewIndex::
        MOV EDX,[RBX+VIEW_INDEX.FA]
        CMP EDX,[FaOfSymbolsEnd]
        JB .50:
    .90:RET
      ENDP AnalyzeElfSymbols

↑ AnalyzeLibcofFileHeader

  Linkable archive file format.

Structure
  PFCOFF_FILE_HEADER
Manual
  [MS_PECOFF]
Input
  RBX=^ViewIndex (working structure)
  R8=InputPtr (file loaded in memory)
Output
  Analyzed elements are stored as ViewIndex records to File_index.
Clobbers
  RAX,RCX
Calls
  SaveViewIndex

    AnalyzeLibcofFileHeader PROC
       MOV [RBX+VIEW_INDEX.Rem],=B'Short import header'
       MOV [RBX+VIEW_INDEX.Size],20+Level2
       CALL SaveViewIndex::
       MOV [RBX+VIEW_INDEX.Rem],=B'Import signature: !4Hh'
       MOV [RBX+VIEW_INDEX.Size],4
       CALL SaveViewIndex::
       MOV [RBX+VIEW_INDEX.Rem],=B'Version: !2D'
       MOV [RBX+VIEW_INDEX.Size],2
       CALL SaveViewIndex::
       MOV [RBX+VIEW_INDEX.Rem],=B'Machine: !2Hh: !0$'
       CALL SaveViewIndex::
       MOV [RBX+VIEW_INDEX.Rem],=B'Time&Date stamp: !4T UTC'
       MOV [RBX+VIEW_INDEX.Size],4
       CALL SaveViewIndex::
       MOV [RBX+VIEW_INDEX.Rem],=B'Size of data: !4Hh=!4D'
       CALL SaveViewIndex::
       MOV [RBX+VIEW_INDEX.Rem],=B'Ordinal|hint: !2D'
       MOV [RBX+VIEW_INDEX.Size],2
       CALL SaveViewIndex::
       MOV [RBX+VIEW_INDEX.Rem],=B'Import type: !2I'
       CALL SaveViewIndex::
       RET
      ENDP AnalyzeLibcofFileHeader

↑ AnalyzeLibcofMemberHeader

Structure
  PFLIBCOF_ARCHIVE_MEMBER_HEADER
Manual
  [MS_PECOFF]
Input
  RBX=^ViewIndex (working structure) with .FA set.
  R8=InputPtr (file loaded in memory)
Output
  Analyzed elements are stored as ViewIndex records to File_index.
Clobbers
  RAX,RCX
Calls
  SaveViewIndex

    AnalyzeLibcofMemberHeader PROC
        MOV [RBX+VIEW_INDEX.Rem],=B'Member header !16X'
        MOV [RBX+VIEW_INDEX.Size],60+Level3
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Name: !16X'
        MOV [RBX+VIEW_INDEX.Size],16
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Date: !12L'
        MOV [RBX+VIEW_INDEX.Size],12
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'User: !6X'
        MOV [RBX+VIEW_INDEX.Size],6
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Group: !6X'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Mode: !8X'
        MOV [RBX+VIEW_INDEX.Size],8
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'!15$Member size: !10X'
        MOV [RBX+VIEW_INDEX.Size],10
        MOV EDX,[RBX+VIEW_INDEX.FA]
        LEA RSI,[R8+RDX]
        LodD RSI
        MOV [MemberSize],EAX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Terminating signature: !2Hh'
        MOV [RBX+VIEW_INDEX.Size],2
        CALL SaveViewIndex::
       RET
      ENDP AnalyzeLibcofMemberHeader

↑ AnalyzeMzProgram

  DOS executable file format.

Structure
  PFMZ_DOS_HEADER
Extension
  .exe
Manual
  [MZ]
  [MZEXE]
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    AnalyzeMzProgram PROC
        MOV [RBX+VIEW_INDEX.Rem],=B'MZ program header '
        MOV [RBX+VIEW_INDEX.Size],64+Level2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Signature !2X'
        MOV [RBX+VIEW_INDEX.Size],2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Bytes in the last page !2Hh=!2D'
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOVZXW ECX,[R8+RDX]
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Number of 512-byte pages !2Hh=!2D'
        MOV EDX,[RBX+VIEW_INDEX.FA]
        CMP RDX,[InputSize::]
        JNB .90:
        MOVZXW EAX,[R8+RDX]
        JRCXZ .20:
        DEC EAX
    .20:SHL EAX,9
        ADD EAX,ECX
        MOV [MzBytesFileSize],EAX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Number of relocations !2Hh=!2D'
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOVZXW EAX,[R8+RDX]
        MOV [NrOfRelocations],EAX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Header size in paragraphs incl.relocations !2Hh=!2D'
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOVZXW EAX,[R8+RDX]
        SHL EAX,4                ; Convert paragraphs to bytes.
        MOV [MzHeaderSize],EAX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Min.paragraphs allocated above code !2Hh=!2D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Max.paragraphs allocatable !2Hh=!2D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'SS relative to the MZ program !2Hh'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'SP !2Hh'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Checksum !2Hh=!2D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'IP entry relative to the MZ program body !2Hh=!2D'
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOVZXW EAX,[R8+RDX]
        MOV [MzEntry],EAX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'CS entry relative to the MZ program body !2Hh'
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOVZXW EAX,[R8+RDX]
        SHL EAX,4
        ADD [MzEntry],EAX       ; MzEntry is entry point relative to the start of MZ program.
        ; "# MZ program data" are between 0 and MxEntry.
        ; It should be above 0 and below (MzBytesFileSize-MxHeaderSize),
        ;  otherwise it is invalid and "# MZ program data" is not emited (entire MZ program is then "# MZ program code").
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'FA of relocation table !2Hh=!2D'
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOVZXW EAX,[R8+RDX]
        MOV [FaOfRelocations],EAX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Overlay !2Hh'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Size],32
        MOV [RBX+VIEW_INDEX.Rem],=B'Reserved'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Size],4
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOV EAX,[R8+RDX]
        MOV [FaOfPeSignature],EAX
        MOV [RBX+VIEW_INDEX.Rem],=B'FA of LE/NE/PE header = !4Hh=!4D'
        CALL SaveViewIndex::
        MOV ECX,[NrOfRelocations]
        JRCXZ .50:
        MOV [RBX+VIEW_INDEX.Rem],=B'Relocations'
        MOV EDX,[FaOfRelocations]
        CMP RDX,[InputSize::]
        JNB .90:
        MOV [RBX+VIEW_INDEX.FA],EDX
        SHL ECX,2
        ADD ECX,Level1
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.FA],EDX
        MOV [RBX+VIEW_INDEX.Size],4
        MOV ECX,[NrOfRelocations]
        CMP ECX,65000
        JNB .90:
    .40:MOV [RBX+VIEW_INDEX.Rem],=B'Relocation !4Fh'
        CALL SaveViewIndex::
        LOOP .40:
    .50:

        ; Try to create element "# MZ program data" if MzEntry is above zero.
        MOV ECX,[MzEntry]
        JRCXZ .70:
        MOV EDX,[MzBytesFileSize]
        MOV EAX,[MzHeaderSize]
        SUB EDX,EAX
        JB .90:
        CMP ECX,EDX      ; ECX is MzEntry, EDX is body (code+data) size.
        JNB .60:         ; MzEntry is out, ignore it.
        ; Create element "# MZ program data" between 0 and MzEntry.
        MOV [RBX+VIEW_INDEX.Rem],=B'MZ program data'
        MOV [RBX+VIEW_INDEX.FA],EAX     ; MzHeaderSize.
        OR ECX,Level1
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'!X'
        CALL SaveViewIndex::
        JMP .70:
    .60:MOVD [MzEntry],0
    .70: ; Create element "# MZ program code" between MzEntry (may be 0) and the end of file.
        MOV [RBX+VIEW_INDEX.Rem],=B'MZ program 16-bit code+data'
        MOV ECX,[MzHeaderSize]
        MOV [RBX+VIEW_INDEX.FA],ECX
        MOV EDX,[MzBytesFileSize]
        MOV EAX,EDX
        SUB EDX,ECX         ; EDX is netto code size.
        CMP EAX,0x0490
        JNE .80:
        MOV EAX,[FaOfPeSignature]
        CMPD [R8+RAX],'PE'
        JNE .80:
        MOV EDX,[FaOfPeSignature]
        MOV ECX,[MzHeaderSize]
        SUB EDX,ECX
    .80:MOV EAX,[MzEntry]
        SUB EDX,EAX
        ADD [RBX+VIEW_INDEX.FA],EAX
        OR EDX,Level1
        MOV [RBX+VIEW_INDEX.Size],EDX
        CALL SaveViewIndex
        MOV [RBX+VIEW_INDEX.Rem],=B'!v'
        CALL SaveViewIndex
    .90:RET
       ENDP AnalyzeMzProgram

↑ AnalyzeOmfRecord

  Linkable object module.

Extension
  .obj
Manual
  [OMF]
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
Output
  ZF=1 when LIBEND was just processed.
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    AnalyzeOmfRecord: PROC
        MOV [RBX+VIEW_INDEX.Rem],=B'OMF record !1O'
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOVZXB EAX,[R8+RDX+0]
        MOV [LastOmfRecord],EAX
        CMP AL,0x82              ; LHEADR?
        JNE .05:
        MOV [RBX+VIEW_INDEX.Rem],=B'Module !19$'
        MOVZXW ECX,[R8+RDX+1]
        OR ECX,Level3
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
    .05:MOVZXW ECX,[R8+RDX+1]
        MOV [RecordSize],ECX
        ADD ECX,3+Level2
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'!1O'
        MOV [RBX+VIEW_INDEX.Size],1
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Record size: !2D'
        MOV [RBX+VIEW_INDEX.Size],2
        CALL SaveViewIndex::
        MOV EDX,[RBX+VIEW_INDEX.FA]
        CMPB [R8+RDX-3],0x88       ; COMENT?
        JNE .40:
        MOV AL,[R8+RDX]
        LEA RSI,[=B'No purge, list']
        CMP AL,0x80
        JE .10:
        LEA RSI,[=B'Purge, no list']
        CMP AL,0x40
        JE .10:
        LEA RSI,[=B'No purge, no list']
        CMP AL,0xC0
        JE .10:
        LEA RSI,[=B'Purge, list']
    .10:MOV [RBX+VIEW_INDEX.Rem],RSI
        MOV [RBX+VIEW_INDEX.Size],1
        CALL SaveViewIndex::
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOV AL,[R8+RDX]
        Dispatch AL,0x00,0x9D,0xA0,0xA8,0xA9,0xE9
        LEA RSI,[=B'Comment class !1Hh']
        JMP .20:
    .0x00:LEA RSI,[=B'Class 00h: Translator']
        JMP .20:
    .0x9D:LEA RSI,[=B'Class 9Dh: CPU and memory model']
        JMP .20:
    .0xA0:LEA RSI,[=B'Class A0h: Import|export definition']
        JMP .20:
    .0xA8:LEA RSI,[=B'Class A8h: Weak extern definition']
        JMP .20:
    .0xA9:LEA RSI,[=B'Class A9h: Lazy extern definition']
        JMP .20:
    .0xE9:LEA RSI,[=B'Class E9h: File dependency']
        ;JMP .20:
    .20:MOV [RBX+VIEW_INDEX.Rem],RSI
        CALL SaveViewIndex::
        SUB [RecordSize],2
    .40:MOV [RBX+VIEW_INDEX.Rem],=B'!X'
        MOV ECX,[RecordSize]
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        CMPB [LastOmfRecord],0xF1
        RET
       ENDP AnalyzeOmfRecord

↑ AnalyzeOptionalHeader

  32-bit executable file format component.

Structure
  PFPE_OPTIONAL_HEADER32
Manual
  [MS_PECOFF]
Input
  RBX=^ViewIndex (working structure)
  R8=InputPtr (file loaded in memory)
Output
  Analyzed elements are stored as ViewIndex records to File_index.
Clobbers
  RAX,RCX
Calls
  SaveViewIndex

    AnalyzeOptionalHeader PROC
        MOV [RBX+VIEW_INDEX.Rem],=B'64-bit optional header'
        MOV ECX,240+Level2
        JSt [Status::],ArgWidth64,.10:
        MOV [RBX+VIEW_INDEX.Rem],=B'32-bit optional header'
        MOV ECX,224+Level2
    .10:MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Magic !2Hh=!2D'
        MOV [RBX+VIEW_INDEX.Size],2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Linker version: !10$'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Size of code: !4Hh=!4D'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Size of initialized data:   !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Size of uninitialized data: !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'RVA entry: !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'RVA base code: !4Hh=!4D'
        CALL SaveViewIndex::
        JSt [Status::],ArgWidth64,.20:
        MOV [RBX+VIEW_INDEX.Rem],=B'RVA base data: !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Image base: !4Hh=!4D'
        JMP .25:
    .20:MOV [RBX+VIEW_INDEX.Rem],=B'Image base: !8Hh=!8D'
        MOV [RBX+VIEW_INDEX.Size],8
    .25:CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Section alignment: !4Hh=!4D'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'File alignment:    !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'OS version: !11$'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Image version: !11$'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Subsystem version: !11$'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Win32 version: !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Image size:   !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Headers size: !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Checksum: !4Hh'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Subsystem: !12$'
        MOV [RBX+VIEW_INDEX.Size],2
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'DLL characteristics: !2Hh'
        CALL SaveViewIndex::
        JSt [Status::],ArgWidth64,.40:
        MOV [RBX+VIEW_INDEX.Rem],=B'Size of stack reserve: !4Hh=!4D'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Size of stack commit:  !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Size of heap reserve:  !4Hh=!4D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Size of heap commit:   !4Hh=!4D'
        JMP .45
    .40:MOV [RBX+VIEW_INDEX.Rem],=B'Size of stack reserve: !8Hh=!8D'
        MOV [RBX+VIEW_INDEX.Size],8
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Size of stack commit:  !8Hh=!8D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Size of heap reserve:  !8Hh=!8D'
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Size of heap commit:   !8Hh=!8D'
    .45:CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Loader flags: !4Hh'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Number of data directories: !4D'
        MOV EDX,[RBX+VIEW_INDEX.FA]
        CMP RDX,[InputSize::]
        JNB .90:
        MOV EAX,[R8+RDX]
        MOV [NrOfDataDirectories],EAX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Data directories'
        MOV EAX,[RBX+VIEW_INDEX.FA]
        MOV [FaOfDataDirs],EAX
        MOV ECX,[NrOfDataDirectories]
        MOV EAX,4+4
        MUL RCX
        OR EAX,Level2
        MOV [RBX+VIEW_INDEX.Size],EAX
        CALL SaveViewIndex::
    .70:MOV [RBX+VIEW_INDEX.Rem],=B'PE data directory !13$' ; Fn13$DataDirName
        MOV [RBX+VIEW_INDEX.Size],8+Level1
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'RVA: !4Hh=!4D'
        MOV [RBX+VIEW_INDEX.Size],4
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'Size: !4Hh=!4D'
        CALL SaveViewIndex::
        LOOP .70:
    .90:RET
       ENDP AnalyzeOptionalHeader

↑ AnalyzePE

  Portable executable file format.

Structure
  PFCOFF_FILE_HEADER PFCOFF_SECTION_HEADER PFCOFF_RELOCATION PFCOFF_LINENUMBER PFCOFF_SYMBOL
Extension
  .obj
Manual
  [MS_PECOFF]
Input
  RBX=^ViewIndex
  R8=InputPtr (file loaded in memory)
  [InputSize::] size of input file
  [Status::] ArgWidthMask specifies PE32 or PE64.
Output
  ViewIndex from RBX are repeatedly written to File_index.
Clobbers
  all but RBX, R8.
Calls
  SaveViewIndex

    AnalyzePE: PROC
        JSt [Status::],ArgDynamicLibrary,.20:
        JSt [Status::],ArgWidth64,.10:
        MOV [RBX+VIEW_INDEX.Rem],=B'Format PE32 "!14$" size=!24$ !25$'
        JMP .30:
    .10:MOV [RBX+VIEW_INDEX.Rem],=B'Format PE64 "!14$" size=!24$ !25$'
        JMP .30:
    .20:JSt [Status::],ArgWidth64,.25:
        MOV [RBX+VIEW_INDEX.Rem],=B'Format DLL32 "!14$" size=!24$ !25$'
        JMP .30:
    .25:MOV [RBX+VIEW_INDEX.Rem],=B'Format DLL64 "!14$" size=!24$ !25$'
    .30:MOV [RBX+VIEW_INDEX.FA],0
        MOV RCX,[InputSize::]
        OR ECX,Level4
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        CALL AnalyzeMzProgram
        MOV [RBX+VIEW_INDEX.Rem],=B'PE Headers'
        MOV EAX,[FaOfPeSignature]
        MOV [RBX+VIEW_INDEX.FA],EAX
        JSt [Status::],ArgWidth64,.40:
        MOV ECX,4+20+224+Level3
        JMP .50:
    .40:MOV ECX,4+20+240+Level3
    .50:MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'PE signature'
        MOV ECX,4+Level2
        MOV [RBX+VIEW_INDEX.Size],ECX
        CALL SaveViewIndex::
        MOV [RBX+VIEW_INDEX.Rem],=B'!2X'
        CALL SaveViewIndex::
        CALL AnalyzeCoffFileHeader
        CALL AnalyzeOptionalHeader
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOV [FaOfSectionHeaders],EDX
        MOV EAX,[NrOfSections]
        LEA EAX,[EAX+4*EAX]
        LEA EAX,[8*EAX]                    ; Multiply by section header size (40).
        MOV [RBX+VIEW_INDEX.Rem],=B'COFF section headers'
        OR EAX,Level2
        MOV [RBX+VIEW_INDEX.Size],EAX
        CALL SaveViewIndex::
        MOV ECX,[NrOfSections]
        JRCXZ .70:
        CMP ECX,257
        JNB .90:
    .60:PUSH RCX
          CALL AnalyzeCoffSectionHeader
        POP RCX
        LOOP .60:
    .70:CALL AnalyzeCoffRawData
        CALL AnalyzeCoffRelocations
        CALL AnalyzeCoffSymbolTable
        CALL AnalyzeCoffStringTable
    .90:RET
       ENDP AnalyzePE

↑ Fn00$CoffMachine

  Internal function trigerred by !0$ in VIEW_INDEX.Rem

Input
  RDI=^string where to write function result,
  RBX=^VIEW_INDEX structure,
  R8=InputPtr (file loaded in memory).
Output
  RDI is updated by the output string.
Clobbers
  RAX,RCX,RDX,RSI

    Fn00$CoffMachine PROC
         MOV CX,[R8+RDX]
         Dispatch CX,0x0000,0x014C,0x0200,0x8664,0x01C0,0xAA64
         JMP .90:
    .0x0000:LEA RSI,[=B'UNKNOWN']
         JMP .70:
    .0x014C:LEA RSI,[=B'I386']
         JMP .70:
    .0x0200:LEA RSI,[=B'IA64']
         JMP .70:
    .0x8664:LEA RSI,[=B'AMD64']
         JMP .70:
    .0x01C0:LEA RSI,[=B'ARM']
         JMP .70:
    .0xAA64:LEA RSI,[=B'ARM64']
    .70: LODSB
         CMP AL,0
         JE .90:
         STOSB
         JMP .70:
    .90: RET
        ENDP Fn00$CoffMachine

↑ Fn01$CoffCharacteristics

  Internal function trigerred by !1$ in VIEW_INDEX.Rem

Input
  RDI=^string where to write function result,
  RBX=^VIEW_INDEX structure,
  R8=InputPtr (file loaded in memory).
Output
  RDI is updated by the output string.
Clobbers
  RAX,RCX,RDX,RSI

    Fn01$CoffCharacteristics PROC  ; Input:CX=COFF.Characteristics
         MOV CX,[R8+RDX]
    %bit %SETA 0x01
    name %FOR RELOCS_STRIPPED, EXEC, LINE_NUMS_STRIPPED, SYM_S, AGGR, \
             LARGE_ADDRESS_AWARE, NU, LE, 32BIT_MACHINE, DBG_S, RUN_SWAP, \
             NRUN_SWAP, FS, FILE_DLL, UP_SYS, BE
           TEST CX,%bit
           JZ .No%name:
           LEA RSI,[=B'%name']
           CALL .70:
    .No%name:
           %bit %SETA %bit << 1   ; >>
        %ENDFOR name
        DEC RDI                 ; Remove the last '|'.
        JMP .90:
    .70:LODSB
        CMP AL,0
        JE .80:
        STOSB
        JMP .70:
    .80:MOV AL,'|'
        STOSB
    .90:RET
        ENDP Fn01$CoffCharacteristics

↑ Fn02$CoffSectionName

  Internal function trigerred by !2$ in VIEW_INDEX.Rem

  Function will write the name of section whose FA equals `[RBX+VIEW_INDEX.FA]`.

Input
  RDI=^string where to write function result,
  RBX=^VIEW_INDEX structure,
  R8=InputPtr (file loaded in memory).
Output
  RDI is updated by the output string.
Clobbers
  RAX,RCX,RDX,RSI

    Fn02$CoffSectionName:: PROC     ; Store section name to RDI. RBX is the first element of section header, raw data or relocations.
        MOV EDX,[FaOfSectionHeaders] ; Try all section headers, they start at FA=20.
        MOV ECX,[NrOfSections]

    .10: ; EDX is FA of section headers. EAX is the searched for FA of section header, raw data or relocations.
        MOV EAX,[RBX+VIEW_INDEX.FA] ; The searched for FA of A) section header, B) raw data or C) relocation.
        CMP EAX,EDX              ; A) Pointers to .Name of section EDX header?
        JE .30:
        LEA RSI,[R8+RDX+8+4+4+4] ; B) Pointer to FA of raw data in section header.
        MOV EAX,[RSI]
        CMP EAX,[RBX+VIEW_INDEX.FA]
        JE .30:
        LEA RSI,[R8+RDX+8+4+4+4+4] ; C) Pointer to FA of relocations in section header.
        MOV EAX,[RSI]
        CMP EAX,[RBX+VIEW_INDEX.FA]
        JE .30
        ADD EDX,40               ; Add section header size.
        LOOP .10:                ; EDX is not .FA of the corresponding header. Try the next one.
        JMP .90:
    .30:; EDX is FA of section header. Write its section name to RDI.
        MOV ESI,EDX
        CALL FnStoreSectionName
    .90:RET
       ENDP Fn02$CoffSectionName

↑ Fn03$CoffSectionFlags

  Internal function trigerred by !3$ in VIEW_INDEX.Rem

Input
  RDI=^string where to write function result,
  RBX=^VIEW_INDEX structure,
  R8=InputPtr (file loaded in memory).
Output
  RDI is updated by the output string.
Clobbers
  RAX,RCX,RDX,RSI

    Fn03$CoffSectionFlags PROC
           MOV EDX,[RBX+VIEW_INDEX.FA]
           MOV ECX,[R8+RDX]
    %bit  %SETA 0x01
    name  %FOR ?,?,?,NO_PAD,?,CNT_CODE,INITIALIZED_DATA,UNINITIALIZED_DATA, \
               ?,LNK_INFO,?,LNK_REMOVE,LNK_COMDAT,?,?,GPREL, \
               ?,?,?,?,?,?,?,?, \
               NRELOC_OVFL,DISCARDABLE,NOT_CACHED,NOT_PAGED,SHARED,EXECUTE,READ,WRITE
           TEST ECX,%bit
           JZ .No%.:
           %IF "%name"!==="?"
            LEA RSI,[=B'%name']
            CALL .70:
           %ENDIF
    .No%.:
           %bit %SETA %bit << 1   ; >>
          %ENDFOR name
          DEC RDI
          SHR ECX,20
          AND CX,0x000F
          JZ .90:
          DEC ECX
          MOV EAX,1
          SHL EAX,CL
          LEA RSI,[=B'+ALIGN_']
          MOV CL,7
          REP MOVSB
          StoD RDI
          JMP .90:
    .70:  LODSB
          CMP AL,0
          JE .80:
          STOSB
          JMP .70:
    .80:  MOV AL,'|'
          STOSB
    .90:  RET
        ENDP Fn03$CoffSectionFlags

↑ Fn04$CoffSymbolName

  Internal function trigerred by !4$ in VIEW_INDEX.Rem

Input
  RDI=^string where to write function result,
  RBX=^VIEW_INDEX structure,
  R8=InputPtr (file loaded in memory).
Output
  RDI is updated by the output string.
Clobbers
  RAX,RCX,RDX,RSI

    Fn04$CoffSymbolName PROC
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOV RAX,[R8+RDX]
        TEST EAX
        JZ .50:                  ; Jump on long name.
    .20:CMP AL,0
        JE .90:
        STOSB
        SHR RAX,8
        JMP .20:
    .50:SHR RAX,32               ; EAX is now index in string table.
        ADD EAX,[FaOfStringTable]
        LEA RSI,[R8+RAX]
    .60:LODSB
        CMP AL,0
        JE .90:
        STOSB
        JMP .60:
    .90:RET
     ENDP Fn04$CoffSymbolName

↑ Fn05$CoffSymbolSection

  Internal function trigerred by !5$ in VIEW_INDEX.Rem

Input
  RDI=^string where to write function result,
  RBX=^VIEW_INDEX structure,
  R8=InputPtr (file loaded in memory).
Output
  RDI is updated by the output string.
Clobbers
  RAX,RCX,RDX,RSI

    Fn05$CoffSymbolSection PROC
         MOV EDX,[RBX+VIEW_INDEX.FA]
         MOVZXW EAX,[R8+RDX]
         CMP AX,0xFFFF
         LEA RSI,[=B'CONSTANT']
         JE .50:
         TEST AX,AX
         LEA RSI,[=B'EXTERN']
         JZ .50:
         LEA RSI,[=B'DEBUG']
         JS .50:
         LEA RSI,[=B'Section #']
         MOV ECX,9
         REP MOVSB
         MOV EDX,EAX             ; Section #1,2,3,,,
         StoD RDI
         MOV AX,': '
         STOSW
         MOV EAX,40              ; Size of section header.
         DEC EDX
         MUL RDX
         MOV ESI,[FaOfSectionHeaders]
         ADD ESI,EAX
         CALL FnStoreSectionName
         JMP .90:
    .50: LODSB
         CMP AL,0
         JE .90:
         STOSB
         JMP .50:
    .90: RET
        ENDP Fn05$CoffSymbolSection

↑ Fn06$CoffSymbolType

  Internal function trigerred by !6$ in VIEW_INDEX.Rem

Input
  RDI=^string where to write function result,
  RBX=^VIEW_INDEX structure,
  R8=InputPtr (file loaded in memory).
Output
  RDI is updated by the output string.
Clobbers
  RAX,RCX,RDX,RSI

    Fn06$CoffSymbolType PROC    ; Store Type, Class, Aux to RDI.
         MOV EDX,[RBX+VIEW_INDEX.FA]
         MOV ECX,[R8+RDX]
         CMP CH,1
         LEA RSI,[=B'Pointer to ']
         JE .20:
         CMP CH,2
         LEA RSI,[=B'Function ']
         JE .20:
         CMP CH,3
         LEA RSI,[=B'Array ']
         JNE .30:
    .20: LODSB
         CMP AL,0
         JE .30:
         STOSB
         JMP .20:
    .30:
      %i %SETA 1
    type %FOR VOID,CHAR,SHORT,INT,LONG,FLOAT,DOUBLE,STRUCT,UNION,ENUM,MOE,BYTE,WORD,UINT,DWORD
          CMP CL,%i
          JNE .No%type:
          LEA RSI,[=B'%type ']
          JMP .40:
    .No%type:
      %i %SETA %i+1
         %ENDFOR type
         JMP .50:
    .40: LODSB
         CMP AL,0
         JE .50:
         STOSB
         JMP .40:
    .50: SHR ECX,16
         JZ .90:
         CMP CL,2
         LEA RSI,[=B'EXTERN']
         JE .70:
         CMP CL,3
         LEA RSI,[=B'STATIC']
         JE .70:
         CMP CL,103
         LEA RSI,[=B'FILE']
         JE .70:
         CMP CL,104
         LEA RSI,[=B'SECTION']
         JE .70:
         CMP CL,105
         LEA RSI,[=B'WEAK']
         JNE .80:
    .70: LODSB
         CMP AL,0
         JE .80:
         STOSB
         JMP .70:
    .80: TEST CH,CH
         JZ .90:
         LEA RSI,[=B'+auxilliary']
    .85: LODSB
         CMP AL,0
         JE .90:
         STOSB
         JMP .85:
    .90: RET
        ENDP Fn06$CoffSymbolType

↑ Fn07$CoffIndexStore

  Internal function trigerred by !07$ in VIEW_INDEX.Rem

Input
  RDI=^string where to write function result,
  RBX=^VIEW_INDEX structure,
  R8=InputPtr (file loaded in memory).
Output
  RDI is updated by the output string.
Clobbers
  RAX,RCX,RDX,RSI

    Fn07$CoffSymbolIndexStore PROC  ; Store and increment symbol index to RDI.
        MOV EAX,[SymbolIndex]
        PUSH RDI
          LEA RDI,[Number]
          MOV RSI,RDI
          StoD RDI
          SUB RDI,RSI
          MOV ECX,EDI
        POP RDI
        REP MOVSB
        INC [SymbolIndex]
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOVZXB ECX,[R8+RDX+17]
        ADD [SymbolIndex],ECX
        RET
       ENDP Fn07$CoffSymbolIndexStore

↑ Fn08$CoffSymbolByIndex

  Internal function trigerred by !8$ in VIEW_INDEX.Rem

Input
  RDI=^string where to write function result,
  RBX=^VIEW_INDEX structure,
  R8=InputPtr (file loaded in memory).
Output
  RDI is updated by the output string.
Clobbers
  RAX,RCX,RDX,RSI

    Fn08$CoffSymbolByIndex PROC
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOV EAX,[R8+RDX]         ; Get symbol index.
        LEA ECX,[EAX+8*EAX]
        ADD ECX,ECX              ; Multiply by symbol size (18).
        ADD ECX,[FaOfSymbolTable]
        MOV RAX,[R8+RCX]
        TEST EAX
        JZ .50:                  ; Jump on long name.
    .20:CMP AL,0
        JE .90:
        STOSB
        SHR RAX,8
        JMP .20:
    .50:SHR RAX,32               ; EAX is now index in string table.
        ADD EAX,[FaOfStringTable]
        LEA RSI,[R8+RAX]
    .60:LODSB
        CMP AL,0
        JE .90:
        STOSB
        JMP .60:
    .90:RET
     ENDP Fn08$CoffSymbolByIndex

↑ Fn09$CoffSectionIndexStore

  Internal function trigerred by !9$ in VIEW_INDEX.Rem

Input
  RBX=^VIEW_INDEX structure
  R8=InputPtr (file loaded in memory)
  RDI=^string where to write function result
Output
  RDI is updated by the output string.
Clobbers
  RAX,RCX,RDX,RSI

    Fn09$CoffSectionIndexStore PROC  ; Store and increment section index to RDI.
        MOV EAX,[SectionIndex]
        PUSH RDI
          LEA RDI,[Number]
          MOV RSI,RDI
          StoD RDI
          SUB RDI,RSI
          MOV ECX,EDI
        POP RDI
        REP MOVSB
        INC [SectionIndex]
        RET
       ENDP Fn09$CoffSectionIndexStore

↑ Fn10$MajorMinorVersion1

  Internal function trigerred by !10$ in VIEW_INDEX.Rem

Input
  RBX=^VIEW_INDEX structure
  R8=InputPtr (file loaded in memory)
  RDI=^string where to write function result
Output
  RDI is updated by the output string.
Clobbers
  RAX,RCX,RDX,RSI

    Fn10$MajorMinorVersion1 PROC ; Interpret BYTE version as Major.Minor
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOVZXB EAX,[R8+RDX+0]     ; Get major version.
        StoD RDI
        MOV AL,'.'
        STOSB
        MOV AL,[R8+RDX+1]        ; Get minor version.
        StoD RDI
        RET
       ENDP Fn10$MajorMinorVersion1

↑ Fn11$MajorMinorVersion2

  Internal function trigerred by !11$ in VIEW_INDEX.Rem

Input
  RBX=^VIEW_INDEX structure
  R8=InputPtr (file loaded in memory)
  RDI=^string where to write function result
Output
  RDI is updated by the output string.
Clobbers
  RAX,RCX,RDX,RSI

    Fn11$MajorMinorVersion2 PROC ; Interpret WORD version as Major.Minor
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOVZXW EAX,[R8+RDX+0]    ; Get major version.
        StoD RDI
        MOV AL,'.'
        STOSB
        MOV AX,[R8+RDX+2]        ; Get minor version.
        StoD RDI
        RET
       ENDP Fn11$MajorMinorVersion2

↑ Fn12$WinSubsystem

  Internal function trigerred by !12$ in VIEW_INDEX.Rem

Input
  RBX=^VIEW_INDEX structure
  R8=InputPtr (file loaded in memory)
  RDI=^string where to write function result
Output
  RDI is updated by the output string.
Clobbers
  RAX,RCX,RDX,RSI

    Fn12$WinSubsystem PROC ; Interpret WORD version as subsystem token.
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOVZXW EAX,[R8+RDX]
        Dispatch AX,0x0002,0x0003,0x0001,0x0000
        StoD RDI
        JMP .90:
    .0x0000:MOV RAX,'UNKNOWN'
        JMP .70:
    .0x0001:MOV RAX,'NATIVE'
        JMP .70:
    .0x0002:MOV EAX,'GUI'
        JMP .70:
    .0x0003:MOV EAX,'CON'
    .70:CMP AL,0
        JE .90:
        STOSB
        SHR RAX,8
        JMP .70:
    .90:RET
       ENDP Fn12$WinSubsystem

↑ Fn13$DataDirName

  Internal function trigerred by !13$ in VIEW_INDEX.Rem

Input
  RBX=^VIEW_INDEX structure
  R8=InputPtr (file loaded in memory)
  RDI=^string where to write function result
  Fn13Index=iteration number 0,1,2,,,15
Output
  RDI is updated by the output string.
Clobbers
  RAX,RCX,RDX,RSI

    Fn13$DataDirName PROC ; Write option header's data directoryname.
        PUSH RCX,RDI
          MOV EDX,[Fn13Index]
          LEA RDI,[DataDirNames]
          INC  [Fn13Index]
          TEST EDX
          JZ .60:
          MOV ECX,-1
          XOR EAX,EAX
    .20:  REPNE SCASB
          DEC EDX
          JNZ .20:
    .60:  MOV RSI,RDI
        POP RDI,RCX
    .70:LODSB
        CMP AL,0
        JE .90:
        STOSB
        JMP .70:
    .90:RET
       ENDP Fn13$DataDirName

↑ Fn14$FileName

  Internal function trigerred by !14$ in VIEW_INDEX.Rem

Input
  RBX=^VIEW_INDEX structure
  R8=InputPtr (file loaded in memory)
  RDI=^string where to write function result
  Fn13Index=iteration number 0,1,2,,,15
Output
  RDI is updated by the output string.
Clobbers
  RAX,RCX,RDX,RSI

    Fn14$FileName PROC ; Write input filename.
         LEA RSI,[ArgInputFile::]
    .10: LODSB
         CMP AL,0
         JE .90:
         CMP AL,128
         JB .50:
         MOV AL,'~'
    .50: STOSB
         JMP .10:
    .90: RET
        ENDP Fn14$FileName

↑ Fn15$SaveMemberSize

  Internal function trigerred by !15$ in VIEW_INDEX.Rem

Input
  RBX=^VIEW_INDEX structure
  R8=InputPtr (file loaded in memory)
  RDI=^string where to write function result
Output
  RDI is updated by the output string.
  [MemberSize] is updated from Member header Size (decadic offset 30h).
Clobbers
  RAX,RCX,RDX,RSI

    Fn15$SaveMemberSize:: PROC
        MOV EDX,[RBX+VIEW_INDEX.FA]
        PUSH RSI
          LEA RSI,[R8+RDX]
          LodD RSI
        POP RSI
        MOV [MemberSize],EAX
        RET
       ENDP Fn15$SaveMemberSize

↑ Fn16$DisplayName

  Internal function trigerred by !16$ in VIEW_INDEX.Rem

Input
  RBX=^VIEW_INDEX structure
  R8=InputPtr (file loaded in memory)
  RDI=^string where to write function result
Output
  RDI is updated by the output string.
  [MemberSize] is updated from Member header Size (decadic offset 30h).
Clobbers
  RAX,RCX,RDX,RSI

    Fn16$DisplayName:: PROC
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOV EAX,[R8+RDX]
        CMP RAX,[InputSize::]
        JA .90:
        LEA RSI,[R8+RAX]
    .10:LODSB
        CMP AL,' '
        JBE .90:
        CMP AL,128
        JAE .90:
        STOSB
        JMP .10:
    .90:RET
       ENDP Fn16$DisplayName

↑ Fn17$DisplayName

  Internal function trigerred by !17$ in VIEW_INDEX.Rem

Input
  RBX=^VIEW_INDEX structure
  R8=InputPtr (file loaded in memory)
  RDI=^string where to write function result
Output
  RDI is updated by the output string.
  [MemberSize] is updated from Member header Size (decadic offset 30h).
Clobbers
  RAX,RCX,RDX,RSI

    Fn17$DisplaySymbolName:: PROC
        MOV ESI,[FaOfArchiveStrings]
        ADD RSI,R8
    .10:LODSB
        CMP AL,0
        JE .20:
        STOSB
        JMP .10:
    .20:SUB RSI,R8
        MOV [FaOfArchiveStrings],RSI
        RET
       ENDP Fn17$DisplaySymbolName

↑ Fn18$MemberNumber

  Internal function trigerred by !18$ in VIEW_INDEX.Rem

Input
  RBX=^VIEW_INDEX structure
  R8=InputPtr (file loaded in memory)
  RDI=^string where to write function result
Output
  RDI is updated by the output string.
  [MemberSize] is updated from Member header Size (decadic offset 30h).
Clobbers
  RAX,RCX,RDX,RSI

    Fn18$MemberNumber PROC
        MOV EAX,[MemberNumber]
        INC EAX
        MOV [MemberNumber],EAX
        StoD RDI
        RET
       ENDP Fn18$MemberNumber

↑ Fn19$OmfModuleName

  Internal function trigerred by !19$ in VIEW_INDEX.Rem

Input
  RBX=^VIEW_INDEX structure
  R8=InputPtr (file loaded in memory)
  RDI=^string where to write function result
Output
  RDI is updated by the output string.
  [MemberSize] is updated from Member header Size (decadic offset 30h).
Clobbers
  RAX,RCX,RDX,RSI

    Fn19$OmfModuleName PROC
         MOV EDX,[RBX+VIEW_INDEX.FA]
         MOVZXW ECX,[R8+RDX+1]
         SUB ECX,2
         JB .90:
         AND ECX,0x000000EF
         PUSH RSI
           LEA RSI,[R8+RDX+4]
           REP MOVSB
         POP RSI
    .90: RET
       ENDP Fn19$OmfModuleName

↑ Fn20$ElfSectionName

  Internal function trigerred by !20$ in VIEW_INDEX.Rem

Input
  RBX=^VIEW_INDEX structure
  R8=InputPtr (file loaded in memory)
  RDI=^string where to write function result
Output
  RDI is updated by the output string.
  [MemberSize] is updated from Member header Size (decadic offset 30h).
Clobbers
  RAX,RCX,RDX,RSI

    Fn20$ElfSectionName:: PROC     ; Find a section header with .sh_offset and .sh_size equal to .FA and .Size.
        JSt [Status::],ArgWidth64,.50:
        MOV ESI,[R8+20h]        ; FA of section headers in the file header. 0-th section header SHDR32 offset by file header.
        MOV EDX,[RBX+VIEW_INDEX.FA] ; RBX describes section data.
        XOR ECX,ECX             ; ECX=Section number #0, #1, #2...
        MOV EAX,[RBX+VIEW_INDEX.Size]
        AND EAX,0x0FFF_FFFF     ; Get rid of level.
    .10:CMP EDX,[R8+RSI+10h]    ; Does it correspond to SHDR32 data offset?
        JNE .20:
        CMP EAX,[R8+RSI+14h]    ; Does it correspond to SHDR32 data size?
        JE .30:
    .20:ADD ESI,40              ; Try the next section header PHDR32.
        INC ECX
        CMP CX,[R8+30h]         ; Number of section headers by file header.
        JB .10:
        JMP .90:
    .30:; Found section header #ECX at RSI which corresponds with this data.
        MOV EAX,ECX
        StoD RDI                ; Section number.
        MOV AL,' '
        STOSB
        MOV EAX,[R8+RSI+0]      ; Get section name (offset in .shstrtab).
        ADD EAX,[FaOfShstrtabData]
        LEA RSI,[R8+RAX]
    .40:LODSB
        CMP AL,0
        JZ .90:
        STOSB
        JMP .40:

    .50:MOV ESI,[R8+28h]        ; FA of section headers in the file header. 0-th section header SHDR64 offset by file header.
        MOV EDX,[RBX+VIEW_INDEX.FA]
        XOR ECX,ECX             ; ECX=Section number #0, #1, #2...
        MOV EAX,[RBX+VIEW_INDEX.Size]
        AND EAX,0x0FFF_FFFF     ; Get rid of level.
    .60:CMP RDX,[R8+RSI+18h]    ; Does the FA correspond to SHDR64 data offset?
        JNE .70:
        CMP RAX,[R8+RSI+20h]    ; Does the section contents .Size correspond to SHDR32 data size?
        JE .80:
    .70:ADD ESI,64              ; Try the next section header PHDR64.
        INC ECX
        CMP CX,[R8+3Ch]         ; Number of section headers by file header.
        JB .60:
        JMP .90:
    .80:; Found section header #ECX at RSI which corresponds with this data.
        MOV EAX,ECX
        StoD RDI                ; Section number.
        MOV AL,' '
        STOSB
        MOV EAX,[R8+RSI+0]      ; Get section name (offset in .shstrtab).
        ADD EAX,[FaOfShstrtabData]
        LEA RSI,[R8+RAX]
    .85:LODSB
        CMP AL,0
        JZ .90:
        STOSB
        JMP .85:
    .90:RET
      ENDP Fn20$ElfSectionName

↑ Fn21$ElfSymbolName

  Internal function trigerred by !21$ in VIEW_INDEX.Rem

Input
  RBX=^VIEW_INDEX which refers to an ELF symbol.
  R8=InputPtr (file loaded in memory)
  RDI=^string where to write function result
Output
  RDI is updated by the output string.
  [MemberSize] is updated from Member header Size (decadic offset 30h).
Clobbers
  RAX,RCX,RDX,RSI

    Fn21$ElfSymbolName:: PROC    ; Find the section which hosts symbol with [RBX+VIEW_INDEX.FA].
         JSt [Status::],ArgWidth64,.50:
         MOV ESI,[R8+20h]        ; FA of 0-th section header SHDR64 by file header. RSI=FA of EHDR32.e_shoff.
         XOR ECX,ECX
         MOV EDX,[RBX+VIEW_INDEX.FA] ; EDX is FA of the symbol SYM32 (10h bytes). Find its section (.symtab).
    .10: CMP EDX,[R8+RSI+10]     ; Is symbol EDX within the range SHDR32.sh_offset..SHDR32.sh_offset+size
         JB  .20:                ;   of section header RSI?
         MOV EAX,[R8+RSI+14h]    ; SHDR32.sh_size
         ADD EAX,[R8+RSI+10h]    ; FA of end of SHDR32 data.
         CMP EDX,EAX
         JB .30:                 ; Jump if found .symtab or .dynsym section.
    .20: ADD ESI,40              ; Try the next section header SHDR32.
         INC ECX                 ; Section number.
         CMP CX,[R8+30h]         ; Number of section headers by file header.
         JB .10:                 ; Exceeded this number of section headers (EHDR32.e_shnum)?
         JMP .90:
    .30: ; Found section header number ECX (.symtab or .dynsym section) at FA RSI which hosts this symbol.
         MOV EAX,[R8+RSI+18h]    ; SHDR32.sh_link - ordinal of section with .strtab (#0, #1, #2 etc).
         MOV ECX,40              ; Size of SHDR32.
         MUL RCX
         ADD RAX,[R8+20h]        ; FA of 0-th section header SHDR32 by file header.
         MOV RCX,[R8+RAX+10h]    ; FA of SHDR32.sh_offset of .strtab.
         CMP RCX,[InputSize]
         JNB .90:
         ADD RCX,R8              ; RCX points to .strtab contents.
         MOV EDX,[RBX+VIEW_INDEX.FA]
         CMP RDX,[InputSize]
         JNB .90:
         MOV EAX,[R8+RDX+0]      ; SYM32.st_name (offset in string table).
         LEA RSI,[RCX+RAX]
         CMP RSI,[InputEnd]
         JNB .90:
    .40: LODSB
         CMP AL,0
         JZ .90:
         STOSB
         JMP .40:
    .50: MOV RSI,[R8+28h]        ; FA of 0-th section header SHDR64 by file header. RSI=FA of EHDR64.e_shoff.
         XOR ECX,ECX
         MOV EDX,[RBX+VIEW_INDEX.FA] ; EDX is FA of the symbol SYM64 (18h bytes). Find its section (.symtab).
    .60: CMP RDX,[R8+RSI+18h]    ; Is symbol EDX within the range SHDR64.sh_offset..SHDR64.sh_offset+size
         JB  .70:                ;  of section header RSI?
         MOV RAX,[R8+RSI+20h]    ; SHDR64.sh_size
         ADD RAX,[R8+RSI+18h]    ; FA of end of SHDR64 data.
         CMP RDX,RAX
         JB .80:                 ; Jump if found (.symtab or .dynsym section).
    .70: ADD ESI,64              ; Otherwise try the next section header SHDR64.
         INC ECX                 ; Section number.
         CMP CX,[R8+3Ch]         ; Exceeded this number of section headers (EDHR64.e_shnum)?
         JB .60:
         JMP .90:
    .80: ; Found section header number ECX (.symtab or .dynsym) at FA RSI which hosts this symbol.
         MOV EAX,[R8+RSI+28h]    ; SHDR64.sh_link - ordinal of section with .strtab (#0, #1, #2 etc).
         MOV ECX,64              ; Size of SHDR64.
         MUL RCX
         ADD RAX,[R8+28h]        ; FA of 0-th section header SHDR64 by file header.
         MOV RCX,[R8+RAX+18h]    ; FA of SHDR64.sh_offset of .strtab.
         CMP RCX,[InputSize]
         JNB .90:
         ADD RCX,R8              ; RCX points to .strtab contents.
         MOV EDX,[RBX+VIEW_INDEX.FA] ; FA SYM64.
         CMP RDX,[InputSize]
         JNB .90:
         MOV EAX,[R8+RDX+0]      ; SYM64.st_name (offset in string table).
         LEA RSI,[RCX+RAX]
         CMP RSI,[InputEnd]
         JNB .90:
    .85: LODSB
         CMP AL,0
         JZ .90:
         STOSB
         JMP .85:
    .90: RET
      ENDP Fn21$ElfSymbolName

↑ Fn22$ElfProgramSections

  Internal function trigerred by !22$ in VIEW_INDEX.Rem

Input
  RBX=^VIEW_INDEX structure of a program.
  R8=InputPtr (file loaded in memory)
  RDI=^string where to write function result
  [Status::] specifies program width.
Output
  RDI is updated by the output string.
  [MemberSize] is updated from Member header Size (decadic offset 30h).
Clobbers
  RAX,RCX,RDX,RSI

    Fn22$ElfProgramSections:: PROC  ; Number of sections which belong to the segment.
        JSt [Status::],ArgWidth64,.50:
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOV R12D,[R8+RDX+4+4]     ; PHDR32.p_vaddr
        MOV R11D,[R8+RDX+14h]     ; PHDR32.p_memsz
        ADD R11,R12               ; FA of end of program span.
        MOV ESI,[R8+20h]          ; EHDR32.e_shoff
        XOR ECX,ECX               ; Section counter.
    .10:CMP CX,[R8+30h]           ; EHDR32.e_shnum
        JAE .90:
        MOV EAX,[R8+RSI+0Ch]      ; SHDR32.sh_addr
        CMP EAX,R12D
        JB .20:
        CMP EAX,R11D
        JA .20:
        MOV AL,'#'
        STOSB
        MOV EAX,ECX
        StoD RDI
        MOV AL,' '
        STOSB
    .20:ADD ESI,40                ; Size of SHDR32
        INC ECX
        JMP .10:
    .50:MOV EDX,[RBX+VIEW_INDEX.FA]
        CMP RDX,[InputSize::]
        JNB .90:
        MOV R12,[R8+RDX+10h]      ; PHDR64.p_vaddr
        MOV R11,[R8+RDX+28h]      ; PHDR64.p_memsz
        ADD R11,R12               ; FA of end of program span.
        MOV RSI,[R8+28h]          ; EHDR64.e_shoff
        CMP RSI,[InputSize::]
        JNB .90:
        XOR ECX,ECX               ; Section counter.
    .60:CMP CX,[R8+3Ch]           ; EHDR64.e_shnum
        JAE .90:
        MOV RAX,[R8+RSI+10h]      ; SHDR64.sh_addr
        CMP RAX,R12
        JB .70:
        CMP RAX,R11
        JA .70:
        MOV AL,'#'
        STOSB
        MOV EAX,ECX
        StoD RDI
        MOV AL,' '
        STOSB
    .70:ADD ESI,64                ; Size of SHDR64
        INC ECX
        JMP .60:
    .90: RET
      ENDP Fn22$ElfProgramSections

↑ Fn23$GifColorTableSize

  Internal function trigerred by !23$ in VIEW_INDEX.Rem

Input
  RBX=^VIEW_INDEX structure of a program.
  R8=InputPtr (file loaded in memory)
  RDI=^string where to write function result
  [Status::] specifies program width.
Output
  RDI is updated by the output string.
Clobbers
  RAX,RCX,RDX,RSI

    Fn23$GifColorTableSize:: PROC  ; Number of sections which belong to the segment.
        MOV EDX,[RBX+VIEW_INDEX.FA]
        MOV CL,[R8+RDX]
        XOR EAX,EAX
        TEST CL,0x80
        JZ .80:
        AND CL,0x07
        INC CL
        INC EAX
        SHL EAX,CL
        LEA EAX,[EAX+2*EAX]
        MOV [SizeOfColorTable],EAX
    .80:MOV ECX,EAX
        StoH RDI,Size=3
        MOV AX,'h='
        STOSW
        MOV EAX,ECX
        StoD RDI
        RET
      ENDP Fn23$GifColorTableSize

↑ Fn24$FileSize

  Internal function trigerred by !24$ in VIEW_INDEX.Rem

Input
  RBX=^VIEW_INDEX structure of a program.
  R8=InputPtr (file loaded in memory)
  RDI=^string where to write function result
  [Status::] specifies program width.
Output
  RDI is updated by the output string.
Clobbers
  RAX,RCX,RDX,RSI

    Fn24$FileSize:: PROC  ; Size of the input file hexadecimal and decimal.
        MOV EAX,[InputSize]
        StoH RDI,Size=R15
        MOV AX,'h='
        STOSW
        MOV EAX,[InputSize]
        StoD RDI
        RET
     ENDP Fn24$FileSize

↑ Fn25$Override

  Internal function trigerred by !25$ in VIEW_INDEX.Rem

  Write `Code=XXXXh..XXXXb Width=16` when (/CE - /CB)>0 and `Data=XXXXh..XXXXh` when (/DE - /DB)>0.

Input
  RBX=^VIEW_INDEX structure of a program.
  R8=InputPtr (^file contents loaded in memory)
  RDI=^string where to write function result
  [Status::] specifies program width.
Output
  RDI is updated by the output string.
Clobbers
  RAX,RCX,RDX,RSI

    Fn25$Override:: PROC ; Size of the input file hexadecimal and decimal.
        MOV ECX,[ArgCodeBegin::] ; FA of /CB=
        MOV EDX,[ArgCodeEnd::]   ; FA of /CE=
        CMP EDX,ECX
        JNA .50:
    .20:MOV EAX,'Code'
        STOSD
        MOV AL,'='
        STOSB
        MOV EAX,ECX
        StoH RDI,Size=R15
        MOV EAX,'h..'
        STOSD
        DEC RDI
        MOV EAX,EDX
        StoH RDI,Size=R15
        MOV EAX,'h Wi'
        STOSD
        MOV EAX,'dth='
        STOSD
        MOV EAX,[Status::]
        SHR EAX,16
        AND EAX,16|32|64
        StoD RDI
        MOV AL,' '
        STOSB
    .50:MOV ECX,[ArgDataBegin::] ; FA of /DB=
        MOV EDX,[ArgDataEnd::]   ; FA of /DE=
        CMP EDX,ECX
        JNA .90:
        MOV EAX,'Data'
        STOSD
        MOV AL,'='
        STOSB
        MOV EAX,ECX
        StoH RDI,Size=R15
        MOV EAX,'h..'
        STOSD
        DEC RDI
        MOV EAX,EDX
        StoH RDI,Size=R15
        MOV AL,'h'
        STOSB
    .90:RET
     ENDP Fn25$Override

↑ FnStoreSectionName

  Internal function trigerred by !2$ and !5$ in VIEW_INDEX.Rem

Input
  RDI=^string where to write section name,
  RSI=File address of 8-byte section name, perhaps in [FaOfStringTable],
  R8=InputPtr (file loaded in memory).
Output
  RDI is updated by the output string.
Clobbers
  RAX,RSI

    FnStoreSectionName PROC ; ESI is FA of 8 byte section name. Store it to RDI. R8=InputPtr
         ADD RSI,R8
         LODSB
         CMP AL,'/'
         JNE .50
         LodD RSI
         MOV RSI,[FaOfStringTable]
         ADD RSI,R8
         ADD RSI,RAX
    .20: LODSB
         CMP AL,0
         JE .90:
         STOSB
         JMP .20:
    .50: MOV RAX,[RSI-1]
    .60: CMP AL,0
         JE .90:
         STOSB
         SHR RAX,8
         JMP .60:
    .90: RET
        ENDP FnStoreSectionName

    ENDPROGRAM viewmain

▲Back to the top▲