Несовместимость 16-разрядной сборки с 64-разрядной windows 7


Недавно я обнаружил, что 64-битное окно не будет запускать 16-битные приложения (в данном случае.com), потому что 64-битная windows не имеет 16-битной подсистемы (или так говорит интернет). Я столкнулся с этим, когда пытался выполнить an .bat-файл, который требовал редактирования.

У меня есть довольно большой опыт работы с сборкой x86, но я никогда не писал программ для работы под windows (или любой другой ОС, если на то пошло). Из-за обратной совместимости семейства x86 я никогда не уделял особого внимания насколько же битной была моя программа. Пока он не использовал инструкции, которые не были введены в процессор, на котором должна была работать программа, все было в порядке.

Мой вопрос: что именно делает код 16, 32 или 64 битным, что вызывает проблемы несовместимости 16-битных приложений, по-видимому, есть?

Можно ли разобрать небольшие 16-битные приложения и немного изменить, чтобы заставить их работать, или это действительно неразумно?

Update: я не ищу способ запустить их такие приложения, как это есть, то есть через эмуляторы или другие программы, которые я могу разработать для себя. Я просто хочу понять основные механики, которые заставляют windows принимать или отклонять программу.

6 4

6 ответов:

Чтобы запустить "16-битное приложение", которое в данном случае означает приложение DOS, Windows® необходимо настроить задачу в режиме VM86. Проблема в том, что это работает, когда процессор находится в 32-разрядном режиме VPAM (Virtual Protected Address Mode), который используется ОС i386, но не тогда, когда процессор находится в так называемом "длинном режиме", введенном AMD. Процессор amd64 "Long Mode" поддерживает только выполнение 32-разрядных и 64-разрядных задач.

Итак, 64-битное ядро ОС не имеет возможности запускать 16-битные задачи непосредственно на процессоре, вы всегда нужно использовать какую-то эмуляцию. Если вы найдете ОС, которая может это сделать, она либо имеет встроенную эмуляцию, либо работает в 32-битном режиме вместо 64-битного, либо работает как в 32-битном, так и в 64-битном режиме и счастливо переключается между ними в каком-то злом, извращенном взломе, о котором я где-то читал.

По опыту, использование DOSBOX-это ваш лучший выбор.

Edit: как Windows® обнаруживает, что не может выполнить ваш код?

Это во многом зависит от типа программы обнаруженный. Есть пакетные файлы (BAT, CMD) которые он знает, чтобы обрабатывать, PIF файлы (я думаю, что они все еще не убили их), и, наконец, COM и EXE исполняемые файлы. Случай COM прост: 65280 байт-Макс. 16-битная программа MS-DOS®, выход. EXE файлы, с другой стороны, имеют определенные заголовки файлов: один для 16-битного DOS (или Win3.x) часть (ключевое слово: MZ), одна для 32-разрядной / 64-разрядной части (LE, LX, PE (по крайней мере), a. out и COFF-ключевые слова здесь, некоторые из которых используются для OS / 2 совместимость или только ею, некоторые различными вариантами NT).

На самом деле существует несколько проблем. Во-первых, процессор имеет разные режимы работы для каждой "разрядности". Но для каждого типа приложений требуется среда выполнения, выходящая за пределы разрядности. Он называетсяприкладной двоичный интерфейс (ABI). Например, файлы. com содержат код, который ожидает реального режима DOS среды, включая определенное оборудование. Более ранние версии windows должны были запускать что-то похожее на DosBox, чтобы запустить их. Каждый тип исполняемому файлу может не требоваться полная эмуляция аппаратного обеспечения, но для взаимодействия с основной операционной системой требуется большой объем кода. Таким образом, для каждого типа исполняемого файла операционная система будет проверять, какая среда выполнения необходима, и отказываться запускать исполняемый файл, если он не может предоставить правильную среду.

Мой вопрос: что именно делает код 16, 32 или 64 бит, что запускает проблемы несовместимости 16-битных приложений видимо есть?

