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 文件只会被当成普通文本

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

相关推荐
AI科技星19 小时前
《全域数学/数术工坊》体系总览
c语言·开发语言·汇编·electron·概率论
H Journey1 天前
用汇编语言写一个hello world,并进行汇编和编译
汇编·assembly·寄存器
逆境不可逃1 天前
一篇速成 汇编程序语言设计之 8086 汇编核心指令
汇编
疯狂打码的少年2 天前
【程序语言与编译】程序设计语言分类(机器/汇编/高级)
汇编·笔记
JAMSAN09302 天前
16.0% 高增长!全球异构计算架构服务市场扩容态势
汇编·人工智能·架构
iCxhust4 天前
8086汇编 word ptr
汇编·单片机·嵌入式硬件·微机原理·8088单板机
大阳1234 天前
ARM.9(RGBLCD,PWM)
c语言·开发语言·汇编·单片机·嵌入式硬件·pwm·rgblcd
2301_789015625 天前
Linux基础开发工具一:软件包管理器、vim编辑器
linux·服务器·c语言·汇编·c++·编辑器·vim
是星辰吖~6 天前
X86反汇编_深度学习_基础二叉树
汇编
iCxhust6 天前
汇编返回指令ret iret retf区别
汇编·微机原理·8088单板机