EuroAssembler Index Manual Download Source Macros


Sitemap Links Forum Tests Projects

viewmain.htm
Data
Data
Procedures
AutodetectFileFormat
ByLevel
ExpandRem
ViewCreate
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
FnStoreSectionName

This is a module of EuroTool program EuroView.


         EUROASM CPU=X64,AutoAlign=yes,DumpWidth=38,Unicode=no
viewmain PROGRAM Format=COFF,Width=64
           %DROPMACRO *
           INCLUDEHEAD argument.htm
           INCLUDE1 memory64.htm, cpuext64.htm, cpuext.htm, sort64.htm, string64.htm, 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       ; |####

VIEW_INDEX STRUC             ; A structure which describes one viewed element.
.Rem     D QWORD             ; Pointer to the remark (in EuroView memory). It may contain !x variables.
.FA      D DWORD             ; 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.
.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
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.
AddressDigits::       D DWORD ; Number of address digits in listing (4..8).
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
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.
AutodetectFileFormat never fails; at least it ends with RAX=^FormatBIN:: and RDX=^'BIN',0.
Input
[InputPtr] points to the start of memory-mapped input file.
[InputSize::] size of the input file
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.
Calls
Detect%FF
AutodetectFileFormat:: PROC
FF %FOR %FileFormats
     MOV RSI,[InputPtr::]
     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.
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.
!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.
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 . Be sure to INCLUDE1 time.htm.
ExpandRem:: PROC
      MOV RSI,R12
      TEST RSI
      JZ .0x00:
.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:  LodD RSI                         ; Load the decimal number following '!'.
      JNC .30:
      MOV ECX,R13D                     ; If it's missing, use R13 instead.
      TEST ECX
      JZ .0x00:
      MOV EAX,ECX
.30:  MOV ECX,EAX                      ; The number following !.
      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.
      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.
      JMP .Dispatched:
.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]          ; Fn marker. Call a function from FnTable.
      MOV RCX,R9
      PUSH RSI
        CALL RAX
      POP RSI
      RET
.0x00:MOV EAX,0x0A0D
      STOSD
      RET
   ENDP ExpandRem
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.

In Phase Two the procedure ViewCreate uses the sorted indexes to generate an output listing.

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

Input
ArgInputFile, ArgOutputFile, ArgFileFormat.
FileOutput and FileIndex are created and memory-mapped to OutputPtr..OutputEnd and IndexPtr..IndexEnd.
Called by
WndProc
Calls
[FormatProcPtr], ExpandRem
ViewCreate:: PROC
    MOV EDX,[ArgFileFormat::]          ; Nonzero ordinal.
ff  %FOR %FileFormats                  ; Enumeration declared in argument.htm.
     LEA RAX,[Format%ff]
     CMP EDX,ArgFileFormat%ff
     JE .02:
    %ENDFOR ff
    LEA RAX,[FormatBIN]
.02:MOV [FormatProcPtr],RAX
    LEA RBX,[ViewIndex]                ; Working variable in the form VIEW_INDEX.
    MOV R8,[InputPtr]                  ; Start of input file loaded in memory. Phase One begins.
    CALL [FormatProcPtr]               ; Call FormatMZ, FormatCOFF32 etc. to write the index file.
    LEA RBX,[ViewIndex]                ; Add padding at the end of VIEW_INDEX array.
    MOV [RBX+VIEW_INDEX.Rem],=B'!X'
    MOV EAX,[InputSize]
    MOV [RBX+VIEW_INDEX.FA],EAX
    MOV [RBX+VIEW_INDEX.Size],0
    CALL SaveViewIndex::
    CALL [FileIndexReopenProc]         ; 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
    SAL RAX,4
    LEA RBX,[RDI+RAX-2*16]             ; RBX=the last but one VIEW_INDEX.
    MOV EDX,[RBX+VIEW_INDEX.FA]
    MOV EAX,[RBX+VIEW_INDEX.Size]
    ADD EAX,EDX
    MOV ECX,[InputSize]
    SUB ECX,EAX
    JZ .05:
    ADD RBX,16                         ; RBX=the last VIEW_INDEX.
    MOV [RBX+VIEW_INDEX.FA],EAX
    MOV [RBX+VIEW_INDEX.Size],ECX
.05:MOV RBX,RDI                        ; Pointer to an array of VIEW_INDEXes is now in RBX.

.10:; Phase Two. Convert each VIEW_INDEX record RBX to a listing line(s) and write it to the listing in FileOutput.
    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]
    JNA .40:
    MOV EDX,[RDI+VIEW_INDEX.Size]
    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.
    SUB ECX,EDX
    JBE .40:
    ; There is ECX bytes of unassigned alignment between objects. Create listing lines for them.
    MOV R13,RCX                        ; Amount of alignment bytes (may be over 16).
    MOV R14,RDX                        ; FA of alignment bytes mapped in memory.
