Всем привет! Разбираюсь с заголовком EXE файла(DOS) Подскажите для чего нужна таблица настройки адресов ? Написал прогу для чтения заголовка, посмотрел на настройку адресов в таблице, она указывает на некий участок в программе, что это дает для программисту? Вирусу нужна эта таблица ? А если написать прогу чтобы она восстанавливала себя из памяти на диск, нужна таблица?
tahir Когда ехешник состоит из нескольких сегментов (не обязательно 65536 байт длиной каждый), для доступа к каждому сегменту (как коду, так и данным) приходится применять абсолютную адресацию сегмента. К примеру - вызов процедуры в другом сегменте - call 1234:5678 - смещение в сегменте всегда известно, а абсолютный адрес сегмента (1234) - нет, его загрузчик ФС динамически вычисляет при загрузке проги в память. Поэтому по таблице в шапке ехешника и происходит настройка абсолютов в уже загруженной проге.
Спасибо! Это я понял, но получается система держит эти переменные держит где-то, заголовок не грузиться в память?
tahir Система ничего в памяти не держит - считывает заголовок ехешника в память (всегда и обязательно), видит, сколько элементов надо настроить и согласно им считывает остальное от ехешника (причем не все, а только небходимое). Когда это положили в память, начинает корректировать абсолютные адреса сегментов. Когда коррекцию произвела (ведь ехешник может грузиться изначально по любому сегментгому адресу) - передает на него управление - он запускается.
Memphis интересно пообщаться с умными людьми... ведъ файл ехе считывается в память целиком , если не оверлей так ведъ, только код в один сегмент, данные в другой, стек в в третьем
ДОС грузит в память, если память не изменяет, не весь ехешник, а ровно столько, сколько указано в его заголовке, после чего производит настройку в соответствии с адресом загрузки и запускает файл на выполнение.
Некорректное утверждение. DOS резервирует N-ное количество параграфов, указанное в заголовке файла (не считая тех, что нужны для переменных среды и PSP), и в начало данной области загружает двоичный образ всех сегментов, после чего производит настройку сегментных адресов в пределах образа. Сегментов любого типа в файле может быть множество (в исполняемом файле они не различаются по типам, там лишь хранятся два указателя - точки входа и вершины стека), причем размером хоть по 16 байт.
tahir ведъ файл ехе считывается в память целиком , если не оверлей - да нет. ФС сама решает (правда, не знаю как), сколько кода надо положить в память. Пример - чистый ДОС (размер ОЗУ ограничен 10-ю сегментами). Запускаю, к примеру, Раровский SFX (ехешник), длиной пусть 30 МБ - разумеется, столько невозможно положить в ОЗУ за один присест - тем не менее, он успешно запускается и распаковывается.
ну во первых в конце у него оверлей с архивом, а во вторых в заголовке программы имеются все необходимые данные, на тему распределения памяти и адреса запуска
Phantom_84 только мне казалось что дос лишь принимает к сведению максимально необходимый размер памяти и отдает всю имеющуюся память в распоряжение программы. во всяком случае, чтобы запустить программу из программы с помощью функций доса нужно сначала освободить для нее память, не используемую текущей программой. это описано аж в 5 разных книгах, разных авторов по программированию под дос в разделах посвященных tsr-программам (Terminate and Stay Resident)
а вот тут могу не согласиться. переменных среды располагаются в разных версиях доса в разных областях, но в основном это либо адреса ниже первых 64 Кб, либо 64 Кб выше 1-го Мб и в отличие от PSP не куда оттуда не деваются, а вот PSP приклеивается к программе как целый отдельный сегмент, который принадлежит лично ей и существует пока программа не завершится.
Для COM-программы - да, для EXE-программы в MZ-заголовке есть поле, указывающее необходимый размер памяти, и (если я не ошибаюсь) выделяется только необходимый размер, а остаток остаётся свободным.
Представьте там аж даже два такие поля, первое нужно чтобы иногда выдавать сообщение out of memory. а второе чтобы знать надо ли перемещать часть command.com на диск, чтобы освободить часть памяти. больше эти поля никак системой не интерпретируются, а системный загрузчик всегда сливает программе всю память (ибо одна задача. зачем системе еще может понадобится память)
Да неужели? Вот фрагмент из исходников DosBox, ответственный за выделение памяти при запуске: Код (Text): /* Get Memory */ Bit16u minsize,maxsize;Bit16u maxfree=0xffff;DOS_AllocateMemory(&pspseg,&maxfree); if (iscom) { minsize=0x1000;maxsize=0xffff; if (machine==MCH_PCJR) { /* try to load file into memory below 96k */ pos=0;DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET); Bit16u dataread=0x1800; DOS_ReadFile(fhandle,loadbuf,&dataread); if (dataread<0x1800) maxsize=dataread; if (minsize>maxsize) minsize=maxsize; } } else { /* Exe size calculated from header */ minsize=long2para(imagesize+(head.minmemory<<4)+256); if (head.maxmemory!=0) maxsize=long2para(imagesize+(head.maxmemory<<4)+256); else maxsize=0xffff; } if (maxfree<minsize) { DOS_SetError(DOSERR_INSUFFICIENT_MEMORY); DOS_FreeMemory(envseg); return false; } if (maxfree<maxsize) memsize=maxfree; else memsize=maxsize; if (!DOS_AllocateMemory(&pspseg,&memsize)) E_Exit("DOS:Exec error in memory"); Тут прямо написано, что выделяемый размер памяти не превышает значения maxmemory из заголовка (может быть меньше, если свободной памяти меньше, но гарантированно не меньше minmemory). А DOSBox довольно точно эмулирует DOS. Added: Динамическая память (функции 48h/49h/4Ah) для этой задачи, естественно.