Ну: очевидный ответ будет: зависит от того, что программа использует 8,16,32 или 64-битные регистры. Очевидно, но не верно: программа, работающая в MS DOS, может использовать 8,16 или 32-битные регистры, если процессор поддерживает их. Кроме того, программа Windows может использовать (и действительно использует) 8-и 16-разрядные регистры, помимо использования 32-разрядных регистры и (если процессор и ОС его поддерживают) 64-битные регистры.

Вопрос, я думаю, должен быть: что именно заставляет программу работать под DOS или Windows 32 бит или Windows 64 бит.

Во-первых , структура исполняемого файла. 32-разрядный или 64-разрядный исполняемый файл Windows-это не то же самое, что 16-разрядный исполняемый файл. Windows использует так называемый "портативный исполняемый файл" (сокращение от PE). MS DOS использует как файлы. COM (унаследованные от CP / M), так и .EXE файлы (также известные как исполняемые файлы MZ).

Во-вторых : одна программа хранится в памяти и начинает выполняться, там есть некоторая среда, которую программа ожидает там, например, армия вызовов функций, доступ к которым осуществляется специальными инструкциями, такими как INT, которые отвечают за выполнение различных задач, от вывода символа на консоль, до открытия и чтения файлов и многое другое.

В-третьих : приложения MS DOS ожидают, что некоторые структуры в памяти будут находиться на определенном уровне адрес памяти; например, память экрана. Кроме того, он ожидает, что некоторые устройства ввода-вывода будут существовать по определенному адресу ввода-вывода. Многие так называемые "плохие поведенческие" приложения не используют BIOS или DOS для печати на экране,а записывают непосредственно в память экрана для более быстрого вывода. Я помню настройку в Turbo Pascal, Turbo Basic или, может быть, Turbo C compiler, чтобы программист мог выбирать функции вывода консоли для прохождения через BIOS или непосредственно к аппаратному обеспечению.

Четвертое : программа ожидает процессор должен вести себя определенным образом. 16-битные программы DOS предназначены для использования так называемого реального режимапроцессоров x86, и этот режим навязывает свое особое видение адресов памяти, чтобы назвать наиболее отчетливую особенность этого режима. С появлением 32-битных ОС, которые переводят процессор в защищенный режим , программы реального режима не могут работать, потому что способ работы адресов памяти в защищенном режиме очень отличается от способа работы в реальном режиме.

ОС для запуска исполняемых файлов MZ требуетсякакой-то загрузчик для этих файлов (чтобы соответствовать первому пункту) и среда, которая должна имитировать ту, в которой приложение должно работать (чтобы соответствовать остальным пунктам). В мире Linux эти компоненты являются частью того, что они называют личностями (способ для Linux запускать код из других ОС, таких как FreeBSD, при условии, что код предназначен для одного и того же процессора на обеих платформах). В мире Windows это так известен какподсистемы . Windows XP и Windows 7, например, имеют подсистемуWin32 и подсистемуDOS . Древние версии Windows (возможно, Windows NT 3.5 или NT 4.0) также имели личностьOS/2 , способную запускать 16-битные текстовые приложения OS/2.

Итак, ваша ОС Windows нуждается в соответствующей подсистеме для запуска кода, предназначенного для другой ОС, такой как MS DOS. Но процессор должен помочь любым возможным способом. Это происходит потому, что платформа x86 ввел 8086 виртуальный режим в 80386: чтобы иметь возможность создавать задачи, в которых процессор ведет себя очень похоже на реальный режим 8086.

Таким образом, с помощью самого процессора, соответствующий загрузчик, обработчик INT, способный переводить запрос DOS в запрос Windows, интеллектуальный обработчик страниц, способный перехватывать доступы к определенным разделам памяти и переводить их в запросы на рисование символов на экране, и обработчик ошибок ввода-вывода, способный олицетворять устройства, с которыми приложение использовало для работы, программы, написанные для DOS, могут работать под управлением Windows или Linux (DOSemu)

Итак, что происходит с 64 битами? Чтобы код мог работать с доступом к 64-разрядным регистрам, используется другой вид защищенного режима, называемыйlong mode . Я мало что знаю об этом длинном режиме, но из того, что я прочитал, этот режим не позволяет процессору создавать задачу, используя виртуальный режим 8086. Существует еще один режим, называемый совместимость mode или что-то в этом роде, что позволяет процессору создавать 64 и 32-разрядные задачи, но не 8086 виртуальных задач mode.

Без помощи процессора подсистему DOS очень трудно создать: Вы можете имитировать карту памяти, перехватывать любой доступ к специальным областям памяти или вводу / выводу, перехватывать инструкции INT, но, кроме того, вы должны перехватывать любую попытку обновить регистры сегментов, чтобы попытаться также имитировать адресацию реального режима, и я на самом деле не уверен, что сегменты используются в долгосрочной перспективе. режим. Это выполнимо, поскольку такие приложения, как DOSBox, доказывают это, но Microsoft больше не нуждается в DOS (она не нуждалась в нем в течение длительного времени, но клиенты не разделяли их точку зрения до, возможно, введения Windows 2000/XP). 32-разрядная Windows 7 может использовать ту же подсистему DOS, что и предыдущие версии Windows (я даже читал некоторое время назад о взломе, чтобы вернуть подсистему OS/2 обратно в Windows 2000 или Windows XP), Но для Windows 7 64-разрядной должна была быть разработана полностью новая подсистема DOS (или купленный).

Подробнее здесь: http://www.codeproject.com/Articles/45788/The-Real-Protected-Long-mode-assembly-tutorial-for#Main

Общий подход заключается в использовании эмулятора, такого какDosBox . Нет способа изменить что-то в двоичном файле, чтобы заставить его работать с использованием другого набора команд. Это должно быть сделано, начиная с исходного кода.

Установите DOSBox и получайте удовольствие. Это бесплатно в http://www.dosbox.com/

Правка:

Разрядность кода означает предположения о размере регистра/операнда. С другой стороны, текущая "разрядность" процессора составляет 16 в реальном режиме, а в защищенном режиме это флаг в структуре памяти, который описывает текущий выполняемый фрагмент кода (дескриптор сегмента и/или запись страницы, если быть точным). ОС настраивает указанные метаданные памяти и поддерживает их разрядность. Зависящий в последнем случае те же биты команды могут означать

add ax, bx

Или

add eax, ebx

Или

add rax, rbx

Разрядность процессора и предположения кода лучше совпадают. Если они этого не сделают, то не пройдет много времени, прежде чем приложение выйдет из строя или начнет плохо себя вести. Как только код пытается загрузить, скажем, регистр из памяти, а размер регистра на уровне процессора не соответствует тому, что думает код, процессор загружает мусор (или не загружает часть регистра). Только представь, что будет с этим человеком. следующее в 32-битном режиме:

MyData dw 0x17 ;2 bytes of data
SomeOtherData dw 0x200 ;2 more
...
mov ax, [MyData] ;We think we mean AX, but the CPU thinks it's EAX

EAX будет загружать значение 0x2000017. Определенно не то, что ожидает программа. Теперь представьте, что программа затем сравнивает значение с 0x17 и делает условный прыжок на основе этого.

Можно вручную перевести 16-битную сборку реального режима в 32-битный защищенный режим, но это будет не просто перевод имен регистров. Из программы DOS вы должны были бы перейти к программе Windows, и это другая группа. Не простой перевод-скорее портирование.

Это чисто коммерческое решение - просто нет технической причины, о чем свидетельствует тот факт, что ваша машина сама может запускать 64-битную или 32-битную версию windows7 - ваш выбор, и вы можете запустить эмулятор Microsoft XP, который будет запускать файлы .COM.

У Microsoft явно есть доступная технология - она описана здесь, но не позволяет ей работать на выпусках Home*.