.18:LEA RDI,[WorkMemory]
    MOV AL,'|'
    STOSB
    MOV RAX,R14
    StoH RDI,Size=R15
    MOV AL,':'
    STOSB
    XOR EAX,EAX
    XOR EDX,EDX
    LEA RSI,[R8+R14]
    MOV ECX,R13D
    CMP ECX,16
    JBE .20:
    MOV ECX,16
.20:JRCXZ .30:
.24:TEST DL,0000_0011b
    JNZ .28:
    TEST EDX
    JZ .28:
    MOV AL,' '
    STOSB
.28:LODSB
    StoH RDI,Size=2
    INC EDX
    LOOP .24:
.30: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 .34:
    MOV AL,' '
    REP STOSB
.34:LEA RSI,[=B'| alignment']
    MOV ECX,11
    REP MOVSB
    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 ECX,R13D
    CMP ECX,16
    JBE .38:
    MOV ECX,16
.38:ADD R14,RCX
    SUB R13,RCX
    JA .18:
.40:; 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 .47:
    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 .44:
      MOVD [SymbolNumber::],0          ; Clear the symbol number counter when a new section begins.
.44:POP RDI,RSI
.47:MOV R12,[RBX+VIEW_INDEX.Rem]
    CALL ExpandRem:                    ; Expand !x 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:                               ; VIEW_INDEX at RBX represents a gray Level0 line,
    MOV R12,[RBX+VIEW_INDEX.Rem]       ;  or more Level0 lines when RBX+VIEW_INDEX.Size is above 16.
    MOV R13D,[RBX+VIEW_INDEX.Size]
    MOV R14D,[RBX+VIEW_INDEX.FA]
    TEST R13
    JZ .85:
.50:LEA RDI,[WorkMemory]               ; Print |file_address: R14 at the beginning of WorkMemory.
    MOV AL,'|'
    STOSB
    MOV RAX,R14
    StoH RDI,Size=R15
    MOV AL,':'
    STOSB
    XOR EAX,EAX
    XOR EDX,EDX
    LEA RSI,[R8+R14]
    MOV ECX,R13D
    CMP ECX,16
    JBE .57:
    MOV ECX,16
.57:JRCXZ .70:
.60:TEST DL,0000_0011b
    JNZ .63:
    TEST EDX
    JZ .63:
    MOV AL,' '
    STOSB                              ; Insert a space after each four hexa bytes.
.63:LODSB
    StoH RDI,Size=2
    INC EDX
    LOOP .60:
.70: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 .75:
    MOV AL,' '
    REP STOSB
.75:MOV AX,'| '
    STOSW                              ; Terminate the dump column.
    CALL ExpandRem                     ; Print the remark, if any, with expanded !variables.
    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 ECX,R13D
    CMP ECX,16
    JBE .80:
    MOV ECX,16
.80:ADD R14,RCX
    SUB R13,RCX
    JA .50:
.85:ADD RBX,SIZE# VIEW_INDEX
    JMP .10:
.90:RET
  ENDP ViewCreate
↑ 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$'
    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$'
    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$'
    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

32bit 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

64bit 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

32bit 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

64bit 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

32bit 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$'
.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

64bit 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$'
    JMP FormatELF32.Common:
  ENDP FormatELF64
↑ FormatELFSO32

32bit 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$'
    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$'
    JMP FormatELF32.Common:
  ENDP FormatELFSO64
↑ FormatELFX32

32bit 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$'
    JMP FormatELF32.Common:
  ENDP FormatELFX32
↑ FormatELFX64

64bit 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$'
    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$'
    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$'
    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::
    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$'
    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$'
    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$'
    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$'
    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$'
    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$'
    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$'
    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

32bit 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

64bit 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$'
    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$'
    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
    MOVZXW EAX,[RSI+16]     ; Size of optional header.
    TEST EAX
    JNZ .No:
    MOV AX,[RSI+0]          ; COFF machine.
    CMP AX,0x014C           ; Machine I386?
    JNE .No:
    TESTW [RSI+18],0x0100   ; 32 bit machine?
    JNZ .No:
    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
    MOVZXW EAX,[RSI+16]     ; Size of optional header.
    TEST EAX
    JNZ .No:
    MOV AX,[RSI+0]          ; COFF machine.
    CMP AX,0x014C           ; Machine I386?
    JNE .No:
    TESTW [RSI+18],0x0100   ; 32 bit machine?
    JZ .No:
    CLC                     ; Detected.
    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
    MOVZXW EAX,[RSI+16]     ; Size of optional header.
    TEST EAX
    JNZ .No:
    MOV AX,[RSI+0]          ; COFF machine.
    CMP AX,0x8664           ; Machine AMD64?
    JNE .No:
    TESTW [RSI+18],0x0100   ; 32 bit machine?
    JNZ .No:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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.
    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.
    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: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:
    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:
    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$'
    JSt [Status::],ArgWidth64,.10:
    MOV [RBX+VIEW_INDEX.Rem],=B'Format COFF32 "!14$" size=!24$'
    JSt [Status::],ArgWidth32,.10:
    MOV [RBX+VIEW_INDEX.Rem],=B'Format COFF16 "!14$" size=!24$'
    JSt [Status::],ArgWidth16,.10:
    MOV [RBX+VIEW_INDEX.Rem],=B'Format COFF "!14$" size=!24$'
