studio - ¿Puede un compilador de C generar un ejecutable de 64 bits donde los punteros son de 32 bits?
exportar exe c# (10)
La mayoría de los programas se adaptan bien al espacio de direcciones de <4GB, pero necesitan usar nuevas funciones solo disponibles en la arquitectura x64.
¿Hay compiladores / plataformas donde pueda usar registros x64 e instrucciones específicas pero conservando los punteros de 32 bits para ahorrar memoria?
¿Es posible hacer eso de forma transparente en el código heredado? ¿Qué cambio para hacer eso?
O
¿Qué cambios en el código es necesario para obtener características de 64 bits mientras se mantienen los punteros de 32 bits?
¿Qué son exactamente las "características de 64 bits" que necesita, no es un poco vago?
Encontré esto mientras buscaba una respuesta en mi mismo: http://www.codeproject.com/KB/cpp/smallptr.aspx
También retomar la discusión en la parte inferior ...
Nunca tuve la necesidad de pensar en esto, pero es interesante darse cuenta de que uno puede preocuparse por la cantidad de espacio que necesitan los punteros ...
Creo que esto sería similar al MIPS n32 ABI: registros de 64 bits con punteros de 32 bits.
En el ABI n32, todos los registros son de 64 bits (por lo que requiere un procesador MIPS64). Pero las direcciones y los punteros son solo de 32 bits (cuando se almacenan en la memoria), lo que reduce la huella de la memoria. Cuando se carga un valor de 32 bits (como un puntero) en un registro, se amplía a partir de 64 bits. Cuando el procesador utiliza el puntero / dirección para una carga o almacenamiento, se utilizan todos los 64 bits (el procesador no es consciente de la n32-ess del SW). Si su sistema operativo admite programas n32 (quizás el sistema operativo también sigue el modelo n32 o puede ser un sistema operativo de 64 bits con soporte agregado de n32), puede ubicar toda la memoria utilizada por la aplicación n32 en la memoria adecuada (por ejemplo, los 2GB inferiores y los 2GB superiores, direcciones virtuales). El único problema con este modelo es que cuando los registros se guardan en la pila (llamadas a funciones, etc.), se usan todos los 64 bits, no hay un modelo de datos de 32 bits en el ABI n32.
Probablemente tal ABI podría implementarse también para x86-64.
Depende de la plataforma. En Mac OS X, los primeros 4 GB del espacio de direcciones de un proceso de 64 bits se reservan y no se asignan, probablemente como una función de seguridad, por lo que nunca se confunde un valor de 32 bits con un puntero. Si lo intentas, puede haber una manera de derrotar esto. Lo resolví una vez escribiendo una clase de "puntero" de C ++ que agrega 0x100000000 al valor almacenado. (Esto fue significativamente más rápido que la indexación en una matriz, lo que también requiere encontrar la dirección de la matriz y multiplicarse antes de la adición).
En el nivel ISA, ciertamente puede elegir cargar y extender a cero un valor de 32 bits y luego usarlo como un puntero de 64 bits. Es una buena característica para tener una plataforma.
No debe ser necesario realizar ningún cambio en un programa a menos que desee utilizar los punteros de 64 bits y de 32 bits simultáneamente. En ese caso, vuelve a los viejos tiempos de tener punteros near
y far
.
Además, ciertamente romperá la compatibilidad ABI con las API que llevan los punteros a los punteros.
En x86, no. En otros procesadores, como PowerPC, es bastante común: los registros de 64 bits y las instrucciones están disponibles en modo de 32 bits, mientras que con x86 tiende a ser "todo o nada".
La segunda parte de tu pregunta es fácil de responder. Es muy posible, de hecho, muchas implementaciones de C tienen soporte, para operaciones de 64 bits que utilizan código de 32 bits. El tipo C que se usa a menudo para esto es long long
(pero verifique con su compilador y arquitectura).
Que yo sepa, no es posible tener punteros de 32 bits en código nativo de 64 bits.
Linux ahora tiene un soporte bastante completo para X32 ABI, que hace exactamente lo que pide el que pregunta, de hecho, es parcialmente compatible como una configuración bajo el sistema operativo Gentoo. Creo que esta pregunta debe ser revisada a la luz del desarrollo del resentimiento.
Me temo que si le preocupa el tamaño de los punteros, es posible que tenga problemas mayores con los que lidiar. Si la cantidad de punteros será de millones o miles de millones, probablemente se encontrará con limitaciones dentro del sistema operativo Windows antes de que realmente se quede sin memoria física o virtual.
Mark Russinovich ha escrito un gran artículo relacionado con esto, titulado Pushing the Limits of Windows: Virtual Memory .
Técnicamente, es posible que un compilador lo haga. AFAIK, en la práctica no se hace. Se ha propuesto para gcc (incluso con un parche aquí: http://gcc.gnu.org/ml/gcc/2007-10/msg00156.html ) pero nunca se integró (al menos, no se documentó la última vez que comprobado). Según tengo entendido, también es necesario que el kernel y la biblioteca estándar funcionen (es decir, el kernel debería configurar las cosas de una manera que actualmente no es posible y no sería posible utilizar el ABI de 32 o 64 bits para comunicarse con el kernel). ).
Vale la pena señalar que hay un ABI en desarrollo para Linux, X32, que le permite crear un binario x86_64 que utiliza índices y direcciones de 32 bits.
Sólo relativamente nuevo, pero interesante, no obstante.
Una forma sencilla de evitar esto es si solo tendría unos pocos tipos para las estructuras a las que apunta. Entonces, simplemente puede asignar grandes matrices para sus datos y hacer la indexación con uint32_t
.
Por lo tanto, un "puntero" en dicho modelo sería solo un índice en una matriz global. Por lo general, tratar con eso debería ser lo suficientemente eficiente con un compilador decente, y le ahorraría algo de espacio. Perdería otras cosas que podrían interesarle, por ejemplo, la asignación dinámica.
Otra forma de lograr algo similar es codificar un puntero con la diferencia con respecto a su ubicación real. Si puede asegurarse de que esa diferencia siempre se ajuste a 32 bits, también podría ganar.