Может ли компилятор C генерировать исполняемый 64-битный код, где указатели 32-битные? - PullRequest
18 голосов
/ 07 ноября 2010

Большинство программ хорошо вписывается в адресное пространство <4 ГБ, но необходимо использовать новые функции, доступные только в архитектуре x64. </p>

Существуют ли компиляторы / платформы, где я могу использовать регистры x64 и специальные инструкции, но сохраняя 32-битные указателидля экономии памяти?

Возможно ли сделать это прозрачно на устаревшем коде?Какой переключатель сделать это?

ИЛИ

Какие изменения в коде необходимы для получения 64-битных функций при сохранении 32-битных указателей?

Ответы [ 10 ]

16 голосов
/ 07 ноября 2010

Простой способ обойти это, если у вас есть только несколько типов для ваших структур, на которые вы указываете.Тогда вы можете просто выделить большие массивы для ваших данных и выполнить индексацию с помощью uint32_t.

Так что «указатель» в такой модели будет просто индексом в глобальном массиве.Обычно обращение с этим должно быть достаточно эффективным с приличным компилятором, и это сэкономит вам немного места.Вы потеряете другие вещи, которые могут вас заинтересовать, например, динамическое распределение.

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

4 голосов
/ 19 августа 2012

Стоит отметить, что в настоящее время разрабатывается ABI для linux, X32, который позволяет создавать двоичный файл x86_64, использующий 32-битные индексы и адреса.

Только относительно новый, но, тем не менее, интересный.

http://en.wikipedia.org/wiki/X32_ABI

4 голосов
/ 07 ноября 2010

Технически это возможно для компилятора.AFAIK, на практике это не сделано.Он был предложен для gcc (даже с патчем здесь: http://gcc.gnu.org/ml/gcc/2007-10/msg00156.html), но никогда не интегрировался (по крайней мере, он не был задокументирован в последний раз, когда я проверял). Насколько я понимаю, ему также нужна поддержка со стороны ядра и стандартабиблиотека для работы (т. е. ядро ​​должно было бы настроить вещи так, как это в настоящее время невозможно, и использование существующего 32- или 64-битного ABI для взаимодействия с ядром было бы невозможным).

3 голосов
/ 08 ноября 2010

Какие именно «64-битные функции» вам нужны, не правда ли, они немного расплывчаты?

Нашел это, ища ответ: http://www.codeproject.com/KB/cpp/smallptr.aspx

Также поднимите обсуждение внизу ...

Никогда не приходилось думать об этом, но интересно осознавать, что можно беспокоиться о том, сколько нужно указателей пространства ...

2 голосов
/ 07 ноября 2010

На x86 нет. На других процессорах, таких как PowerPC, это довольно распространено - 64-битные регистры и инструкции доступны в 32-битном режиме, тогда как в x86 это, как правило, «все или ничего».

1 голос
/ 17 февраля 2012

Я думаю, что это будет похоже на MIPS n32 ABI: 64-битные регистры с 32-битными указателями.

В ABI n32 все регистры являются 64-битными (поэтому требуется процессор MIPS64). Но адреса и указатели являются только 32-разрядными (при хранении в памяти), уменьшая объем памяти. При загрузке 32-разрядного значения (такого как указатель) в регистр оно расширяется до 64-разрядного знака. Когда процессор использует указатель / адрес для загрузки или сохранения, используются все 64-разрядные (процессор не знает о n32-ess SW). Если ваша ОС поддерживает программы n32 (возможно, ОС также следует модели n32 или это может быть надлежащая 64-разрядная ОС с добавленной поддержкой n32), она может найти всю память, используемую приложением n32, в подходящей памяти (например, младшие 2 ГБ и выше 2ГБ, виртуальные адреса). Единственный недостаток этой модели в том, что при сохранении регистров в стеке (вызовы функций и т. Д.) Используются все 64-битные модели, в n32 ABI нет 32-битной модели данных.

Вероятно, такой ABI мог бы быть реализован и для x86-64.

1 голос
/ 07 ноября 2010

Боюсь, что если вас беспокоит размер указателей, у вас могут возникнуть более серьезные проблемы.Если число указателей будет в миллионах или миллиардах, вы, вероятно, столкнетесь с ограничениями в ОС Windows, прежде чем фактически исчерпаете физическую или виртуальную память.

Марк Руссинович написал отличную статью, касающуюсяк этому, названный Расширение границ Windows: виртуальная память .

1 голос
/ 07 ноября 2010

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

Насколько я знаю, невозможно иметь 32-битные указатели в 64-битном собственном коде.

1 голос
/ 07 ноября 2010

Это зависит от платформы.В Mac OS X первые 4 ГБ адресного пространства 64-битного процесса зарезервированы и не отображаются, предположительно в качестве функции безопасности, поэтому нет 32-битное значение всегда ошибочно дляуказательЕсли вы попытаетесь, возможно, есть способ победить это.Однажды я обошел его, написав класс C ++ «указатель», который добавляет 0x100000000 к сохраненному значению.(Это было значительно быстрее, чем индексирование в массив, что также требует поиска базового адреса массива и умножения перед добавлением.)

На уровне ISA вы, безусловно, можете выбрать загрузку и расширение нуля 32.-bit значение, а затем использовать его в качестве 64-битного указателя.Это хорошая возможность для платформы.

Никаких изменений в программе не требуется, если вы не хотите использовать 64-битные и 32-битные указатели одновременно.В этом случае вы возвращаетесь к плохим старым временам с указателями near и far.

Кроме того, вы наверняка нарушите совместимость ABI с API, которые переводят указатели на указатели.

0 голосов
/ 21 февраля 2014

Linux теперь имеет достаточно всестороннюю поддержку ABI X32, которая выполняет именно то, о чем спрашивает аскер, фактически она частично поддерживается как конфигурация в операционной системе Gentoo. Я думаю, что этот вопрос необходимо пересмотреть в свете недавнего развития.

...