News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Microsoft 64 bit ABI specs.

Started by hutch--, April 24, 2017, 04:15:01 PM

Previous topic - Next topic

hutch--

This is taken from the Microsoft site and has been slightly modified to make it more readable in plain text format. The attached text file contains the same data.


x64 Architecture

The x64 architecture is a backwards-compatible extension of x86. It provides a legacy 32-bit mode, which is identical to x86, and a new 64-bit mode. The term "x64" includes both AMD 64 and Intel64. The instruction sets are close to identical.

Registers
x64 extends x86's 8 general-purpose registers to be 64-bit, and adds 8 new 64-bit registers. The 64-bit registers have names beginning with "r", so for example the 64-bit extension of eax is called rax. The new registers are named r8 through r15. The lower 32 bits, 16 bits, and 8 bits of each register are directly addressable in operands. This includes registers, like esi, whose lower 8 bits were not previously addressable. The following table specifies the assembly-language names for the lower portions of 64-bit registers.

64-bit register    Lower 32 bits    Lower 16 bits    Lower 8 bits
    rax             eax                 ax              al
    rbx             ebx                 bx              bl
    rcx             ecx                 cx              cl
    rdx             edx                 dx              dl
    rsi             esi                 si              sil
    rdi             edi                 di              dil
    rbp             ebp                 bp              bpl
    rsp             esp                 sp              spl
    r8              r8d                 r8w             r8b
    r9              r9d                 r9w             r9b
    r10             r10d                r10w            r10b
    r11             r11d                r11w            r11b
    r12             r12d                r12w            r12b
    r13             r13d                r13w            r13b
    r14             r14d                r14w            r14b
    r15             r15d                r15w            r15b

Operations that output to a 32-bit subregister are automatically zero-extended to the entire 64-bit register. Operations that output to 8-bit or 16-bit subregisters are not zero-extended (this is compatible x86 behavior). The high 8 bits of ax, bx, cx, and dx are still addressable as ah, bh, ch, dh, but cannot be used with all types of operands. The instruction pointer, eip, and flags register have been extended to 64 bits (rip and rflags, respectively) as well.

The x64 processor also provides several sets of floating-point registers:
Eight 80-bit x87 registers.
Eight 64-bit MMX registers. (These overlap with the x87 registers.)
The original set of eight 128-bit SSE registers is increased to sixteen.

Calling Conventions
Unlike the x86, the C/C++ compiler only supports one calling convention on x64. This calling convention takes advantage of the increased number of registers available on x64:
The first four integer or pointer parameters are passed in the rcx, rdx, r8, and r9 registers.
The first four floating-point parameters are passed in the first four SSE registers, xmm0-xmm3.
The caller reserves space on the stack for arguments passed in registers. The called function can use this space to spill the contents of registers to the stack.
Any additional arguments are passed on the stack.

An integer or pointer return value is returned in the rax register, while a floating-point return value is returned in xmm0.
rax, rcx, rdx, r8-r11 are volatile.
rbx, rbp, rdi, rsi, r12-r15 are nonvolatile.

The calling convention for C++ is very similar: the this pointer is passed as an implicit first parameter. The next three parameters are passed in registers, while the rest are passed on the stack.

Addressing Modes
The addressing modes in 64-bit mode are similar to, but not identical to, x86.
Instructions that refer to 64-bit registers are automatically performed with 64-bit precision. (For example mov rax, [rbx] moves 8 bytes beginning at rbx into rax.)
A special form of the mov instruction has been added for 64-bit immediate constants or constant addresses. For all other instructions, immediate constants or constant addresses are still 32 bits.
x64 provides a new rip-relative addressing mode. Instructions that refer to a single constant address are encoded as offsets from rip. For example, the mov rax, [addr] instruction moves 8 bytes beginning at addr + rip to rax.
Instructions, such as jmp, call, push, and pop, that implicitly refer to the instruction pointer and the stack pointer treat them as 64 bits registers on x64.


mineiro

One thing that confuses is about x64 and x86_64;
From my readings we are using x86_64, not sure if x64 it's specific to Itanium processors.
I'd rather be this ambulant metamorphosis than to have that old opinion about everything

hutch--

It came from the earliest x64 was done by AMD so Intel back then has to draw a distinction between the AMD hardware and their own. Then they were forced by the market to produce a non-Itanium 64 bit version. These days x64 just means Intel x86 hardware in 64 bit mode. You really don't want Itanium code.  :P

sinsi

One glaring omission - 16-byte aligning of the stack before an API call.
😁

mineiro

yes, I agree, Itanium it's a complete diferent animal, not compatible with previous x86.
I'd rather be this ambulant metamorphosis than to have that old opinion about everything