X64汇编语言寄存器结构及其与X86架构编程区别

目录

1.  关于X64架构

2.  X64架构的寄存器结构

2.1  通用目的寄存器

2.2 浮点数寄存器

2.3 指令指针寄存器

2.4 段寄存器

2.5 标识寄存器

2.6 控制寄存器

2.6.1 控制寄存器CR0

2.6.2 控制寄存器CR2

2.6.3 控制寄存器CR3

2.6.4 控制寄存器CR4

2.6.5 控制寄存器CR8

2.6.6 控制寄存器CR1,CR5-7, CR9-15

2.7  模式指定寄存器(MSRs)(Model Specific Registers)

2.7.1 IA32  EFER寄存器

2.7.2  FS.base, GS.base

2.7.3  内核GSBase

2.8  调试寄存器(Debug Registers)

2.8.1  DR0-DR3寄存器

2.8.2  DR6寄存器

2.8.3  DR7寄存器

2.9  测试寄存器(Test Registers)

2.10  保护模式寄存器(Protected Mode Registers)

2.10.1  全局描述符表寄存器(GDTR)(Global Descriptor Table Registers)

2.10.2 局部描述符表寄存器(LDTR)(Local Descriptor Table Registers)

2.10.3 任务寄存器(TR)(Task Registers)

2.10.4 中断描述符表寄存器(IDTR)(Interrupt Descriptor Table Registers)

3.  X64架构调用约定

4.  X64架构寻址模式


1.  关于X64架构

X64结构是一个向后兼容的X86结构的扩展。它提供了一个传统的32位模式。实际上,它等同于一个X86模式,和一个新的64位模式。

2.  X64架构的寄存器结构

2.1  通用目的寄存器

