x64(一)

一、从 8 个到 16 个:通用寄存器数量翻倍

1.1 x86:8 个通用寄存器

cpp 复制代码
EAX  EBX  ECX  EDX
ESI  EDI
EBP  ESP

1.2 x64:16 个通用寄存器

x64 在保留原有寄存器的同时,引入了 R8--R15:

cpp 复制代码
RAX  RBX  RCX  RDX
RSI  RDI
RBP  RSP
R8   R9   R10  R11
R12  R13  R14  R15

二、寄存器宽度的变化:从 32 位到 64 位

2.1 寄存器层级关系

RAX 为例:

cpp 复制代码
RAX (64)
└── EAX (32)
    └── AX (16)
        ├── AH (8)
        └── AL (8)

⚠️ x64 中一个极其重要的规则:

写 EAX 会自动清零 RAX 的高 32 位

cpp 复制代码
mov rax,0x6666666666666666
mov eax,0x12345678
;rax = 0x12345678

2.2 新增寄存器 R8--R15 的子寄存器

x64 不只是"加寄存器",还补全了子寄存器体系。

R8 为例:

位宽 名称
64 位 R8
32 位 R8D
16 位 R8W
8 位 R8B

三、64 位并不等于 64 位地址:符号位与"规范地址(Canonical Address)

x64 的通用寄存器已经全部扩展到了 64 位。

但这并不意味着:

x64 处理器真的使用了完整的 64 位虚拟地址空间

事实上,x64 的地址是"受限制的 64 位"。

3.1 Intel x64 对"虚拟地址"的基本规定

从 Intel SDM 的角度来看,x64 虚拟地址并不是完整使用 64 位。

Intel 规定:

  • 0--47 位:地址有效位

  • 48--63 位:符号位(Sign Extension)

3.2 Canonical Address(规范地址)

规则只有一条,但极其重要:

位 48--63 必须全部等于第 47 位

换句话说:

  • 如果 bit47 = 0

    👉 bit48--63 必须全是 0

  • 如果 bit47 = 1

    👉 bit48--63 必须全是 1

否则,该地址是 非法地址。

3.3 Windows 的进一步限制:只使用 44 位地址

在 Intel 的规范之上,Windows 又加了一层限制。

在当前主流 Windows x64 实现中:

  • 实际只使用 0--43 位 作为地址

  • 高位同样要求符号扩展

四 、x64 与 x86 的全局变量差异

在反汇编工具中,x64 下对全局变量的访问表面上看起来和 x86 几乎一致,

但这是一个极具迷惑性的现象。

如果只停留在反汇编层面,很容易得出错误结论:

"x64 其实也在用硬编码的绝对地址访问全局变量。"

事实恰恰相反。

4.1 一段"看起来几乎一样"的反汇编

下面是同一段 C 代码:

cpp 复制代码
#include<iostream>
using namespace std;

int i = 0;

int main()
{
	i = 1;
	return 0;
}

x86(32 位)反汇编:

cpp 复制代码
C7 05  48 7F D1 00  01 00 00 00
mov dword ptr [00D17F48h],1  

x64(64 位)反汇编:

cpp 复制代码
C7 05  6B A9 00 00  01 00 00 00
mov dword ptr [00007FF6ED38C170h],1  

从 反汇编显示 来看:

  • 两者都像是在向一个"写死的地址"写值

  • x64 甚至直接显示成了 64 位地址

4.2 x64 中的全局变量访问方式:RIP-relative

在 x64 下,同样的 C 代码,生成的汇编通常是:

cpp 复制代码
mov eax, dword ptr [rip + offset]

这就是 x64 中非常核心的一种寻址方式:

RIP-relative addressing(相对于指令指针寻址)

它的真实含义是:

cpp 复制代码
全局变量地址 = 下一条指令的 RIP + 偏移量

而不是一个"写死的绝对地址"。

更细节部分参考《二进制转反汇编》

六、在 VS2019 的 C/C++ 项目中编写 x64 汇编(MASM)

在 x86 时代,我们可以直接使用 __asm 内联汇编;

但在 x64 下,MSVC 已经彻底移除了内联汇编支持。

也就是说:

在 VS2019 的 x64 项目中,写汇编只能使用"独立汇编文件 + MASM"

6.1启用 MASM 支持

默认情况下,VS2019 的 C/C++ 项目并不会编译 .asm 文件,

需要手动开启 MASM。

操作步骤:

  • 右键项目

  • 项目 → 生成自定义

  • 勾选 masm (.targets, .props)

  • 点击 确定

这一步的本质是:

告诉 MSBuild:

这个项目里可能包含 MASM 汇编文件

6.2 添加汇编文件并设置为 MASM

接下来添加你的汇编文件,例如:

cpp 复制代码
test.asm

然后:

  • 选中 .asm 文件

  • 右键 → 属性

  • 配置属性 → 常规

  • 项类型 → 选择

    👉 Microsoft Macro Assembler

否则:

  • .asm 文件只会被当成普通文本

  • 编译时根本不会进入汇编流程

相关推荐
我在人间贩卖青春5 天前
汇编之伪指令
汇编·伪指令
我在人间贩卖青春5 天前
汇编之伪操作
汇编·伪操作
济6175 天前
FreeRTOS基础--堆栈概念与汇编指令实战解析
汇编·嵌入式·freertos
myloveasuka5 天前
汇编TEST指令
汇编
我在人间贩卖青春5 天前
汇编编程驱动LED
汇编·点亮led
我在人间贩卖青春5 天前
汇编和C编程相互调用
汇编·混合编程
myloveasuka6 天前
寻址方式笔记
汇编·笔记·计算机组成原理
请输入蚊子6 天前
《操作系统真象还原》 第六章 完善内核
linux·汇编·操作系统·bochs·操作系统真像还原
myloveasuka6 天前
指令格式举例
汇编·笔记·计算机组成原理
我在人间贩卖青春7 天前
汇编之分支跳转指令
汇编·arm·分支跳转