[Baidu Space] [Go] porting the program to 64-bit Windows

Source: Internet
Author: User
Tags comparison table truncated

From:http://goooder.bokee.com/2000373.html ( Leili finishing)

Summary: This article provides a simple and systematic introduction to how to smooth the support and transition of 32-bit Windows programs to 64-bit Windows operating systems. Includes a version of the 64-bit operating system, a programming model, and some porting principles even include an introduction to the porting principles of the driver.

The author introduces: System analyst, now working in Beijing. The author's blog:http://goooder.blogchina.com.

Objective:

Perhaps everyone also on the 32-bit CPU and operating system use or feel very well in line with the daily needs, but the Windows 64 has quietly come to everyone's side. Many software vendors have also announced that their software has supported 64-bit operating systems.

The author succeeded in implementing a software 64-bit operating system porting a few months ago. The general scenario is that the upper-level applications still use 32-bit programs, but the drivers for the system software are all turned into 64-bit. This is also the minimum cost of allowing the application to support 64 bits. The whole process was less than one months (two people months), which solved most of the problems. And some of the hard-to-chew bones are caused by the code that was not so standardized. Because this is not the subject of this article, stop there.

The following is the result of my work in the process of sorting out all kinds of information obtained. For the sake of the system of the article, some content of MSDN Chinese website was posted. Hope to be helpful to everyone's work.

A Most likely to benefit from 64-bit applications

L need a lot of addressable memory, so the system overall memory needs more than 4GB application. Examples of applications that use large datasets (financial and scientific modeling software) and host-based desktop applications (running multiple threads simultaneously without compromising performance);

L must simultaneously manage a large number of users or application threads, such as large-scale thin client solutions, large databases, and data warehousing applications for solutions in Customer Relationship Management (CRM), Supply chain Management (SCM), Enterprise Resource Planning (ERP), and Digital Rights Management (DRM) systems;

L need real-time encryption and decryption to improve security applications, including e-commerce applications and protection of proprietary or categorical data;

• Applications requiring mathematical precision and floating-point performance, including modelling, simulation, statistical and financial Analysis, image/video/signal processing, physics, medical research, remote communication, encryption and compression;

L need large-scale, robust database performance applications, including decision support, search and indexing, document and content management, and speech recognition;

• Applications requiring large memory addressing for 64-bit computing, including many high-performance computing (HPC) cluster applications;

L need to provide digital content creation capabilities such as computer-aided design, manufacturing and engineering (CAD, CAM and CAE), digital music production and video editing, and real-time media streaming solutions;

L need to achieve a realistic cinematic consumer experience with maximum performance, including computer games, digital video and collaboration;

l need to migrate functionality previously limited to 64-bit workstations to desktops for enterprise, consumer, and computer enthusiasts, including 3D modeling, rendering, animation, simulation, and software development.

Two 64-bit version of Windows XP classification

Microsoft released its 64-bit Windows XP on March 28, 2003. 64-bit Windows XP is called Windows XP 64-bit Edition. is actually the 64-bit version of Windows XP Professional. It is divided into two different versions depending on the microprocessor architecture:

Version 1.ia-64 of Windows XP

For Intel (Intel) IA-64 Architecture, the Itanium 2 (ITANIUM2) pure 64-bit microprocessor for Windows XP 64-bit Edition Version 2003 for itanium-based Systems. It is a powerful operating system with 64-bit addressing capabilities, primarily for high-end IA-64 architecture workstations, used in high-end scientific operations, oil exploration processes, stereoscopic mapping, complex animation, and more, and is a highly efficient operation (high performance Computing) Of the powerful operating system. It is estimated that it may be renamed to Windows XP Professional itanium-based Edition. Support dual processor, minimum 1GB memory support, up to 16GB of memory.

Version 2.x64 of Windows XP