.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]
    JRCXZ .90:
    MOV EDX,[FaOfSectionHeaders] ;Size of COFF file header, FA of 1st section header.
.10:MOV [RBX+VIEW_INDEX.Rem],=B'Raw data|code of section !2$'
    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::
    MOV [RBX+VIEW_INDEX.Rem],=B'!X'
    CALL SaveViewIndex::
.80:ADD EDX,40               ; Size of section header.
    LOOP .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

32bit 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 32bit section header.
    MUL RCX
    MOV EDX,[R8+20h]         ; FA of section headers in 32bit file header.
    LEA EAX,[EAX+EDX+10h]    ; FA of 32bit section .shstrtab
    CMP RAX,[InputSize::]
    JNB .90
    MOV ECX,[R8+RAX]         ; FA of data in 32bit 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 64bit section header.
    MUL RCX
    MOV RDX,[R8+28h]         ; FA of section headers in 64bit file header.
    LEA EAX,[EAX+EDX+18h]    ; FA of 64bit section .shstrtab data.
    CMP RAX,[InputSize::]
    JNB .90:
    MOV ECX,[R8+RAX]         ; FA of data in 64bit 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
.1D:                         ; progbits
.3D:                         ; strtab

     MOV [RBX+VIEW_INDEX.Rem],=B'!X'
     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 [RBX+VIEW_INDEX.Rem],=B'!X'
     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 DOS 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 start of MZ !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'Entry IP !2Hh=!2D'
    CALL SaveViewIndex::
    MOV [RBX+VIEW_INDEX.Rem],=B'CS entry relative to the start of MZ !2Hh'
    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:MOV [RBX+VIEW_INDEX.Rem],=B'MZ program executable body'
    MOV ECX,[MzHeaderSize]
    MOV [RBX+VIEW_INDEX.FA],ECX
    MOV EDX,[MzBytesFileSize]
    MOV EAX,EDX
    SUB EDX,ECX
    CMP EAX,0x0490
    JNE .60:
    MOV EAX,[FaOfPeSignature]
    CMPD [R8+RAX],'PE'
    JNE .60:
    MOV EDX,[FaOfPeSignature]
    MOV ECX,[MzHeaderSize]
    SUB EDX,ECX
.60:OR EDX,Level1
    MOV [RBX+VIEW_INDEX.Size],EDX
    CALL SaveViewIndex
    MOV [RBX+VIEW_INDEX.Rem],=B'!X'
    MOV [RBX+VIEW_INDEX.FA],ECX
    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

32bit 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'64bit optional header'
    MOV ECX,240+Level2
    JSt [Status::],ArgWidth64,.10:
    MOV [RBX+VIEW_INDEX.Rem],=B'32bit 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$'
    JMP .30:
.10:MOV [RBX+VIEW_INDEX.Rem],=B'Format PE64 "!14$" size=!24$'
    JMP .30:
.20:JSt [Status::],ArgWidth64,.25:
    MOV [RBX+VIEW_INDEX.Rem],=B'Format DLL32 "!14$" size=!24$'
    JMP .30:
.25:MOV [RBX+VIEW_INDEX.Rem],=B'Format DLL64 "!14$" size=!24$'
.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

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 header. EAX is the searched for FA of section header, raw data or relocations.
    MOV EAX,[RBX+VIEW_INDEX.FA] ; The searched for FA of section header, raw data or relocation.
    CMP EAX,EDX              ; Pointers to .Name of section EDX header?
    JE .30:
    LEA RSI,[R8+RDX+8+4+4+4]  ; Pointer to FA of raw data.
    MOV EAX,[RSI]
    CMP EAX,[RBX+VIEW_INDEX.FA]
    JE .30:
    LEA RSI,[R8+RDX+8+4+4+4+4]; Pointer to FA of relocations.
    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 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=8
    MOV AX,'h='
    STOSW
    MOV EAX,[InputSize]
    StoD RDI
    RET
 ENDP Fn24$FileSize
↑ 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▲