64-bit platform easy-to-make error

Source: Internet
Author: User

Introduction to 64-bit platforms

  1. IA-64 is a 64-bit microprocessor architecture developed by Intel and Hewlett Packard companies together. It's implemented in Itanium and Itanium 2 microprocessors. To learn more on the architecture IA-64 see the following Wikipedia article "Itanium".
  2. Intel (em64t/amd64/x86-64/x64) is a extension of x86 architecture with full backward compatibility. There is many variants of its name, and it causes some confusion, but all these names mean the same thing:x86-64, AA-64, Hammer Architecture, AMD64, Yamhill Technology, EM64T, ia-32e, Intel, x64. To learn about many names appeared see the article in Wikipedia: "x86-64".

Advantages of 64-bit platforms

    • 64-bit address space;
    • an extended register set;
    • A command set familiar to developers;
    • Capability to launch obsolete 32-bit applications in a 64-bit operating system;
    • capability to use 32-bit operating systems.

Win64 Program Model

The Win32, the size of a page in Win64 is 4 Kbytes. The first kbytes of the address space is never displayed, so the lowest correct address is 0x10000. Unlike Win32, System DLL ' take more than 4 gbytes.

Compilers for Intel, one peculiarity:they can use registers with great efficiency to pass parameters into function s, instead of the using the stack. This allowed the Win64 architecture developers to get rid of notions such as a calling convention. In Win32, various conventions: __stdcall, __cdecl, __fastcall, etc. In Win64, there are only one calling convention. Here's an example of about four arguments of the integer type are passed through registers:

    • Rcx:the first argument
    • Rdx:the second argument
    • R8:the third argument
    • R9:the Fourth argument

The arguments following the first four integers is passed through the stack. To pass float arguments xmm0-xmm3 registers is used as well as the stack.

The difference in the calling conventions makes it impossible to use both 64-bit and 32-bit code in one program. In other words, if an application have been compiled for the 64-bit mode, all the libraries (DLLs) being used must also be 6 4-bit.

Passing parameters through registers is one of the innovations, make 64-bit programs faster than 32-bit ones.

Performance of 64-bit Platform applications

After being recompiled for a 64-bit system a program can use huge amounts of memory and its speed would increase in 5-15%. 5-10% of speed gain was achieved due to architectural features of the 64-bit processor, for example, a larger number of Reg Isters. And another 1-5% performance gain is determined by the absence of the WoW64 layer that translates calls between 32-bit app Lications and the 64-bit operating system.

For example, Adobe company says, a new 64-bit "Photoshop CS4" are 12% faster than its 32-bit version ".

Easy mistakes on 64-bit platforms

    1. The return value of sizeof () occupies 8bytes under 64-bit platform, not 4bytes under 32-bit platform;
    2. size_t type, pointer type and so on 64-bit platform occupies 8bytes, rather than 32-bit platform under 4bytes;
    3. The printf function, "%d" "%u" "%x" mode can only print out the number of 32bit type, if you want to print out the number of 64bit, you need to add "I" (Windows platform) or "Z" (Linux platform), such as "%id" "%iu" "%ix", "%zd" " %zu ""%ZX ";
    4. Integer constants, such as 1, in the 64-bit platform under the type of int, so occupy 4bytes, then in the shift operation, you need to pay attention to this point;
    5. When a shift is performed, the shifted variable is first cast to signed and then shifted, such as the following code:
structbitfieldstruct {unsigned ShortA: the; unsigned ShortB: -;}; Bitfieldstruct obj;obj.a=0x4000; size_t addr= Obj.a << -;//Sign Extensionprintf"addr 0x%ix\n", addr);//Output on 32-bit system:0x80000000//Output on 64-bit system:0xffffffff80000000//OBJ.A is converted into signed int before shift.
  1. Address addition, it is easy to make mistakes, such as the following code
    intA =-2; unsigned B=1;intarray[5] = {1,2,3,4,5 };int*ptr = array +3;p TR= ptr + (A + B);//Invalid pointer value on 64-bit platformprintf"%i\n", *ptr);//Access violation on 64-bit platform

    The reasons are as follows:

Let us follow the algorithm of calculating the expression "PTR + (A + B)":

    • According to C + + rules, the variable A of the type int is converted to unsigned.
    • A and B are summed and we get the value 0xFFFFFFFF of unsigned type.
    • The expression "PTR + 0xFFFFFFFFu" is calculated.

The result of this process depends upon the size of the pointer on a particular architecture. If The addition takes place in the 32-bit program, the expression was equivalent to "Ptr-1" and the program successfully Prints the value "3". The 64-bit program, the value 0xFFFFFFFFu are fairly added to the pointer. As a result, the pointer gets far outside the array while we encounter some troubles when trying to get access to the item By this pointer.

Like in the first case, we recommend your use of memsize-types in pointer arithmetic to avoid the situation described Above. Here is one ways to correct the code:

ptr = ptr + (ptrdiff_t (a) +=-21= ptr + (A + B);

Casting of pointer types can also cause errors

intarray[4] = {1,2,3,4 };enumenumbers {ZERO, one, I, three, four};//Safe cast (for MSVC)Enumbers *enumptr = (Enumbers *) (array); cout<< enumptr[1] <<" ";//unsafe castsize_t *sizetptr = (size_t *) (array); cout<< sizetptr[1] <<Endl;//Output on 32-bit system:2 2//Output on 64-bit system:2 17179869187=0x0000000400000003

Reason: In the 64-bit system, size_t accounted for 8bytes, so sizetptr[1] points to the memory of 4btyes of the number 3 and 4 splicing up memory block, that is 0x0000000400000003

Storage of integer values in double

size_t a = size_t (-1); double B = A; --A; ---//  x86:a              = = C//  x64:a! = C

Reason:

This code was justified when it was executed on a 32-bit system because the type double had a significant bits and can store a 32-bit integer value without loss. If you save a 64-bit an integer number into double, the exact result would be lost.

Number of bytes of memory occupied by the struct

struct mystruct{  bool  m_bool;   Char *m_pointer;   int M_int;}; // x86:sizeof (mystruct) = // x64:sizeof (mystruct) =
struct mystruct{   Char *m_pointer;   int m_int;   BOOL M_bool;}; // x86:sizeof (mystruct) = // x64:sizeof (mystruct) =

" byte Alignment Tips": The process of optimizing a field arrangement may seem complicated. But there was a very simple and very effective method:you just need to arrange the fields in decreasing order of their siz Es.

[References]:

    1. 64-bit Platform C + + development considerations
    2. Lessons on the development of 64-bit/C + + Applications

Easy-to-make errors with 64-bit platforms

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.