x64 architecture for ultra-Micro (AMD) (Opteron) and Fast Dragon (Athlon64) belongs to the 64-bit extended microprocessor Windows XP 64-bit Edition for 64-bit Extended Systems. Because Intel also released the x64 architecture of Intel EM64T Technology Xeon (Xeon) and the Pentium 4 (Pentium 4) 64-bit extension microprocessor, Microsoft changed the version of Windows XP 64-bit Edition to Windows XP Professional x64 Edition, which supports AMD and Intel's x64 architecture. Workstations, desktops, and laptops in a general x64 architecture can be used in the same way as 32-bit Windows XP Professional, but with 64-bit addressing capabilities. Support dual processor, minimum 256MB memory support, up to 16GB of memory.

Windows XP Professional x64 Edition is similar to the 32-bit version

Three Design goals for the x64 version of the Windows operating system

The x64 version has 5 major features, namely:

1. At the same time easily support 32-bit WIN32 program and 64-bit programs;

2. In the 64-bit running program code and 32-bit running program should be the same code;

3. Enable existing programs to have enterprise application performance; (Enable existing applications to level to enterprise capacities)

4. Support the new design so that it can take advantage of the large address space and memory space;

5. Support 32-bit existing programs.

The x64 bit platform does not appear Win64 API, it is still familiar with the Win32 API (now the more appropriate name for the Windows API). However, it has some new compatible 64-bit data types, so you may need to make small changes to your code. This means that developers can build 32-bit and 64-bit versions of code from a single codebase, reducing the maintenance overhead associated with maintaining two code repositories.

However, in x64, Microsoft has removed some of the older components, such as the Win16 subsystem. Therefore, Windows 64-bit code does not support 16-bit Windows programs. POSIX and OS/2 subsystems are also not supported. A new subsystem, called WOW64, has emerged.

Four x64 Emerging Subsystem ―wow64

WOW64 is the abbreviation of windows-32-on-windows-64. It provides a 32-bit simulation environment for existing 32-bit applications, allowing most 32-bit applications to run directly on the Windows 64-bit version without modification. It is similar to the old WOW32 subsystem, which is responsible for running 16-bit code under the Windows 32-bit version.

Although the x64 CPU itself has a 32-bit compatibility mode that can handle the actual execution of the IA-32 instruction, the WOW layer is still essential. The WOW subsystem is responsible for services such as process switching between 32-bit and 64-bit modes and simulating 32-bit systems. For example, 32-bit and 64-bit programs have different registry hives, a different system directory for 32-bit binaries, and a 64-bit binary file still uses the System32 directory. Therefore, when a 32-bit application is installed into the system, the WOW layer ensures that the 32-bit binaries are placed in a new directory SysWOW64. This is done by intercepting calls to the API (such as GetSystemDirectory) and returning the appropriate directory, depending on whether the application is running under WOW. A similar problem may exist in the registry. Because both 32-bit and 64-bit COM servers can be installed on the system and are located under the same class identifier (CLSID), the WOW layer needs to redirect calls to the registry to the appropriate 32-bit or 64-bit hive. The WOW layer also handles mirroring changes between some areas of the registry so that it can more easily support interaction between 32-bit and 64-bit code.

WOW64 is important because it enables developers to take advantage of most existing 32-bit code when it comes to performance and scalability concerns. It is the best combination of the two methods. Developers can migrate application services to 64-bit, while leaving the Microsoft Management Console (MMC) configuration snap-in as 32-bit. The Windows 64-bit version includes the 32-bit and 64-bit versions of MMC. When the retention management tool is selected to be 32-bit, interprocess communication may encounter some problems, but as long as the interface is properly designed, protocols such as Remote Procedure call (RPC) should be able to run between 32-bit and 64-bit processes. Another point to keep in mind about WOW64: It's not designed for applications that require high performance. At a minimum, the WOW64 subsystem needs to extend the 32-bit parameter to 64 bits, and the 64-bit return value needs to be truncated to 32 bits. In the worst case, the WOW64 subsystem will need to make kernel calls, involving more than just the conversion to the kernel, but also the conversion from the processor's 32-bit compatibility mode to its native 64-bit mode. When running under WOW64, the application will not be able to adjust properly. For applications that want to retain them as 32-bit, they must be tested under WOW64. If performance does not meet expectations, you need to consider migrating your application to 64-bit.

