В компьютерном программировании самоперемещающаяся программа — это программа, которая при запуске перемещает свои собственные адресно-зависимые инструкции и данные и, следовательно, может быть загружена в память по любому адресу. [1] [2] Во многих случаях самоперемещающийся код также является формой самомодифицирующегося кода .
Самоперемещение похоже на процесс перемещения , используемый компоновщиком - загрузчиком , когда программа копируется из внешнего хранилища в основную память; разница в том, что перемещение выполняет сама загруженная программа, а не загрузчик в операционной системе или оболочке .
Одна из форм самоперемещения происходит, когда программа копирует код своих инструкций из одной последовательности мест в другую последовательность мест в пределах основной памяти одного компьютера, а затем передает управление процессором от инструкций, находящихся в исходных местах памяти, к инструкциям, находящимся в целевых местах памяти. Таким образом, данные, с которыми работает алгоритм программы, представляют собой последовательность байтов, которые определяют программу.
Статическое самоперемещение обычно происходит во время загрузки (после того, как операционная система загрузила программное обеспечение и передала ему управление, но еще до завершения его инициализации), а иногда также при изменении конфигурации программы на более позднем этапе во время выполнения . [3] [4]
Например, самоперемещение часто используется на ранних этапах загрузки операционных систем на архитектурах, подобных совместимым с IBM PC , где загрузчики цепочки нижнего уровня (такие как главная загрузочная запись (MBR), загрузочная запись тома (VBR) и начальные этапы загрузки операционных систем, таких как DOS ) перемещаются со своего места, чтобы загрузить в память следующий этап.
В CP/M отладчик Dynamic Debugging Tool (DDT) динамически перемещался в верхнюю часть доступной памяти посредством перемещения границ страниц , чтобы максимизировать область переходных программ (TPA) для запуска программ. [5] [6]
В 1988 году альтернативный процессор командной строки ZCPR 3.4 для Z-System представил так называемые программы типа 4 , которые также могли самостоятельно перемещаться через встроенную заглушку. [7] [8] [9] [10] [11]
В DOS самоперемещение иногда также используется более продвинутыми драйверами и резидентными системными расширениями (RSX) или программами terminate-and-stay-resident (TSR), загружающими себя "высоко" в верхнюю память более эффективно, чем это возможно для внешних "высоких"-загрузчиков (таких как LOADHIGH / HILOAD , INSTALLHIGH / HIINSTALL или DEVICEHIGH / HIDEVICE и т. д. [12] начиная с DOS 5), чтобы максимизировать память, доступную для приложений. Это связано с тем, что операционная система не имеет знаний о внутренней работе драйвера, который нужно загрузить, и поэтому должна загрузить его в свободную область памяти, достаточно большую, чтобы вместить весь драйвер как блок, включая его код инициализации, даже если он будет освобожден после инициализации. Для TSR операционная система также должна выделить префикс сегмента программы (PSP) и сегмент окружения . [13] Это может привести к тому, что драйвер не будет загружен в наиболее подходящую свободную область памяти или даже вообще не позволит ему загрузиться высоко. В отличие от этого, самоперемещающийся драйвер может быть загружен в любое место (включая обычную память ), а затем переместить только его (обычно гораздо меньшую) резидентную часть в подходящую свободную область памяти в верхней памяти. Кроме того, усовершенствованные самоперемещающиеся TSR (даже если они уже загружены в верхнюю память операционной системой) могут перемещаться по большей части своего собственного сегмента PSP и буфера командной строки и освобождать свой сегмент среды, чтобы еще больше уменьшить результирующий след памяти и избежать фрагментации . [14] Некоторые самоперемещающиеся TSR также могут динамически изменять свою «природу» и трансформироваться в драйверы устройств, даже если изначально были загружены как TSR, тем самым обычно также освобождая некоторую память. [4] Наконец, технически невозможно, чтобы внешний загрузчик переместил драйверы в расширенную память (EMS), верхнюю область памяти (HMA) или расширенную память (через DPMS или CLOAKING ), поскольку эти методы требуют, чтобы небольшие специфичные для драйвера заглушки оставались в обычной или верхней памяти для координации доступа к целевой области перемещения, [15] [примечание 1] [примечание 2] а в случае драйверов устройств еще и потому, что заголовок драйвера всегда должен оставаться в первом мегабайте. [15] [13]Чтобы достичь этого, драйверы должны быть специально спроектированы для поддержки самостоятельного перемещения в эти районы. [15]
Некоторые расширенные драйверы DOS также содержат как драйвер устройства (который будет загружен по смещению +0000h операционной системой), так и TSR (загружаемый по смещению +0100h), разделяющие общую часть кода внутри как fat binary . [13] Если общий код не разработан как позиционно-независимый , он требует некоторой формы внутреннего исправления адреса, аналогичного тому, что в противном случае уже было бы выполнено перемещающимся загрузчиком ; это похоже на стадию исправления при самоперемещении, но с кодом, уже загруженным в целевое местоположение загрузчиком операционной системы (вместо того, чтобы это делал сам драйвер).
IBM DOS/360 не имела возможности перемещать программы во время загрузки. Иногда поддерживалось несколько версий программы, каждая из которых создавалась для разного адреса загрузки ( раздела ). Особый класс программ, называемых самоперемещающимися программами, был закодирован для перемещения себя после загрузки. [16] IBM OS/360 перемещала исполняемые программы, когда они загружались в память. Требовалась только одна копия программы, но после загрузки программа не могла быть перемещена (так называемый одноразовый позиционно-независимый код ).
В качестве экстремального примера (многократного) самоперемещения, также называемого динамическим самоперемещением, можно построить компьютерную программу так, чтобы она не оставалась по фиксированному адресу в памяти, даже во время выполнения, как, например, используется в тестах памяти червей . [17] [18] [19] [20] Apple Worm также является динамическим самоперемещающимся. [21]
[…] Лоус: […] «
динамическое перемещение
» ОС. Можете ли вы рассказать нам, что это такое и почему это было важно? […]
Юбэнкс
: […] то, что сделал
Гэри
[…], было […] ошеломляющим. […] Я помню тот день в
школе,
когда он вбежал в лабораторию и сказал: «Я придумал, как
переместить
». Он воспользовался тем фактом, что единственным байтом всегда будет
байт старшего порядка
. И поэтому он создал
битовую карту
. […] неважно, сколько памяти у компьютера, операционную систему всегда можно переместить в старшую память. Поэтому вы могли бы коммерциализировать это […] на машинах с разным объемом памяти. […] вы не могли бы продавать 64K
CP/M
и 47K CP/M. Было бы просто смешно иметь жесткую компиляцию в адресах. Так что Гэри понял это однажды ночью, вероятно, посреди ночи, думая о чем-то кодирующем, и это действительно сделало CP/M возможным для коммерциализации. Я действительно думаю, что без этого перемещения это была бы очень сложная проблема. Чтобы заставить людей купить его, это покажется им сложным, и если вы добавите больше памяти, вам придется пойти и получить другую операционную систему. […]
Intel
[…]
перевернула байты
, верно, для адресов памяти. Но они всегда были в одном и том же месте, поэтому вы могли переместить его на
границу 256 байт
, если быть точным. Поэтому вы всегда могли переместить его с помощью всего лишь битовой карты того, где эти […] Законы: Безусловно, самое красноречивое объяснение, которое я когда-либо получал о динамическом перемещении […][5][6] (33 страницы)
[…] Добавьте заголовок драйвера устройства SYS в драйвер, чтобы CTMOUSE мог быть
как в одном
, обычной
TSR
, так и в драйвере устройства - аналогично нашему расширенному драйверу клавиатуры FreeKEYB. […] Это на самом деле не нужно в
DR DOS
, поскольку
INSTALL
= поддерживается с DR DOS 3.41+, а DR DOS сохраняет порядок директив
[D]CONFIG.SYS
[…] но это […] улучшит […] гибкость в системах
MS-DOS
/
PC DOS
, которые […] всегда выполняют директивы
DEVICE
= перед любыми операторами INSTALL=, независимо от их порядка в файле. […] программное обеспечение может потребовать, чтобы драйвер мыши присутствовал в качестве драйвера устройства, поскольку драйверы мыши всегда были драйверами устройств в старые времена. Эти драйверы мыши имели определенные имена драйверов устройств в зависимости от используемого ими протокола («
PC$MOUSE
» для
режима систем мыши
, например), и некоторое программное обеспечение может искать эти драйверы, чтобы узнать правильный тип используемой мыши. […] Другим преимуществом было бы то, что драйверы устройств обычно потребляют меньше памяти (нет
среды
, нет
PSP
) […] Это в основном сложный заголовок файла, другой код для разбора командной строки, другая точка входа и строка выхода, и некоторая магия сегментов для преодоления разницы ORG 0 / ORG 100h. Самостоятельная загрузка драйвера устройства немного сложнее, поскольку вам нужно оставить заголовок драйвера там, где он есть, и только переместить остальную часть драйвера […]
[…] По крайней мере,
MS-DOS 6.0
+
GRAFTABL
перемещается по частям своего сегмента
PSP
(смещение +60h и выше), чтобы минимизировать свой резидентный размер. […](Примечание. GRAFTABL 2.00+ после DR-DOS 7.03 также поддерживает динамическое самоперемещение.)
[…] DOSRELO предоставляет метод, позволяющий сделать проблемные программы
DOS
самоперемещающимися. DOSRELO реализует возможность самоперемещения для всех программ, независимо от языка, путем добавления логики точки входа в
объектный код
программы до того, как
редактор связей
каталогизирует ее в
Core Image Library
. […]
[…] Помимо извлечения инструкции,
Z80
использует половину цикла для
обновления
динамической
оперативной памяти
. […] поскольку Z80 должен тратить половину каждого цикла
извлечения инструкции
на выполнение других задач, у него не так много времени для извлечения
байта инструкции
, как для байта данных. Если одна из
микросхем ОЗУ
в месте доступа к памяти немного медленная, Z80 может получить неправильную комбинацию битов при извлечении инструкции, но получить правильную при считывании данных. […] встроенный тест памяти не выявит этот тип проблем […] это строго тест чтения/записи данных. Во время теста все выборки инструкций производятся из ПЗУ
,
а не из ОЗУ […] в результате чего
H89
проходит тест памяти, но все еще работает нестабильно в некоторых программах. […] Это программа, которая тестирует память, перемещаясь через ОЗУ. При этом ЦП печатает текущий адрес программы на ЭЛТ
,
а затем извлекает инструкцию по этому адресу. Если микросхемы ОЗУ в порядке по этому адресу, ЦП перемещает тестовую программу в следующую ячейку памяти, печатает новый адрес и повторяет процедуру. Но если одна из микросхем ОЗУ достаточно медленная, чтобы вернуть неправильную комбинацию битов, ЦП неправильно истолкует инструкцию и будет вести себя непредсказуемо. Однако вполне вероятно, что дисплей зависнет, отображая адрес неисправной микросхемы. Это сужает проблему до восьми микросхем, что является улучшением по сравнению с проверкой целых 32. […] Программа […] выполнит
тест на червя
, передав инструкцию RST 7 (RESTART 7) из нижнего конца памяти до последнего рабочего адреса. Остальная часть программы остается неподвижной и обрабатывает отображение текущего местоположения команды RST 7 и ее
перемещение
. Кстати, программа называется тестом на червя, потому что, когда инструкция RST 7 перемещается вверх по памяти, она оставляет за собой
липкий след
из
NOP
(NO OPERATION). […]