Um zu verstehen wie viel Speicher ein Programm maximal verwenden kann muss man sich etwas mit dem internen Aufbau der Speicherarchitektur beschäftigen.
Die Grundlagen
Auf 32bit Systemen ist es erst mal so, dass die Adressen von Speicherzellen in einer 32bit großen Variable gespeichert werden. Mit diesem Address-Pointer können somit bis zu 4GB (232 Bytes) an Speicher angesprochen werden.
Windows möchte allerdings für interne Zwecke einen Teil von diesem Speicher für sich reservieren. Um es einfacher zu machen hat man einfach den Speicher in zwei Hälften geteilt. Die oberen 2GB hat Windows verwendet. Die Software selbst kann dann noch mit 31bit Adressen arbeiten.
Mit 64bit Systemen wurde der Platz für die Adresspointer verdoppelt. Nun kann Speicher mit 64bit adressiert werden und es stehen bis zu 18.446.744.073.709.551.616 Byte an Adressraum zur Verfügung.
Kompatibilität für alte Software
Auf einem 64bit Windows stehen aber nur für 64bit Programme diese Adressen zur Verfügung. Software mit 32bit Adressen sind immer noch auf 2GB beschränkt. Windows hat seinen eigenen Speicherbereich, die technisch möglichen 4GB stünden theoretisch zur Verfügung. Trotzdem sind die Programme beschränkt. Warum?
Das hat den Hintergrund, dass Windows nicht wissen kann wie die Software mit den Adressen umgeht. Hier mal ein fiktives Codebeispiel. Es werden Zeichen in einem Array abgelegt, mit zwei Pointern kann ein Bereich gekennzeichnet werden.
1 2 3 4 |
int length; char* startPtr, endPtr; length = endPtr - startPtr; |
In diesem Beispiel wird die Länge des Bereichs ermittelt indem man den kleineren Pointer vom größeren abzieht. Das Ergebnis wird in einem vorzeichenbehafteten 32bit int gespeichert. So lange die Differenz kleiner als 2G ist gibt das keine Probleme. Auf einem System das maximal 2GB an Speicher zulässt kann die Länge auch nie größer sein als 2GB.
Würde dieses Beispiel aber auf einem System laufen bei dem 4GB an Speicher zur Verfügung steht und die Länge wäre größer als 2GB, dann würde das Ergebnis hier durch das Vorzeichen negativ werden. Das weitere Verhalten des Programms mit der falschen länge ist unklar. Im besten Fall stürzt es gleich ab, im ungünstigsten Fall wird mit der falschen Zahl weitergearbeitet und es kommt zu Folgefehlern.
Um hier auf der sicheren Seite zu sein müsste für das Ergebnis der Subtraktion ein Typ verwendet werden der groß genug ist um das Ergebnis auch aufnehmen zu können.
Mehr Speicher für 32bit Programme
Wenn man als Softwareentwickler aber sicher ist, dass solche Situationen nicht vorkommen?
Für Programme, die mit Adressen größer als 2GB umgehen können kann man beim Linken das Flag „/LARGEADDRESSAWARE“ setzen. Dadurch ist später im Dateiheader ein spezielles Flag gesetzt der Windows mitteilt, dass auf einem 64bit System der Software 4GB Speicher statt den üblichen 2GB zur Verfügung stehen dürfen.
Nachträglich modifizieren
Ob das Flag gesetzt ist oder nicht lässt sich mit spezieller Software auslesen. Damit ist es auch möglich das Flag für beliebige Programme zu setzen. Aber Vorsicht: Die Modifikation könnte von einem Kopierschutz als Manipulation interpretiert werden. Und garantieren dass eine Software mit den großen Adressen umgehen kann wird nur der Entwickler können. Von außen sieht man das dem Programm nicht an.
CFF Explorer von NTCore
Das Freeware Tool CFF Explorer von NTcore erlaubt unter anderem die Manipulation von Flags in Dateiheader. Damit lässt sich einfach das oben beschriebene Flag unter NT Headers/File Header/Characteristics setzen.
Wer es noch einfacher will kann direkt das 4GB Patch Utility vom gleichen Hersteller verwenden.