WOW64 is implemented in user mode as a layer between the ntdll.dll and the kernel. WOW64 and some of its supported DLLs are just 64-bit DLLs that can be loaded into 32-bit processes. For all other cases, the process remains a pure process. A 32-bit process could not load a 64-bit DLL and vice versa. Therefore, check that all the "LoadLibrary" calls in the code are valid.

For more information about WOW64, see "64-bit Windows programming-running 32-bit Applications" in the Microsoft_ Platform SDK.

Five 64-bit Windows memory address space mapping

By default, the address space of the Windows 32-bit version is limited to 4GB, half of which is reserved for the kernel. This limits the normal application to use only 2GB of valid virtual memory. 2 GB looks like a lot, but because of the wrong allocation algorithms, large file mappings, and even excessive use of DLLs, the address space can easily become fragmented in the application. If you look at the VM Size column in Task Manager, you will see the amount of virtual memory consumed by your normal application. Of course, just like the past DOS period (using Xms/ems), there are many ways to enable 32-bit applications to access more than 4 GB of physical memory. Enter the physical Address Extension (PAE) and Address window extensions (Addresses windowing Extensions,awe). PAE works by extending the number of address bits from 32 to 36来, so that the application can address a space of up to five gigabytes. AWE enables applications to map a range of physical memory greater than 4 GB into the virtual address space. Both of these methods introduce overhead and add complexity to the code.

The Windows 64-bit version provides effective addressing space of up to TB, half of which can be used in user-mode applications. This means that the entire database can be moved into memory, significantly improving performance, or the entire Web site can be cached in memory. It also allows the code to be retained and delegated to a huge block of contiguous virtual memory without actually worrying about virtual memory fragmentation issues. This also takes into account the massive file mapping object or the shared memory portion.

The following is a comparison table of 64-bit architectures and 32-bit architectures:

The following is a comparison of Windows series memory address space allocations:

...

Six Windows 64-bit version of C + + programming
1. 64-bit Coding guidelines

The Windows 64-bit version uses the LLP64 data model. This means that standard C type int and long remain as 32-bit integers. The data type size_t is mapped to the processor word size (IA32 is 32 bits, IA64 is 64 bits), and __int64 is a 64-bit integer. This is done when you assist in migrating 32-bit code. The point is that you can use the same codebase for both the 32-bit version and the 64 version of the application.

There is also a data model called LP64, which maps a standard C-type long to a 64-bit integer and keeps int as a 32-bit integer. This data model is common to Unix platforms, but there may be some difficulties in creating both the 32-bit and 64-bit versions of the application from a single codebase. You may have noticed the common topics here. The idea of 32-bit platforms and 64-bit platforms is that you should be able to build two versions of applications from a single codebase. If that's not possible, you might want to revisit your design. Having a single codebase is a huge win, especially if you plan to release two versions.

In combination with the above considerations, the recommendations are as follows:

Use WINDOWS64 bit or 32-bit secure data type;

Check all pointer operations and where pointers are used;

Overwrite all embedded assembly code; Use intrinsics or native assembly code;

Precompiled command with #if defined (_amd64__) for X64 related code (no __ia64__ macros defined);

Use the # if defined (__ia64__) command for IA64 related code;

Compile the x64 program using the AMD64 processor;

When you create an application that runs in a 64-bit Windows operating system with Visual C + +, you should be aware of the following issues:

In 64-bit Windows operating systems, int and long are 32-bit values.

In 64-bit Windows operating systems, size_t, time_t, and ptrdiff_t are 64-bit values.

In a 32-bit Windows operating system, time_t is a 32-bit value.

Be aware of where the code takes an int value and handles it as a size_t value or time_t value. The number may grow larger than the 32-digit number, and the data may be truncated when it is passed back to the int store.

%x (hexadecimal int format) The printf modifier does not work as expected in a 64-bit Windows operating system; it only operates on the first 32 bits of the value passed to it.

Windows 32-bit operating systems use%i32x to display integers.

Windows 64-bit operating systems use%i64x to display integers.

%p (the hexadecimal format of the pointer) works as expected in a 64-bit Windows operating system.

2. /WP64: Causes the compiler to warn you of potential problems

