x64 体系结构
x64 体系结构是 x86 的向后兼容扩展。 它提供新的 64 位模式和旧版 32 位模式,这与 x86 相同。
术语“x64”包括 AMD 64 和 Intel64。 指令集几乎完全相同。
寄存器
x64 将 x86 的 8 个常规用途寄存器扩展为 64 位,并添加了 8 个新的 64 位寄存器。 64 位寄存器的名称以“r”开头。 例如, eax 的 64 位扩展称为 rax。 新寄存器名为 r8 到 r15。
每个寄存器的低 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 行为) 兼容。
ax、bx、cx 和 dx 的高 8 位仍可寻址为 ah、bh、ch、dh,但不能与所有类型的操作数一起使用。
指令指针 eip 和 标志 寄存器已分别扩展到 64 位, (rip 和 rflags,分别) 。
x64 处理器还提供多组浮点寄存器:
八个 80 位 x87 寄存器。
八个 64 位 MMX 寄存器。 (这些寄存器与 x87 registers 重叠。)
原来的一组 8 个 128 位 SSE 寄存器增加到 16 个。
调用约定
与 x86 不同,C/C++ 编译器仅支持 x64 上的一个调用约定。 此调用约定利用 x64 上可用的寄存器数量增加:
前四个整数或指针参数在 rcx、 rdx、 r8 和 r9 寄存器中传递。
前四个浮点参数在前四个 SSE 寄存器 xmm0-xmm3 中传递。
调用方在堆栈上为寄存器中传递的参数保留空间。 调用的函数可以使用此空间将寄存器的内容溢出到堆栈。
任何其他参数都在堆栈上传递。
整数或指针返回值在 rax 寄存器中返回,而浮点返回值以 xmm0 返回。
rax、 rcx、 rdx、 r8-r11 是可变的。
rbx、 rbp、 rdi、 rsi、 r12-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 位寄存器。