What it takes to write 64-bit apps
Matt Pietrek has written a nice new article on MSDN about everything that you need to know to get started writing applications for 64-bit versions of Windows - otherwise known as x64. It is available here:
http://msdn.microsoft.com/msdnmag/issues/06/05/x64/default.aspx
For your quick reference (and mine :) I've jotted down the important points here if you haven't got the time or inclination to read the article. Here goes.
- Moving from 32-bit to 64-bit is not just a re-compile away.
- You get to address really really large chunks of memory (on the order of terabytes and even larger). Each process gets its own 8TB chunk of memory from the OS.
- All system DLLs are loaded above 4GB typically at addresses around 0x7FF00000000.
- The x64 linker assigns the default load address for 64-bit applications to just above 32 bits. This is being done so that you can quickly discover porting bugs. If you are for instance using a 32-bit pointer where you should have used a 64-bit pointer, because the base address is greater than what can be accommodated in 32 bits the pointer will effectively get truncated resulting in an access violation.
- Most Win32 datatypes continue to retain the size from the 32-bit world. INTs, LONGs, WORDs and DWORDs continue to be 32-bits wide. HANDLEs have become 64-bits wide though.
- x64 versions of Windows include a sub-system called WOW64 that allows 32-bit applications to just work on x64.
- A 64-bit application cannot load 32-bit DLLs and vice versa. However 64 and 32-bit applications can still talk to each other using inter-process communication mechanisms (shared memory, named pipes, synchronization objects).
- x64 is officially off limits for 16-bit applications.
- Two copies of system DLLs are maintained - one for 64-bit applications and one for 32-bit applications. WOW64 silently re-directs file I/O on the system folder for 32-bit applications to
\Windows\SysWow64
. If you want to figure out the path to the 32-bit system folder from a 64-bit app then you can do that by callingGetSystemWow64Directory
. - Just like the file system, WOW64 silently re-directs access to the registry also for 32-bit applications. This is to prevent each type of application from stepping on each other's toes, as can happen when a 64-bit app
CoCreateInstance
s a 32-bit COM component! So, a 32-bit application would see a differentHKEY_CLASSES_ROOT
(and a few other keys) as opposed to a 64-bit app. - x64 now includes a feature called PatchGuard which basically BSODs your system if any kernel mode code alters important kernel mode data structures such as the Interrupt Dispatch Table (IDT). Hmm. Now there's a challenge for rootkit writers and tools such as Regmon that rely on being able to mess around with the IDT.
- CPU registers are now 64-bits wide (obviously) and are called
RAX
,RBX
,RCX
,RDX
,RSI
and so forth. 8 new general purpose registers have been added and are calledR8
,R9
,R10
and so on tillR15
. - No more
__cdecl
,__stdcall
,__fastcall
or__thiscall
! There is only a single calling convention in x64 which passes the first 4 parameters to a function viaRCX
,RDX
,R8
andR9
and the remaining parameters via the stack.
A few quick points on writing code that works on 32-bit and 64-bit computers:
- Pointers cannot be stored in 32-bit types such as
int
s,long
s orDWORD
s. - Use
DWORD_PTR
s,INT_PTR
s andLONG_PTR
s when you want to store pointer values. These types automatically become 64-bits wide on x64 systems (after a recompile that is). - When you use functions like
printf
andsprintf
do not use%X
to print pointer values. Use%p
and you're automagically protected. - Inline assembly is not supported in the 64-bit C++ compiler. Boo! hoo!
comments powered by Disqus