The Microsoft_ Visual C and Microsoft_ Visual C++_. NET 2002 Compiler added the/WP64 switch, which allows you to test 64-bit compatibility issues with 32-bit code. The compiler issues warnings about pointer truncation and incorrect conversions. One of the previous steps in migrating a 32-bit application to a Windows 64-bit version is to open the tag and compile your code as you would normally compile your code. There will be a few errors for the first time. For example, take a look at the following code snippet:

DWORD i = 0;

size_t x = 100;

i = x; C4267:warning C4267: ' = ': conversion from

' size_t ' to ' DWORD ', possible loss of data.

On a 32-bit platform, this code compiles well because size_t is 32-bit, but on a 64-bit platform, size_t is a 64-bit integer. When/WP64 is enabled, the compiler warns you of a similar situation.

Other examples:

void func (DWORD context)

{

char* sz = (char*) context; C4312:warning C4312:

' Type cast ': Conversion

From ' DWORD ' to ' char * ' of

Greater size

Do-something with Sz.

}

char* string = "The quick brown fox jumped over the lazy dog.";

Func ((DWORD) string); C4311:warning C4311: ' Type cast ':

Pointer truncation from ' char * '

To ' DWORD '

After you fix these errors, test your 32-bit code. You want to make sure that the 32-bit code continues to work as expected. 32-bit and 64-bit binaries should be built from the same code base. This is the key concept of writing a constantly advancing Windows application. At the outset, you need to consider 32-bit and 64-bit issues and write code for your application that can run on these two platforms.

3. Polymorphic types

Since the Win32 API is for C, in many cases you need to convert integers to pointers or vice versa. There is no problem with 32-bit hardware, where the size of the pointer is the same as the integer size, but it is completely different on 64-bit hardware. This is why polymorphic types occur.

For specific precision, you can use a fixed-precision data type. Regardless of the processor's word size, they are the same size. Most of these types include precision in their names, as can be seen in the following table:

Also, use the pointer precision data type when you want the precision of the data type to vary with the size of the processor word. These types are also known as polymorphic data types. These types usually end with a _ptr suffix, as shown in the following table:

All Win32 APIs that pass parameters or contextual information through integer parameters are changed to use these new types. The SetWindowLong and SETWINDOWLONGPTR functions are good examples:

Old method:

LONG SetWindowLong (

HWND hwnd,

int NIndex,

LONG Dwnewlong);

New Polymorphic Method:

Long_ptr Setwindowlongptr (

HWND hwnd,

int NIndex,

Long_ptr Dwnewlong);

Note that the XXXPTR version of the function uses the new polymorphic type. It is quite common for developers to store the window's contextual information by storing pointers in additional data regions of the window. Any code that uses the SetWindowLong function to store pointers on a Windows 32-bit version must be changed to call Setwindowlongptr. This change is very simple and can be done very quickly, as most changes require the use of polymorphic types.

In addition, WindowProc and GetQueuedCompletionStatus are also good examples:

LRESULT CALLBACK WindowProc (

HWND hwnd,

UINT Uimsg,

WPARAM WPARAM,

LPARAM LPARAM);

BOOL GetQueuedCompletionStatus (

HANDLE Hcompletionport,

Lpdword Lpnumberofbytes,

Pulong_ptr lpCompletionKey,

lpoverlapped* lpoverlapped,

DWORD dwmilliseconds);

WindowProc uses LPARAM, which is a polymorphic type. GetQueuedCompletionStatus uses ULONG_PTR, which is also polymorphic type. This allows existing code that assumes that the size of an integer is the same as the pointer size and can continue to work with little modification.

The compiler for Microsoft_ Visual Studio_. NET 2002 contains two new optimization modes: Link time Code Generation (LTCG, also known as Whole Program Optimization) and profile Guided optimization (PoGO). Code optimization is more important on Itanium processors than on x86 platforms, because compilers are fully responsible for producing efficient code. For compiler knowledge, please refer to the MSDN Chinese website http://www.microsoft.com/china/MSDN/library/windev/Windows2003/ Nfdnnetservws0364bitdev.mspx to get more information on this.

