intel (Linux):
- Order of function parameters: %rdi, %rsi, %rdx, %rcx, %r8 and %r9.
- Parameters are
- address of return value (unless this fits into a 8B)
- this pointer (if exists)
- agruments of function
- So "%rdi" is usually "this" pointer but might also be the return value address or first argument.
- Note there are some exceptions:
- 1.Member functions (Applies to all C++ compilers and operating systems). All member functions receive a pointer to the object as an implicit parameter, known as this in C++. This pointer comes before the explicit parameters, usually as the first parameter. Constructors must return this in the return register.
- 2.Returning objects (Applies to all compilers and operating systems). Objects that do not fit into the return registers are returned to a storage space supplied by the caller. The caller must supply a return pointer as an implicit parameter to the called function if this is necessary. The same pointer is returned in the return register. The rules for deciding whether an object is returned in registers or through a return pointer are explained below for each platform. A member function that returns an object can have two implicit parameters, a return pointer and a this pointer. In Microsoft compilers and 64 bit Windows, the this pointer is the first parameter, the return pointer is the second parameter, and all explicit parameters come thereafter. In Borland and Gnu compilers and in 64 bit Linux and BSD, the return pointer is the first parameter, the this pointer is the second parameter, and all explicit parameters come thereafter (this order is compatible with C)
- Note there are some exceptions:
- Return-Value: rax
- The registers RAX, RCX, RDX, R8, R9, R10, R11 are considered volatile.
- The registers RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15 are considered nonvolatile and must be saved and restored by a function that uses them.
Example, for some c++ member function returns an object:
```
0x00007fd865fbdcc0 <+0>: push rbp ---> enter this frame
0x00007fd865fbdcc1 <+1>: mov rbp,rsp
0x00007fd865fbdcc4 <+4>: add rsp,0xffffffffffffff80
0x00007fd865fbdcc8 <+8>: mov QWORD PTR [rbp-0x78],rdi ---> 1st param, return value address
0x00007fd865fbdccc <+12>: mov QWORD PTR [rbp-0x80],rsi ---> 2nd, "this" pointer
=> 0x00007fd865fbdcd0 <+16>: mov rax,QWORD PTR [rbp-0x80]
0x00007fd865fbdcd4 <+20>: movzx eax,BYTE PTR [rax+0xa9] ---> access some member offset to 0xa9(must be some value within 8 bits)
0x00007fd865fbdcdb <+27>: cmp al,0x1 ---> eax lower 8 bits
...
0x00007fd865fbddc7 <+263>: mov rdi,rax
0x00007fd865fbddca <+266>: call 0x7fd865fbda60
0x00007fd865fbddcf <+271>: mov rax,QWORD PTR [rbp-0x78] ----> rax is the return value, so the return value's address is copied to rax again.
0x00007fd865fbddd3 <+275>: leave
0x00007fd865fbddd4 <+276>: ret
```
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 |
Really good summary, thanks to the author: