﻿# Урок 2\. Поддержка 32\-битных приложений в 64\-битной среде Windows

Прежде чем приступить к тематике разработки кода 64\-битных программ, остановимся на вопросе обратной совместимости 64\-битных версий Windows с 32\-битными приложениями\. Обратная совместимость осуществляется за счет механизмов, реализованных в [WoW64](https://pvs-studio.ru/ru/blog/terms/0056/)\.

**WoW64** \(Windows\-on\-Windows 64\-bit\) \- подсистема операционной системы Windows, позволяющая запускать 32\-битные приложения на всех 64\-битных версиях Windows\.

Подсистема WoW64 не поддерживает следующие программы:

* программы, скомпилированные для 16\-разрядных операционных систем;
* программы режима ядра, скомпилированные для 32\-разрядных операционных систем\.

## Накладные расходы

Существуют различия WoW64 в зависимости от архитектуры процессора\. Например, 64\-битная версия Windows разработанная для процессора Intel Itanium 2 использует WoW64 для эмуляции [x86](https://pvs-studio.ru/ru/blog/terms/0060/) инструкций\. Такая эмуляция весьма ресурсоемка по сравнению с WoW64 для архитектуры [Intel 64](https://pvs-studio.ru/ru/blog/terms/0022/), так как происходит переключение с 64\-битного режима в режим совместимости при выполнении 32\-битных программ\.

WoW64 на архитектуре Intel 64 \(AMD64 / x64\) не требует эмуляции инструкций\. Здесь подсистема WoW64 эмулирует только 32\-битное окружение за счет дополнительной прослойки между 32\-битным приложением и 64\-битным Windows API\. Где\-то эта прослойка тонкая, где\-то не очень\. Для средней программы потери в производительности из\-за наличия такой прослойки составят около 2%\. Для некоторых программ это значение может быть больше\. Два процента \- это немного, но следует учитывать, что 32\-битные приложения работают немного медленнее под управлением 64\-битной операционной системы Windows, чем в 32\-битной среде\.

Компиляция 64\-битного кода не только исключает необходимость в WoW64, но и дает дополнительный прирост производительности\. Это связано с архитектурными изменениями в микропроцессоре, такими, как увеличение количества регистров общего назначения\. Для средней программы можно ожидать в пределах 5\-15% прироста производительности от простой перекомпиляции\.

## Преимущество 64\-битной среды для 32\-битных программ

Из\-за наличия прослойки WoW64 32\-битные программы работают менее эффективно в 64\-битной среде, чем в 32\-битной\. Но все\-таки простые 32\-битные приложения могут получить одно преимущество от их запуска в 64\-битной среде\. Вы, наверное, знаете, что программа, собранная с ключом /LARGEADDRESSAWARE:YES, может выделять до 3\-х гигабайт памяти, если 32\-битная операционная система Windows запущена с ключом /3gb\. Так вот, эта же 32\-битная программа, запущенная на 64\-битной системе, может выделить почти 4 GB памяти \(на практике около 3\.5 GB\)\.

## Перенаправления

Подсистема WoW64 изолирует 32\-разрядные программы от 64\-разрядных путем перенаправления обращений к файлам и реестру\. Это предотвращает случайный доступ 32\-битных программ к данным 64\-битных приложений\. Например, 32\-битное приложение, которое запускает файл DLL из каталога %systemroot%\\System32, может случайно обратиться к 64\-разрядному файлу DLL, который несовместим с 32\-битной программой\. Во избежание этого подсистема WoW64 перенаправляет доступ из папки %systemroot%\\System32 в папку %systemroot%\\SysWOW64\. Это перенаправление позволяет предотвратить ошибки совместимости, поскольку при этом требуется файл DLL, созданный специально для работы с 32\-разрядными приложениями\.

Подробнее с механизмами перенаправления файловой системы и реестра можно познакомиться в разделе MSDN "[Running 32\-bit Applications](https://msdn.microsoft.com/en-us/library/aa384249(VS.85).aspx)"\.

## Почему невозможно использовать в 64\-битной программе 32\-битные DLL? Можно ли это обойти?

Загрузить 32\-битную DLL из 64\-битного процесса и выполнить код из неё невозможно\. Невозможно в силу дизайна 64\-битных систем\. В принципе, невозможно\. Не помогут ни хитрости, ни недокументированные пути\. Для этого нужно загрузить и проинициализировать WoW64, не говоря уже о структурах в ядре\. Фактически нужно будет на лету превратить 64\-битный процесс в 32\-х битный\. Подробнее эта тема рассмотрена в посте "[Недокументированные функции; Загрузка 32\-х битных DLL в 64\-х битный процесс](https://blog.not-a-kernel-guy.com/2008/02/28/293/)"\. Единственное, что можно порекомендовать, \- это создание суррогатного процесса и взаимодействия с ним посредством технологии COM\. Об этом рассказывается в статье "[Accessing 32\-bit DLLs from 64\-bit code](https://blog.mattmags.com/2007/06/30/accessing-32-bit-dlls-from-64-bit-code/)"\.

А вот загрузить ресурсы из 32\-битной DLL в 64\-битный процесс совсем несложно\. Это можно сделать, если при вызове LoadLibraryEx указать флаг LOAD\_LIBRARY\_AS\_DATAFILE\.

## Постепенный отказ от поддержки 32\-битных программ

Вполне естественно, если компания Microsoft будет стимулировать переход на 64\-битные системы, постепенно отказываясь от поддержки 32\-битных программ в ряде версий операционной системы Windows\. Конечно, это будет очень медленный процесс\. Но все\-таки первые шаги в этом направлении уже сделаны\.

Многие администраторы знают про относительно новый режим установки и работы серверной версии операционной системы под названием Server Core\. Это тот режим, о котором участники войн "Windows vs Linux" говорили очень давно\. Одним из аргументов сторонников использования Linux на сервере была возможность установить серверную ОС без графического интерфейса \(GUI\)\. Но вот и в Windows Server появилась такая возможность\. Установка в этом режиме позволяет получить только командную строку без пользовательского интерфейса\.

Эта возможность \(установка Server Core\) появилась в Windows Server 2008\. Но в Windows Server 2008 R2 появилось нововведение, приближающее 64\-битное будущее\. При установке Windows Server 2008 R2 \(Server Core\) поддержка запуска 32\-битных приложений стала опциональной\. Причем по умолчанию эта поддержка выключена\. И при попытке запуска 32\-битного приложения в режиме Server Core пользователь получит сообщение о невозможности запуска\. Конечно, можно добавить поддержку 32\-битных программ:

start /w ocsetup ServerCore\-WOW64

В обычном \(Full Installation\) режиме 32\-битные приложения по умолчанию запускаются, а вот в Server Core уже нет\.

Тенденция очевидна\. Со временем все более рациональным будет создание 64\-битных версий приложений, так как они смогут функционировать на большем числе версий операционных систем\.

## Дополнительная информация

Интересным источником информации по системе WoW64 является блог Алексея Пахунова: [http://blog\.not\-a\-kernel\-guy\.com/](https://blog.not-a-kernel-guy.com/)\. Алексей является сотрудником компании Microsoft и принимает непосредственное участие в разработке подсистемы WoW64\.

Авторы курса: Андрей Карпов \([karpov@viva64\.com](mailto:karpov@viva64.com)\), Евгений Рыжков \([evg@viva64\.com](mailto:evg@viva64.com)\)\.

Правообладателем курса "Уроки разработки 64\-битных приложений на языке Си/Си\+\+" является ООО "Системы программной верификации"\. Компания занимается разработкой программного обеспечения в области анализа исходного кода программ\. [Сайт компании](https://pvs-studio.ru/ru/pvs-studio/)\.