Seven Porting drivers to a 64-bit Windows operating system

The biggest difference between x64-bit operating systems and x32-bit operating systems is the different memory addressing methods. The 64-bit operating system does not support 32-bit drivers because the driver and the Windows kernel are in one address space. This is the biggest reason for porting 32-bit drivers to 64-bit drivers. Of course, 64-bit drivers can use larger paging memory, nonpaged memory, and system caching. Also, your device supports a 64-bit Windows operating system from this point on.

1. Driver installation under X64

In addition to turning the application's 32-bit driver into a 64-bit program, the driver installer and other configuration files also need to be modified. That is, for a 32-bit program to run on x64, the driver it relies on still needs to be 64-bit. These related procedures include INF files, device installers, class installers, and Co-Installers. Related information can be viewed in MSDN libarary ddk:porting Your Driver to 64-bit Windows.

So, to retrofit the installer for the application. By installing the 32-bit version of the driver as the default installation option, the 32-bit installer is still running after the user inserts the installation disc. However, when the program calls updatedriverforplugandplaydevices the return value is error_in_wow64, this means that the installer is running in a 64-bit Windows environment. At this point, this installer should call the CreateProcess function to start the 64-bit installation process. This 64-bit installation process drives the installation by invoking the INF file in the 64-bit driver directory.

2. Driver to support 32-bit IOCTL

Some ioctl may contain a structure that contains pointers, so it is important to be very careful to treat it differently, depending on the callee parsing the structure or the output structure.

There are three ways to solve this problem:

1. Try to avoid using the IOCTL to pass structures containing pointers;

2. Use API Iois32bitprocess () to determine the program type of the upper-level caller;

3. The new IOCTL command is used in 64-bit programs;

Example:

IOCTL structure in header file

typedef struct _IOCTL_PARAMETERS {

PVOID Addr;

size_t Length;

HANDLE HANDLE;

} ioctl_parameters, *pioctl_parameters;

32-BIT IOCTL Structure

//

This structure is defined

Inside the driver source code

//

typedef struct _IOCTL_PARAMETERS_32 {

Void*pointer_32 Addr;

INT32 Length;

Void*pointer_32 Handle;

} ioctl_parameters_32, *pioctl_parameters_32;

32-bit and 64-bit IOCTL

#ifdef _win64

Case Ioctl_register:

