Skip to content

Latest commit

 

History

History
43 lines (37 loc) · 3.23 KB

File metadata and controls

43 lines (37 loc) · 3.23 KB

Canonical Form


  • All addresses and pointers are 64-bit, but virtual addresses must be in canonical form. Canonical form means that bit 47 and bits 48-63 must match since modern processors only support 48-bit for address space rather than the full 64-bit. If the address is not in canonical form, an exception will be raised

Registers


  • Aside from the old x86 registers being extended from 32-bit to 64-bit, extra General Purpose Registers have also been added (e.g. r8 to r15)
  • 16 general-purpose registers each 64-bits (RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, R8, R9, R10, R11, R12, R13, R14, R15)
    • DWORD (32-bit) version can be accessed with a D suffix, WORD (16-bit) with a W suffix, BYTE (8-bit) with a B suffix for registers R8 to R15
    • For registers with alternate names like x86 (e.g. RAX, RCX), size access for register is same as x86. For example, 32-bit version of RAX is EAX and the 16-bit version is DX
    • RBP is treated like another GPR. As a result, local variables are referenced through RSP
  • 16 XMM registers, each 128-bit long. XMM registers are for SIMD instruction set, which is an extension to the x86-64 architecture. SIMD is for performing the same instruction on multiple data at once and/or for floating point operations
    • Floating point operations were once done using stack-based instruction set that accesses the FPU Register Stack. But now, it can be done using the SIMD instruction set

Calling Conventions


  • Parameters are passed to registers instead of the stack. Although additional ones will still be stored on stack
  • Windows: first 4 parameters are placed in RCX, RDX, R8, and R9
  • Linux: first 6 parameters are placed in RDI, RSI, RDX, RCX, R8, and R9

Exception Handling


  • Windows: on x86, Structured Exception Handling (SEH) is stored on the stack, which makes it vulnerable to buffer overflow attacks. SEH on x64 is implemented differently. SEH is table-based and no longer stored on the stack. It is instead stored in the PE Header
  • Linux: for both x86 and x64, exception handling can be achieved through signals

Other Notable Differences From x86


  • Easier in 64-bit code to differentiate between pointers and data values. The most common size for storing integers is 32 bits and pointers are always 64 bits
  • Supports instruction pointer-relative addressing on data. Unlike x86, referencing data will not use absolute address but rather an offset from RIP
  • Can't directly push an immediate value on the stack with the PUSH instruction in x86-64
    • Needs to move the value into a register first and then push: MOV RAX, 0x1122334455667788; PUSH RAX
  • Have direct access to RIP (instruction pointer) unlike x86
    • This is valid: MOV RAX, RIP

x86 <- RERM[.instruction-sets] -> ARM