8086 → x86-32 → x64
汇编进阶 · 64 位衔接 · 2026
汇编进阶 · 交互式图解

从 8086 到 x64,
64 位又变了什么?

你已经走过 8086 → x86-32(实模式到保护模式、虚拟内存、分页)。这一页再往前走一步到 x64(AMD64)。好消息:核心内存机制一脉相承,x64 主要是——寄存器更宽更多、地址空间更大、函数调用更快。

8086 · 16 位 x86-32 · 32 位 x64 · 64 位
前置:8086 → x86-32目标:x64 / AMD64衔接:逆向分析
01
第 1 章 · SECTION 01

三代总览

8086 · x86-32 · x64 一次看清
01 / 06

先看一张三代对照表。注意最后一行——内存机制从 x86-32 到 x64 几乎没变,这正是"进阶不费力"的原因:

对比项8086x86-32x64 / AMD64
位数 / 年代16 位 · 197832 位 · 198564 位 · 2003
通用寄存器AX BX … (8×16位)EAX EBX … (8×32位)RAX … + R8–R15 (16×64位)
地址空间1 MB4 GB实际 2⁴⁸ = 256 TB
工作模式实模式保护模式长模式
寻址 / 传参段:偏移平坦 + 分页,栈传参平坦 + 分页,寄存器传参
内存机制直接用物理内存虚拟内存 + 分页虚拟内存 + 分页(不变)
一句话主线

位数一路翻倍(16→32→64),带来更宽更多的寄存器、更大的地址空间、更快的调用;但虚拟内存、分页、进程隔离、内存映射这套机制,从 x86-32 到 x64 原样保留。所以这一页你只需要学"增量"。

02
第 2 章 · SECTION 02

寄存器之变

更宽,也更多
02 / 06

更宽:RAX ⊃ EAX ⊃ AX ⊃ AH / AL

64 位的 RAX 是在你熟悉的名字上"套娃":它的低 32 位就是 EAX,低 16 位是 AX,AX 再拆成 AH/AL。老名字全都还能用,只是外面多了一圈:

RAX 64 位
EAX 低 32 位
AX 低 16 位
AHAL
RBX / RCX / RDX / RSI / RDI / RBP / RSP 也是同样的嵌套关系。
一个重要细节

在 x64 里,写 32 位寄存器会自动把对应 64 位寄存器的高 32 位清零。例如 mov eax, 5 之后,RAX 的高 32 位一定是 0。但写 AXAL 不会清零高位。逆向读代码时这点很关键。

更多:8 个 → 16 个通用寄存器

x64 在原来 8 个的基础上,新增了 R8R15 共 8 个。寄存器多了,更多变量能直接放在寄存器里,少访问内存、跑得更快,也让"寄存器传参"成为可能(第 4 章):

RAXRBXRCXRDX RSIRDIRBPRSP R8R9R10R11 R12R13R14R15
原有 8 个(名字升级为 R 开头) 新增 8 个(R8–R15)
03
第 3 章 · SECTION 03

地址空间之变

4GB → 天文数字
03 / 06

x64 的寄存器是 64 位,理论上能表示 2⁶⁴ 个地址。但现实中没那么多内存,所以当前实现只用 48 位——这已经大到难以想象:

1 MB
8086 · 20 位
× 4096
4 GB
x86-32 · 32 位
× 65536
256 TB
x64 · 48 位

每个进程依然是独立的一套虚拟地址空间,只是从 4GB 变成 256TB 级别。

分页没变,只是"表更大、级数更多"

x64 仍然用分页 + 页表把虚拟地址翻译成物理地址,概念和 x86-32 一模一样。区别是:地址变长了,一级页表装不下,于是页表从 x86-32 的 2 级变成 x64 的 4 级(PML4 → PDPT → PD → PT)。对你来说,"页号 → 页帧"的原理不变

进阶:规范地址(了解即可)