if (iois32bitprocess (IRP)) {
/* If This is a +-bit process */
Params32 = (pioctl_parameters_32) (Irp>associatedirp.systembuffer);

if (Irpsp->parameters.deviceiocontrol.inputbufferlength < sizeof (ioctl_parameters_32)) {

status = Status_invalid_parameter;

} else {
LOCALPARAM.ADDR = params32->addr;
Localparam.handle = params32->handle;
Localparam.length = params32->length;

/* Handle the IOCTL here * *

status = Status_success;
irp->iostatus.information = sizeof (ioctl_parameters);
}
} else {/* 64bit process IOCTL */

} else {/* 64bit process IOCTL */

params = (pioctl_parameters)
(Irp->associatedirp.systembuffer);

if (irpsp->parameters.deviceiocontrol.inputbufferlength
< sizeof (ioctl_parameters)) {
status = Status_invalid_parameter;

} else {
Rtlcopymemory (&localparam, params,
sizeof (ioctl_parameters));

/* Handle the IOCTL here * *
status = Status_success;
}
irp->iostatus.information = sizeof (ioctl_parameters);
}
Break

3. 64-bit INF File Requirements

After Windows Server 2003SP1, the installation of a 64-bit driver was raised. This simplifies the user's operation and improves security.

INF file must contain modifiers such as NTAMD64 or NTIA64. The practice is to add fields of this class in both [Manufacturer] and models sections.

[Manufacturer]

%mycompany% = Mycompanymodels

[Mycompanymodels]

%mydev% = Mydevinstall,mydevhwid

[Manufacturer]

%mycompany% = Mycompanymodels,ntx86,ntamd64

[Mycompanymodels.ntx86]

%mydev% = Mydevinstallx86,mydevhwid

[Mycompanymodels. NTAMD64]

%mydev% = Mydevinstallamd64,mydevhwid

If you only need to install on the WindowsX64 system, you only need to use the NTAMD64 modifier. Please refer to http://www.microsoft.com/whdc/driver/install/64INF_reqs.mspx for more information.

4. Problems that are easily encountered in programming

1) Questions related to pointers

If the programming style of the original project is not tightly controlled, the pointer type is mixed, the use of coercion is too much and so on may be a great test for porting. In addition, there are structures in the program to calculate the location of other variables based on the specific data type the code of this class also needs to be re-examined.

The principle of using pointers is as follows:

1. Do not cast the pointer to the type int, long, ULONG, DWORD, and so on, and should use Uint_ptr and int_ptr;

2. Use Ptrtoulong () and Ptrtolong () to truncate the pointer;

3. Never re-synthesize a new pointer address that has been truncated in an int or ulong pointer address;

4. Carefully calculate the size of the buffer, perhaps the length of the buffer is larger than the maximum number that ULONG can store!

5. Be careful to invoke functions that have outgoing pointers;

For 4, for example: There are two addresses ptr2 (high address), PTR1 (low address), then Len = Ptr2–ptr1 will likely be greater than 2 32.

2) Structure of memory arrangement problem

On a 64-bit operating system, the structure's memory arrangement (structure alignment) also needs careful review. The neat memory arrangement facilitates the processor's execution efficiency. If some compile options are turned on, the compiler may fill in the blanks in order to align memory addresses. During the migration process, the order of variables in the structure needs to be examined carefully, especially with different pack options in the same header file. For example, the following code:

#pragma pack (1)/* You can also use the compile option/zp (struct member Alignment) */

struct Alignsample {

ULONG size;

void *ptr;

};

struct Alignsample s;

void foo (void *p) {

*p = p; will result in an access exception

...

}

Foo ((PVOID) &s.ptr);

The remedy is to use the macro unaligned:

void foo (void *p) {

struct Alignsample s;

* (UNALIGNED void *) &s.ptr = p;

}

Of course, the better way is to first put those 64-bit-length data type variables in the front of the structure.

3) Be careful to use hexadecimal constants, unsigned integers

Be careful with hexadecimal constants, unsigned integers, and so on. For example, some of the following assertions are wrong on a 64-bit system:

~ ((UINT64) (page_size-1)) = = (UINT64) ~ (page_size-1)

Page_size = 0x1000ul//Unsigned Long-32 bits

Page_size-1 = 0x00000fff

Left of equation:

unsigned conversions

(UINT64) (page_size-1) = 0x0000000000000fff

~ ((UINT64) (page_size-1)) = 0xfffffffffffff000

Right of the equation:

~ (page_size-1) = 0xfffff000
(UINT64) (~ (page_size-1)) =0x00000000fffff000

So:

~ ((UINT64) (page_size-1))! = (UINT64) (~ (page_size-1))

And also:

DWORD index = 0;

CHAR *p;

If (p[index–1] = = ' 0 ')

The above code will make an error on the 64-bit system! Because on a 32-bit system

P[index-1] = = p[0xffffffff] = = P[-1]

This is the right one. On a 64-bit system, however:

P[index-1] = = p[0x00000000ffffffff]! = p[-1]

Again such as:

-1! = 0xFFFFFFFF

0xFFFFFFFF! = Invalid Handle

The DWORD is always 32 bits, so look for all the code in the original program that uses the DWORD memory pointer. Also, do not forget to use%i to print the pointer address, and more than 0x80000000 is not necessarily the kernel State address.

5. Development of 64-bit driver tools

64-bit development tools and 32-bit almost, in addition to the necessary Windows DDK 2003, Windbg,driver verifier, etc. are good tools. Finally, it is recommended to download a new WHQL test kit for WHQL testing.

Currently, it is particularly necessary to learn how to use WinDbg to debug 64-bit user-state and kernel-mentality programs. You can also purchase a 64-bit VC environment with visual Stdio 2005来 for 64-bit program development.

[Baidu Space] [Go] porting the program to 64-bit Windows

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.