x64 体系结构

x64 体系结构是 x86 的向后兼容扩展。 它提供新的 64 位模式和旧版 32 位模式,这与 x86 相同。

术语“x64”包括 AMD 64 和 Intel64。 指令集几乎完全相同。

寄存器

x64 将 x86 的 8 个常规用途寄存器扩展为 64 位,并添加了 8 个新的 64 位寄存器。 64 位寄存器的名称以“r”开头。 例如, eax 的 64 位扩展称为 rax。 新寄存器名为 r8r15

每个寄存器的低 32 位、16 位和 8 位可直接在操作数中寻址。 这包括寄存器,如 esi,其低 8 位以前无法寻址。 下表指定 64 位寄存器较低部分的汇编语言名称。

64 位寄存器 低 32 位 低 16 位 低 8 位
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
粒子 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

输出到 32 位子注册的操作会自动向整个 64 位寄存器零扩展。 输出到 8 位或 16 位子注册的操作不是零扩展的, (这与 x86 行为) 兼容。

axbxcxdx 的高 8 位仍可寻址为 ahbhchdh,但不能与所有类型的操作数一起使用。

指令指针 eip标志 寄存器已分别扩展到 64 位, (riprflags,分别) 。

x64 处理器还提供多组浮点寄存器:

  • 八个 80 位 x87 寄存器。

  • 八个 64 位 MMX 寄存器。 (这些寄存器与 x87 registers 重叠。)

  • 原来的一组 8 个 128 位 SSE 寄存器增加到 16 个。

调用约定

与 x86 不同,C/C++ 编译器仅支持 x64 上的一个调用约定。 此调用约定利用 x64 上可用的寄存器数量增加:

  • 前四个整数或指针参数在 rcxrdxr8r9 寄存器中传递。

  • 前四个浮点参数在前四个 SSE 寄存器 xmm0-xmm3 中传递。

  • 调用方在堆栈上为寄存器中传递的参数保留空间。 调用的函数可以使用此空间将寄存器的内容溢出到堆栈。

  • 任何其他参数都在堆栈上传递。

  • 整数或指针返回值在 rax 寄存器中返回,而浮点返回值以 xmm0 返回

  • raxrcxrdxr8-r11 是可变的。

  • rbxrbprdirsir12-r15 是非易失性。

C++ 的调用约定类似。 指针作为隐式第一个参数传递。 接下来的三个参数在剩余寄存器中传递,其余参数在堆栈上传递。

寻址模式

64 位模式下的寻址模式与 x86 相似,但不完全相同。

  • 引用 64 位寄存器的指令以 64 位精度自动执行。 例如, mov rax,[rbx] 将 8 个字节从 rbx 开始移动到 rax

  • 为 64 位即时常量或常量地址添加了一种特殊形式的 mov 指令。 对于所有其他指令,即时常量或常量地址仍为 32 位。

  • x64 提供了新的 相对翻录寻址模式。 引用单个常量地址的指令编码为 翻录的偏移量。 例如, mov rax, [addr] 指令将从 addr + rip 开始的 8 个字节移动到 rax

隐式引用指令指针的指令(如 jmp调用推送弹出)在 x64 上将其视为 64 位寄存器。

另请参阅