X64将X86的8个通用寄存器扩展为64位,增加了8个新的通用64位寄存器。64位寄存器的名称都以字母“r”开头(当然,寄存器名称不区分大小写,也可以是“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

数据寄存器,通常扩展A寄存器

rsi

esi

si

sil

字符串操作的源索引

rdi

edi

di

dil

字符串操作的目的索引

rbp

ebp

bp

bpl

栈指针

rsp

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

新增通用寄存器

注意:使用REX.W指令前缀时,不能访问AH、BH、CH 和 DH。当操作数包含 64 位寄存器时,会添加此前缀(由汇编程序自动添加)。

输出到32位子寄存器的操作数自动零扩展到整个64位寄存器(注:0扩展不影响符号位,因为有符号数最高位为1才表示负数)。输出到8位和16位字寄存器的操作数不是0扩展(这是为了兼容x86的行为)。

ax、bx、cx和dx的高 8 位仍可寻址为ah、bh、ch、dh,但不能与所有类型的操作数一起使用。

指令指针寄存器eip和标识寄存器flags已被分别扩展为64位。

2.2 浮点数寄存器

x64处理器也提供了几套浮点寄存器:

8个80位x87 寄存器。

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

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

2.3 指令指针寄存器

指令指针寄存器rip和标识寄存器flags已被分别扩展为64位。

注意:指令指针只能用于rip相对寻址,它是在long模式中引入的。

名称

64

32

16

RIP

EIP

IP

2.4 段寄存器

段寄存器全部为16位长。

名称

描述

CS

代码段

DS

数据段

SS

堆栈段

ES

扩展段 (用于字符串操作)

FS

通用目的段

GS

通用目的段

无论GDT中的段描述符是什么,CS、DS、ES 和 SS的段都被视为它们的基数为 0。FS 和 GS 例外,它们有 MSR 来改变它们的基数。

对所有段禁用限制检查。

2.5 标识寄存器

标识

描述

0

CF

进位标识(Carry Flag)

1

1

保留(Reserved)

2

PF

校验标识(Parity Flag)

3

0

保留(Reserved)

4

AF

辅助进位标识(Auxiliary Carry Flag)

5

0

保留(Reserved)

6

ZF

零标识(Zero Flag)

7

SF

符号标识(Sign Flag)

8

TF

陷阱标识(Trap Flag)

9

IF

中断使能标识(Interrupt Enable Flag)

10

DF

方向标识(Direction Flag)

11

OF

溢出标识(Overflow Flag)

12-13

IOPL

I/O特权级别标识(I/O Privilege Level)

14

NT

嵌入任务标识(Nested Task)

15

0

保留(Reserved)

16

RF

恢复标识(Resume Flag)

17

VM

虚拟8086标识(Virtual-8086 Mode)

18

AC

对齐检查/访问控制标识(Alignment Check / Access Control)

19

VIF

虚拟中断标识(Virtual Interrupt Flag)

20

VIP

虚拟中断挂起标识(Virtual Interrupt Pending)

21

ID

身份标识(ID Flag)

22-63

0

保留(Reserved)

2.6 控制寄存器

2.6.1 控制寄存器CR0

标识

描述

0

PE

保护模式使能标识(Protected Mode Enable)

1

MP

监控协处理器(Monitor Co-Processor)

2

EM

枚举标识(Emulation)

3

TS

任务切换标识(Task Switched)

4

ET

扩展标识(Extension Type)

5

NE

数字错误标识(Numeric Error)

6-15

0

保留(Reserved)

16

WP

写入保护标识(Write Protect)

17

0

保留(Reserved)

18

AM

对齐掩码标识(Alignment Mask)

19-28

0

保留(Reserved)

29

NW

非直写标识(Not-Write Through)

30

CD

缓存禁用标识(Cache Disable)

31

PG

分页标识(Paging)

32-63

0

保留(Reserved)

请注意,该寄存器是唯一可以通过 2 种方式读写的控制寄存器,而其他控制寄存器只能通过 MOV 指令访问

2.6.2 控制寄存器CR2

该控制寄存器包含触发页面错误的线性(虚拟)地址,可在页面错误的中断处理程序中使用。

2.6.3 控制寄存器CR3

标识

标述

条件

0-11

0-2

0

保留(Reserved)

CR4.PCIDE = 0

3

PWT

页级直写(Page-Level Write Through)

5

PCD

页级缓存禁用(Page-Level Cache Disable)

5-11

0

保留(Reserved)

0-11

PCID

CR4.PCIDE = 1

12-63

PML4的物理基地址(Physical Base Address of the PML4)

请注意,这必须是页面对齐的

2.6.4 控制寄存器CR4

标识

描述

0

VME

虚拟8086模式扩展(Virtual-8086 Mode Extensions)

1

PVI

保护模式虚拟中断(Protected Mode Virtual Interrupts)

2

TSD

仅0环时间戳启用(Time Stamp enabled only in ring 0)

3

DE

调试扩展(Debugging Extensions)

4

PSE

分页扩展(Page Size Extension)

5

PAE

物理地址扩展(Physical Address Extension)

6

MCE

主机检查异常(Machine Check Exception)

7

PGE

分页全局使能(Page Global Enable)

8

PCE

性能监控计数使能(Performance Monitoring Counter Enable)

9

OSFXSR

操作系统支持fxsave fxrstor 指令(OS support for fxsave and fxrstor instructions)

10

OSXMMEXCPT

操作系统支持未屏蔽的simd浮点异常(OS Support for unmasked simd floating point exceptions)

11

UMIP

用户模式指令预防(User-Mode Instruction Prevention (SGDT, SIDT, SLDT, SMSW, STR在用户模式是禁用的))

12

0

保留(Reserved)

13

VMXE

虚拟机扩展使能(Virtual Machine Extensions Enable)

14

SMXE

更安全的模式扩展使能(Safer Mode Extensions Enable)

15

0

保留(Reserved)

17

PCIDE

PCID 使能PCID Enable)

18

OSXSAVE

XSAVE 和处理器扩展状态使能(XSAVE And Processor Extended States Enable)

19

0

保留(Reserved)

20

SMEP

监督模式执行保护使能(Supervisor Mode Executions Protection Enable)

21

SMAP

监督模式访问保护使能(Supervisor Mode Access Protection Enable)

22

PKE

用户模式分页使能保护密钥(Enable protection keys for user-mode pages)

23

CET

控制流执行技术使能(Enable Control-flow Enforcement Technology)

24

PKS

监督模式分页使能保护密钥(Enable protection keys for supervisor-mode pages)

25-63

0

保留(Reserved)

2.6.5 控制寄存器CR8

