/LARGEADDRESSAWARE может испортить вам весь день

Только что потратил кучу времени на разборки с /LARGEADDRESSAWARE. Этот ключ используется для указания сборщику, что данный модуль (.exe или .dll) способен корректно обрабатывать адреса больше 2GB. Модули, помеченные подобным образом, могут быть загружены выше 2GB при условии, что система поддерживает увеличенное пользовательское адресное пространство. На данный момент это либо серверные версии Windows, сконфигурированные ключом /3GB в boot.ini, либо 64-х битные версии системы.

Про причины того, почему расширенное адресное пространство не включается для всех программ, хорошо написал Raymond Chen: Myth: The /3GB switch expands the user-mode address space of all programs. Дело как всегда в том, что слишком много приложений не будут работать в такой конфигурации - начинает буксовать арифметика указателей. Сегодняшний баг занёс ещё одну операцию в “черный” список.

Итак, какое значение будет присвоено переменной wide_ptr после инициализации (код компилируется для x86)?

PVOID ptr = (PVOID)0x87654321;
ULONGLONG wide_ptr = (ULONGLONG)ptr;

Ответ - 0xffffffff87654321! Очевидно, что проблема в расширении знака, однако это совсем не очевидно из данного отрывка кода. Чтобы результат получился верным, код нужно переписать вот так:

PVOID ptr = (PVOID)0x87654321;
ULONGLONG wide_ptr = (ULONGLONG)(ULONG_PTR)ptr;
comments powered by Disqus