Подтвердить что ты не робот

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

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

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

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

ИЛИ

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

Ответ 3

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

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

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

Ответ 4

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

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

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

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

Ответ 5

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

Ответ 6

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

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

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

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

Ответ 7

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

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

Ответ 8

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

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

Ответ 9

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

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

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

Ответ 10

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