CR8是64位模式下的一个使用REX前缀可访问的新的寄存器。CR8用于优秀处理外部中断,并且被称为是任务优先级寄存器(Task-priority register,简记为TPRAMD64架构允许软件定义最多15个外部中断优先类。优先分类标号从1到15,其中,1是最低级优先级分类,15是最高优先级分类。CR8使用低序4位来指定任务优先级,而将其余60位保留且必须都置为0。系统软件可以使用 TPR 寄存器临时阻止低优先级中断去中断高优先级任务。这是通过将对应的要被阻止的最高优先级中断的值载入TPR来达成的。例如,将一个值9(对应的二进制是1001)载入TPR屏蔽所有中断优先级小于等于9的所有中断,而允许中断优先级大于等于10的中断被识别。将0载入TPR则允许所有外部中断。将15(对应二进制1111)载入TPR则禁止所有外部中断。复位时,TPR被置为0

目的

0-3

优先极

4-63

保留

2.6.6 控制寄存器CR1CR5-7, CR9-15

保留,当试图访问这些寄存器的时候,CPU将抛出一个#ud异常。

2.7  模式指定寄存器(MSRs)(Model Specific Registers)

2.7.1 IA32  EFER寄存器

扩展特征使能寄存器(EFER)(Extend Feature Enable Register)是AMD K6处理器中加入的模式指定寄存器,允许启用SYSCALL/SYSRET指令,而后是为了进入和退出长模式(long mode),该寄存器在AMD64中成为体系结构,被已被Intel采用。它的它的 MSR 编号是 0xC0000080。

标识

描述

0

SCE

系统调用扩展(System Call Extensions)

1-7

0

保留

8

LME

长模式使能(Long Mode Enable)

10

LMA

长模式激活(Long Mode Active)

11

NXE

非执行使能(No-Execute Enable)

12

SVME

安全虚拟机使能(Secure Virtual Machine Enable)

13

LMSLE

长模式段限制使能(Long Mode Segment Limit Enable)

14

FFXSR

快速FXSAVE/ FXRSTOR( Fast FXSAVE/FXRSTOR)

15

TCE

翻译缓存扩展(Translation Cache Extension)

16-63

0

保留

2.7.2  FS.base, GS.base

地址为 0xC0000100(FS)和 0xC0000101(GS)的 MSR 包含 FS 和 GS 段寄存器的基地址。 这些寄存器通常用于用户代码中的线程指针和内核代码中的 CPU 本地指针。 安全地包含任何内容,因为使用段不会赋予用户代码额外的权限。

在较新的 CPU 中,这些寄存器也可以使用任何特权级别的 WRFSBASE 和 WRGSBASE 指令编写。

2.7.3  内核GSBase

MSR地址为0xC0000102。 基本上是一个在执行swapgs指令后与 GS.base 交换的缓冲区。 通常用于分隔内核和用户使用的GS寄存器。

2.8  调试寄存器(Debug Registers)

2.8.1  DR0-DR3寄存器

包括最多多4个断点的线性地址。假如启用了分页机制,它们将被转换为物理地址。

2.8.2  DR6寄存器

允许调试器确定那一个调试条件触发了调试。当启用了调试异常,在进入调试异常处理之前,低次序的0-3位将被设置。

2.8.3  DR7寄存器

描述

0

局部DR0断点(Local DR0 Breakpoint)

1

全局DR0断点(Global DR0 Breakpoint)

2

局部DR1断点(Local DR1 Breakpoint)

3

全局DR1断点(Global DR1 Breakpoint)

4

局部DR2断点(Local DR2 Breakpoint)

5

全局DR2断点(Global DR2 Breakpoint)

6

局部DR3断点(Local DR3 Breakpoint)

7

全局DR3断点(Global DR3 Breakpoint)

16-17

DR0触发条件(Conditions for DR0)

18-19

DR0断点大小(Size of DR0 Breakpoint)

20-21

DR1触发条件(Conditions for DR1)

22-23

DR1断点大小(Size of DR1 Breakpoint)

24-25

DR2触发条件(Conditions for DR2)

26-27

DR2断点大小(Size of DR2 Breakpoint)

28-29

DR3触发条件(Conditions for DR3)

30-31

DR3断点大小(Size of DR3 Breakpoint)

局部断点位在硬件任务切换时停用,而全局则不会。 00b 条件表示执行中断,01b 表示写观察点,11b 表示 R/W 观察点。 10b 为 I/O R/W 保留(不支持)。

2.9  测试寄存器(Test Registers)

名称

说明

TR3 - TR5

无证(Undocumented)

TR6

测试命令寄存器(Test Command Register)

TR7

测试数据寄存器(Test Data Register)

2.10  保护模式寄存器(Protected Mode Registers)

2.10.1  全局描述符表寄存器(GDTR)(Global Descriptor Table Registers)

操作数大小

标识

描述

64

32

0-15

Limit

GDT大小

16-79

16-47

Base

GDT起始地址

2.10.2 局部描述符表寄存器(LDTR)(Local Descriptor Table Registers)

    存储局部描述符表的段选择子。

2.10.3 任务寄存器(TR)(Task Registers)

存储任务状态段TSS(Task Status Segment) 段选择子。

2.10.4 中断描述符表寄存器(IDTR)(Interrupt Descriptor Table Registers)

操作数大小

标识符

描述

64-bit

32-bit

0-15

Limit

 IDT大小

16-79

16-47

Base

IDT起始地址

3.  X64架构调用约定

与X86调用约定不同,C/C++编译器在64位平台上仅支持一种调用约定。这种调用约定利用了64位平台上可获得的新增寄存器数量:

(1)前4个整数或者指针参数依次通过rcx,rdx,r8和r9传递。

(2)前4个浮点参数通过通过前4个SSE寄存器xmm0-xmm3传递。

(3)由调用者为寄存器中的参数传递保留栈上的空间(至少在运行栈上分配32字节的阴影空间(shadow space))。被调用函数可以访问这个栈空间来,将寄存器中的内容写回栈空间。

(4) 任何多余4个参数的其它参数都使用栈来传递,并按照从左到右的次序(即,从第5个参数开始,使用栈传递参数)。

(5) 任何调用返回的整数或者指针值都放在rax寄存器中(调用完成执行返回动作时放在rax寄存器中,例如,调用ret指令时),而浮点数的返回值放在寄存器xmmO中。

(6) rax,rcx,rdx,r8-r11寄存器是易失性的(volatile)。

(7) rbx,rbp,rdi,rsi,r12-r15 寄存器是非易失性的(nonvolatile)。

这些调用约定与C++非类似:指针默认作为第一个参数传递,其它三个参数利用余下的3个寄存器,多出4个的参数则使用栈传递。

(8) call指令从rsp(堆栈指针)寄存器中减去 8,表示空出8字节的栈空间用于存放返回值,因为地址是64位长(8字节)。

(9) 当调用一个子过程(subroutine)的时候,规定指令指针(rip)必须在一个16字节的边界对齐(也就是128位,即16的倍数,这可能是在设计CPU时综合性能考量)。call指令将一个8字节的返回地址压入堆栈中,因此,调用程序必须从堆栈指针中减去8,除了32,它已经减去了阴影空间。

4.  X64架构寻址模式

X64架构的寻址模式与X86类似,但不完全等同:

(1)引用 64 位寄存器的指令以 64 位精度自动执行。例如:

mov rax, [rbx] 将rbx中的8个字节移动动rax中,8个字节即64位。

(2)64位立即常量或常量地址已加入了一种特殊形式的 mov 指令。 对于其他所有指令,立即常量或常量地址仍然是 32 位。

(3)X64架构提供了一种新的rip相对寻址模式(rip-relative),引用单常量地址的指令被编码为基于rip的偏移量(offsets)。例如:

mov rax, [addr] 指令移动以 addr + rip为起始地址的8字节内容到rax寄存器。

(4)隐式引用指令指针和堆栈指针的指令(例如 jmp、call、push 和 pop)将它们视为 X64 上的 64 位寄存器。

参考资料:

Intel和AMD官方文档

微软开发文档:x64 Architecture - Windows drivers | Microsoft Docs

其它网络资源:

CPU Registers x86-64 - OSDev Wiki

Assembly Language Tutorial => x86 Registers

你可能感兴趣的:(汇编语言,操作系统,CPU处理器类,架构,x64寄存器,64位汇编,x64编程,x86汇编)