====== PSX-EXE ====== Формат загрузочного образа (исполняемого файла) PlayStation. ===== Заголовок (2048 байт)===== * 8 байт - строка "PS-X EXE": [0x50, 0x53, 0x2d, 0x58, 0x20, 0x45, 0x58, 0x45]; * 8 байт - неиспользуемые, заполняются нулями; * 32 бит - абсолютный адрес входной точки программы; * 32 бит - начальное значение глобального указателя (GP); * 32 бит - абсолютный адрес загрузки (адрес памяти, в который помещается машинный код программы). Размер памяти, доступной программе, равен RAM_LENGTH в формуле ниже; * 32 бит - размер кода программы в байтах (не считая 2048 байт заголовка). Рассчитывается как разница адресов секций .text и .bss - то есть, этот участок памяти включает в себя код и инициализированные данные, загружаемые из образа (.text, .ctors, .dtors, .data, .rdata, .sdata). Размер кода должен быть кратным 2048 байтам; * 16 байт - неиспользуемые, заполняются нулями; * 32 бит - адрес начала стека. Стек растет вниз от этого адреса, поэтому начало должно быть в верхней части [[RAM]]. Обычно задается как 0x801FFF00, но многие примеры используют 0x801FFFF0 (ближе к верхней границе памяти). Оба варианта валидные; * 32 бит - начальное смещение стека. Обычно 0; * 24 байта - зарезервированные, заполняются нулями; Начиная со смещения 0x04C обычно идет маркер региона: * "Sony Computer Entertainment Inc. for Japan area" для Японии; * "Sony Computer Entertainment Inc. for Europe area" для Европы; * "Sony Computer Entertainment Inc. for North America area" - для Северной Америки. BIOS игнорирует эти строки, поэтому их можно не заполнять. Заголовок образа должен находиться в верхней части [[BIOS]]-сегмента памяти. Код программы (начиная с секции .text) может быть загружен в любой адрес в свободной памяти, но обычно идет сразу после BIOS, т.е. по адресу 0x80010000 (0x80000000 + 64K). ===== Данные (выровнены по 2048 байт) ===== Начиная с 0x800 идет машинный код (+ инициализированные данные) программы. Типовая схема памяти при загрузке образа: RAM_BASE = 0x80000000 RAM_SIZE = 2M BIOS_SIZE = 64K HEADER_SIZE = 2K LOAD_ADDR = RAM_BASE + BIOS_SIZE HEADER = LOAD_ADDR - HEADER_SIZE RAM = LOAD_ADDR RAM_LENGTH = RAM_SIZE - BIOS_SIZE STACK_INIT = RAM_BASE + 0x001FFF00; Можно заметить, что между началом стека и концом памяти остается запас в 256 байт (0x80200000 - 0x801FFF00 = 0x100). Для чего он нужен, точно не известно - возможно, тоже какой-то резерв для BIOS.