1.Common Visual C++ 64-bit Migration Issues

When you use Visual C++ to create applications to run on a 64-bit Windows operating system, you should be aware of the following issues:

当你用Visual c++创建运行在64位Windows上的程序时,你应该意识到下列问题:

  • An ​​int​​ and a ​​long​​ are 32-bit values on 64-bit Windows operating systems. For programs that you plan to compile for 64-bit platforms, you should be careful not to assign pointers to 32-bit variables. Pointers are 64-bit on 64-bit platforms, and you will truncate the pointer value if you assign it to a 32-bit variable.

​ 在64位系统上int型和long型占32位(IL32)。当你在64位平台上编译程序时,你需要注意不要把指针赋值给32位变量。在64位系统上,指针占64位(P64),当你将它赋值给32位变量时,会发生指针值截断(高位截断)。​​ 

  • ​size_t​​​, ​​time_t​​, and ​​ptrdiff_t​​ are 64-bit values on 64-bit Windows operating systems.

    size_t,time_t和ptrdiff_t在64位系统上占64位

  • ​time_t​​​ is a 32-bit value on 32-bit Windows operating systems in Visual C++ versions before Visual C++ 2005. ​​time_t​​ is now a 64-bit integer by default. For more information, see ​​Time Management​​.

 

   Visual c++ 2005之前的Visual c++版本,time_t占32位在32位系统上。现在time_t默认是64位整型。(为了处理32位时间漏洞?)

You should be aware of where your code takes an ​​int​​​ value and processes it as a ​​size_t​​​ or ​​time_t​​​value. It is possible that the number could grow to be larger than a 32-bit number and data will be truncated when it is passed back to the ​​int​​ storage.

你应该意识到,当你的代码中将int型变量赋值给size_t或者time_t型变量,那么数值可能会超过32位,当你再把size_t或者time_t变量赋值给int型,有可能会发生数据截断。

The %x (hex ​​int​​​ format) ​​printf​​ modifier will not work as expected on a 64-bit Windows operating system. It will only operate on the first 32 bits of the value that is passed to it.

printf中的%x占位符在64位系统上不会按所预期的来运行。它仅对传递给它的前32位值进行操作。

  • Use %I32x to display a 32-bit integral type in hex format.

    (在64位系统上)用%I32x显示32位整型类型的16进制格式

  • Use %I64x to display a 64-bit integral type in hex format.

    (在64位系统上)用%I64x显示64位整型类型的16进制格式

  • The %p (hex format for a pointer) will work as expected on a 64-bit Windows operating system.

    %p(显示指针16进制格式)在64位系统上运行的结果符合预期

 

2.x64 software conventions [节选]

Overview of x64 calling conventions

x64位调用约定概述

Two important differences between x86 and x64 are the 64-bit addressing capability and a flat set of 16 64-bit registers for general use. Given the expanded register set, x64 uses the ​​__fastcall​​​ calling convention and a RISC-based exception-handling model. The ​​__fastcall​​​ convention uses registers for the first four arguments and the stack frame to pass additional arguments. For details on the x64 calling convention, including register usage, stack parameters, return values, and stack unwinding, see ​​x64 calling convention​​.

x86和x64系统存在两个重要的不同:64位寻址能力和平坦的16个64位通用寄存器组。采用扩展寄存器组后,x64(架构)使用__fastcall调用约定以及基于RISC(精简指令集)的异常处理模型。__fastcall调用约定使用通用寄存器传递前4个参数,用堆栈传递其余的参数。

Register usage

寄存器的使用

The x64 architecture provides for 16 general-purpose registers (hereafter referred to as integer registers) as well as 16 XMM/YMM registers available for floating-point use. Volatile registers are scratch registers presumed by the caller to be destroyed across a call. Nonvolatile registers are required to retain their values across a function call and must be saved by the callee if used.

x64架构提供了16个通用寄存器(以下简称整数寄存器)和16个XMM/YMM浮点寄存器。易失型寄存器是指调用方假设在调用过程中寄存器值会发生变化的暂存型寄存器。非易失型寄存器是指调用过程中寄存器值由被调用方负责保存并恢复。

Register volatility and preservation

寄存器的易失性和保存方式

The following table describes how each register is used across function calls:

下表描述了各个寄存器在函数调用过程中的用途:

 

 

 

Register

Status

Use

RAX

Volatile

Return value register

RCX

Volatile

First integer argument

RDX

Volatile

Second integer argument

R8

Volatile

Third integer argument

R9

Volatile

Fourth integer argument

R10:R11

Volatile

Must be preserved as needed by caller; used in syscall/sysret instructions

R12:R15

Nonvolatile

Must be preserved by callee

RDI

Nonvolatile

Must be preserved by callee

RSI

Nonvolatile

Must be preserved by callee

RBX

Nonvolatile

Must be preserved by callee

RBP

Nonvolatile

May be used as a frame pointer; must be preserved by callee

RSP

Nonvolatile

Stack pointer

XMM0, YMM0

Volatile

First FP argument; first vector-type argument when ​​__vectorcall​​ is used

XMM1, YMM1

Volatile

Second FP argument; second vector-type argument when ​​__vectorcall​​ is used

XMM2, YMM2

Volatile

Third FP argument; third vector-type argument when ​​__vectorcall​​ is used

XMM3, YMM3

Volatile

Fourth FP argument; fourth vector-type argument when ​​__vectorcall​​ is used

XMM4, YMM4

Volatile

Must be preserved as needed by caller; fifth vector-type argument when ​​__vectorcall​​ is used

XMM5, YMM5

Volatile

Must be preserved as needed by caller; sixth vector-type argument when ​​__vectorcall​​ is used

XMM6:XMM15, YMM6:YMM15

Nonvolatile (XMM), Volatile (upper half of YMM)

Must be preserved by callee. YMM registers must be preserved as needed by caller.

On function exit and on function entry to C Runtime Library calls and Windows system calls, the direction flag in the CPU flags register is expected to be cleared.

当进入和退出C运行库函数和Windows系统调用,CPU标志寄存器(x86中的eflags寄存器)的方向位将被清除。

Image format

可执行映像文件的文件格式

The x64 executable image format is PE32+. Executable images (both DLLs and EXEs) are restricted to a maximum size of 2 gigabytes, so relative addressing with a 32-bit displacement can be used to address static image data. This data includes the import address table, string constants, static global data, and so on.

x64位可执行程序的文件格式是PE32+。可执行程序(DLLs和EXEs)大小被限制为2GB,所以,可以使用32位位移的相对寻址方式来处理静态数据,如:IAT表,字符串常量,静态全局数据(全局变量?)等等