既然只用 48 位,x64 要求地址的高 16 位必须是第 47 位的"符号扩展",这种地址叫规范地址(Canonical)。用户态地址因此集中在低半区,内核态在高半区。

逆向彩蛋:RIP 相对寻址

x64 新增了RIP 相对寻址——可以用"相对当前指令的偏移"来访问数据,而不必写死绝对地址。这让位置无关代码(如 DLL)更好写,你在反汇编里会经常看到 [rip+0x…]

04
第 4 章 · SECTION 04

调用约定之变

栈传参 → 寄存器传参
04 / 06

函数之间怎么传参数,叫调用约定。寄存器变多之后,x64 干脆把"传参"从栈搬到了寄存器——这是逆向时最直观的变化:

x86-32 CDECL / STDCALL
  • 参数从右往左 push 到栈
  • 调用后要清理栈
  • 每次调用都要读写内存,较慢
x64 FASTCALL 风格
  • 前 4 个参数放 RCX RDX R8 R9
  • 多余的才用栈
  • 寄存器比内存快,调用更快
不同系统略有差异

上面是 Windows x64 的约定(前 4 参 RCX RDX R8 R9)。Linux / macOS(System V)用 RDI RSI RDX RCX R8 R9(前 6 参)。逆向时先确认平台。

FIG. 4.1 — 一次 Windows x64 函数调用(点“下一步”)

以调用 add(10, 20, 30, 40, 50) 为例,看参数是怎么交的:

05
第 5 章 · SECTION 05

兼容与不变

老程序还能跑,老知识还能用
05 / 06

你的 32 位老程序,照样能跑

x64 的"长模式"里专门留了一个兼容模式;64 位 Windows 则用 WoW64 子系统来运行 32 位程序。所以你的旧 32 位 EXE/DLL 在新系统上几乎总能直接用。

划重点:知识向前兼容

从 x86-32 到 x64,变的是位数、寄存器数量、传参方式;不变的是虚拟内存、分页、按需调页、进程隔离、内存映射、EXE/DLL。也就是说,前两课讲的机制在 64 位世界依然成立,只是地址从 32 位变成 64 位。

18086实模式 · 段:偏移 · 直接物理内存
2x86-32保护模式 · 平坦+分页 · 虚拟内存
3x64长模式 · 机制不变 · 更宽更快
学完自测 · QUIZ

自测一下

6 道题 · 点选项即看答案与解析

这 6 道题检验你是否完成了从 x86-32 到 x64 的进阶。 尚未作答

Q1x64 中,RAX 的低 32 位是哪个寄存器?
答案:EAX。嵌套关系是 RAX(64) ⊃ EAX(低32) ⊃ AX(低16) ⊃ AH/AL(各8位)。
Q2x64 把通用寄存器从 8 个增加到了 16 个(新增 R8–R15)。
答案:对。更多寄存器让变量少占内存、程序更快,也让"寄存器传参"成为可能。
Q3当前 x64 实现实际用于虚拟地址的位数通常是?
答案:48 位(2⁴⁸ = 256TB)。寄存器虽是 64 位,但当前硬件/系统只用低 48 位做地址,高位必须是符号扩展(规范地址)。
Q4在 x64 中执行 mov eax, 5 后,RAX 的高 32 位会?
答案:自动清零。写 32 位寄存器会把对应 64 位寄存器的高 32 位清零(但写 AX / AL 不会)。这是 x64 的重要规则。
Q5x64 不再使用分页和虚拟内存,回到了直接操作物理内存。
答案:错。x64 仍用分页 + 虚拟内存,只是页表从 2 级变 4 级。"页号 → 页帧"的原理和 x86-32 完全一致。
Q6Windows x64 调用约定中,前 4 个整数参数依次放在?
答案:RCX RDX R8 R9。这是 x64"寄存器传参"的体现(注意是 R8、R9,不是 RAX、RBX);多余参数才用栈。Linux 则用 RDI RSI RDX RCX R8 R9。