Při spuštění souboru typu EXE se vytvoří PSP (sem se
uložej parametry z příkazový řádky), načte se kód programu,
provede se relokace, nastaví se SS:SP podle hodnot v hlavičce a spustí se CS:IP.
ds = es = PSPSEG
Program musí sám nastavit ds.
Ofset | Velikost | Význam |
---|---|---|
0 | 2 | MAGIC - "MZ" (5A4Dh) |
2 | 2 | CBLP - počet bytú v poslední stránce |
4 | 2 | CP - dýlka souboru v 512 bajtovejch stránkách včetně hlavičky |
6 | 2 | CRLC - počet položek v relokační tabulce |
8 | 2 | CPARHDR - velikost záhlaví v paragrafech (16 B) včetně relokační tabulky |
10 | 2 | MINALLOC - Minimální velikost požadovaný paměti za koncem programu v paragrafech |
12 | 2 | MAXALLOC - Maximální velikost požadovaný paměti za koncem programu v paragrafech |
14 | 2 | SS (stack segment) od začátku programu v paragrafech |
16 | 2 | SP (stack pointer) |
18 | 2 | CSUM - Kontrolní součet |
20 | 2 | IP (instruction pointer) |
22 | 2 | CS (code segment) od začátku programu v paragrafech |
24 | 2 | LFARLC - offset relokační tabulky od začátku souboru v bajtech (1Ch = 28) |
26 | 2 | OVNO - Číslo overlaye (0 = základní modul) |
28 | 8 | RES? - nepoužito |
36 | 2 | OEMID? |
38 | 2 | OEMINFO? |
40 | 20 | RES2? - nepoužito |
60 | 4 | LFANEW? - offset nový hlavičky |
LFARLC | CRLC*4 | Relokační tabulka: {uns2 ofs, uns2 seg}*CRLC Segment se počítá od začátku programu v paragrafech |
CPARHDR*16 | (CP*512)-(CPARHDR*16) | Kód programu, max 1 MiB, v praxi ještě míň |
Soubor *.EXE | Paměť | ||||
---|---|---|---|---|---|
Ofset | Velikost | Význam | Adresa | Velikost | Význam |
0:0 | 400h (256*4 = 1024) | Tabulka přerušení | |||
40h:0 | 100h (256) | Proměný BIOSu | |||
0 | 28? | Hlavička | 50h:0 | ? | MS-DOS |
LFARLC | CRLC*4 | Relokační tabulka | PSPSEG:0 | 256 | PSP |
CPARHDR*16 | (CP*512) - (CPARHDR*16) | Kód programu a inicializovaný data |
STARTSEG:0 | (CP*512) - (CPARHDR*16) | Kód programu a inicializovaný data, začátek programu = (STARTSEG+CS):IP, kde CS,IP jsou hodnoty z hlavičky souboru |
? | ? | Neinicializovaný data | |||
(STARTSEG+SS):0 | SP | Zásobník (stack) | |||
? | ? | Halda (heap) | |||
0A000h:0 | 320 KiB | Sdílená paměť | |||
0F000h:0 | 64 KiB | ROM BIOS |
Relokace se provádí takhle:
RTEntry = {uns2 ofs, seg}
foreach(RTEntry rte in RT)
word[STARTSEG+rte.seg:rte.ofs] += STARTSEG;
U aplikací pro Windows je LFARLC >= 40h (obvykle 40h).
Na začátku je vložená aplikace pro MS-DOS zvaná "stub", která vypíše hlášku
"This program requires Microsoft Windows." nebo "This program cannot be run in
DOS mode." a ukončí se.
Ofset | Velikost | Význam | |||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 40h (64) ? | Hlavička pro MS-DOS (old-style header), viz výš | |||||||||
3Ch (60) | 4 | LFANEW - ofset hlavičky pro Windows (new-style header file offset, obvykle 80h) | |||||||||
LFANEW+0 | 2 | Magic = "PE" (4550h) (Portable Executable) | |||||||||
LFANEW+2 | 1 | 0 | |||||||||
LFANEW+3 | 1 | 0 | |||||||||
LFANEW+4 | 2 | Machine (obvykle 14Ch - Intel) | |||||||||
LFANEW+6 | 2 | NumberOfSections - počet položek v SectionTable | |||||||||
LFANEW+8 | 4 | TimeDateStamp - datum a čas, kdy byl soubor vytvořenej | |||||||||
LFANEW+0Ch | 4 | PointerToSymbolTable | |||||||||
LFANEW+10h | 4 | NumberOfSymbols | |||||||||
LFANEW+14h | 2 | SizeOfOptionalHeader (OH) | |||||||||
LFANEW+16h | 2 | Characteristics | |||||||||
LFANEW+18h | 2 | OH Magic | |||||||||
LFANEW+1Ah | 1 | MajorLinkerVersion | |||||||||
LFANEW+1Bh | 1 | MinorLinkerVersion | |||||||||
LFANEW+1Ch | 4 | SizeOfCode | |||||||||
LFANEW+20h | 4 | SizeOfInitializedData | |||||||||
LFANEW+24h | 4 | SizeOfUninitializedData | |||||||||
LFANEW+28h | 4 | AddressOfEntryPoint | |||||||||
LFANEW+2Ch | 4 | BaseOfCode | |||||||||
LFANEW+30h | 4 | BaseOfData | |||||||||
LFANEW+34h | 4 | ImageBase | |||||||||
LFANEW+38h | 4 | SectionAlignment = 4096 or 8192 | |||||||||
LFANEW+3Ch | 4 | FileAlignment = 512 | |||||||||
LFANEW+40h | 2 | MajorOperatingSystemVersion | |||||||||
LFANEW+42h | 2 | MinorOperatingSystemVersion | |||||||||
LFANEW+44h | 2 | MajorImageVersion | |||||||||
LFANEW+46h | 2 | MinorImageVersion | |||||||||
LFANEW+48h | 2 | MajorSubsystemVersion | |||||||||
LFANEW+4Ah | 2 | MinorSubsystemVersion | |||||||||
LFANEW+4Ch | 4 | Reserved1 | |||||||||
LFANEW+50h | 4 | SizeOfImage | |||||||||
LFANEW+54h | 4 | SizeOfHeaders | |||||||||
LFANEW+58h | 4 | CheckSum | |||||||||
LFANEW+5Ch | 2 | Subsystem | |||||||||
LFANEW+5Eh | 2 | DllCharacteristics | |||||||||
LFANEW+60h | 4 | SizeOfStackReserve | |||||||||
LFANEW+64h | 4 | SizeOfStackCommit | |||||||||
LFANEW+68h | 4 | SizeOfHeapReserve | |||||||||
LFANEW+6Ch | 4 | SizeOfHeapCommit | |||||||||
LFANEW+70h | 4 | LoaderFlags | |||||||||
LFANEW+74h | 4 | NumberOfRvaAndSizes = 16 | |||||||||
LFANEW+78h | 8*16 | DataDirectory (RvaAndSizes) RVA = Ofset od ImageBase
IMAGE_DIRECTORY_ENTRY_EXPORT 0 IMAGE_DIRECTORY_ENTRY_IMPORT 1 IMAGE_DIRECTORY_ENTRY_RESOURCE 2 IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 IMAGE_DIRECTORY_ENTRY_SECURITY 4 IMAGE_DIRECTORY_ENTRY_BASERELOC 5 IMAGE_DIRECTORY_ENTRY_DEBUG 6 IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 IMAGE_DIRECTORY_ENTRY_TLS 9 IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 IMAGE_DIRECTORY_ENTRY_IAT 12 |
Počet položek = NumberOfSections
Pozice v souboru = LFANEW + 18h + SizeOfOptionalHeader
Ofset | Velikost | Význam |
---|---|---|
0 | 8 | Name |
8 | 4 | PhysicalAddress / VirtualSize |
12 | 4 | VirtualAddress |
16 | 4 | SizeOfRawData |
20 | 4 | PointerToRawData |
24 | 4 | PointerToRelocations |
28 | 4 | PointerToLinenumbers |
32 | 2 | NumberOfRelocations |
34 | 2 | NumberOfLinenumbers |
36 | 4 | Characteristics: 0x20 - kódová sekce (.text) 0x40 - inicializovaný data (.rdata, .data) 0x80 - neinicializovaný data (.bss) 0x04000000 - nelze cachovat 0x08000000 - nelze stránkovat 0x10000000 - sdílená sekce 0x20000000 - spustitelná sekce 0x40000000 - lze číst 0x80000000 - lze zapisovat |
Lineární adresa | Velikost | Význam |
---|---|---|
ImageBase = 0x400000 | SizeOfImage | Kód programu, inicializovaný data, resources |
0x7D850000 | 0x46000 | KernelBase.dll |
0x7DAB0000 | 0x90000 | gdi32.dll |
0x7DC50000 | 0x100000 | user32.dll |
0x7DD60000 | 0x100000 | kernel32.dll |