不同的CPU都能够解释的机器语言的体系称为指令集架构(ISA,Instruction Set Architecture),也可以称为指令集(instruction set)。Intel将x86系列CPU之中的32位CPU指令集架构称为IA-32,IA是“Intel Architecture”的简称,也可以称为i386、x86-32。AMD等于Intell提出了x86系列的64位扩展,所以由AMD设计的x86系列的64位指令集架构称为AMD64。后来Intel在自己的CPU中加入和AMD64几乎相同的指令集,称为Intel 64的指令集。AMD64和Intel 64可以统称为x86-64。

x86-64的所有寄存器都是与机器字长(数据总线位宽)相同,即64位的,x86-64将x86的8个32位通用寄存器扩展为64位(eax、ebx、ecx、edx、eci、edi、ebp、esp),并且增加了8个新的64位寄存器(r8-r15),在命名方式上,也从”exx”变为”rxx”,但仍保留”exx”进行32位操作,下表描述了各寄存器的命名和作用。

描述

32位

64位

通用寄存器组

eax

rax

ecx

rcx

edx

rdx

ebx

rbx

esp

rsp

ebp

rbp

esi

rsi

edi

rdi

-

r8~r15

浮点寄存器组

st0~st7

st0~st7

XMM寄存器组

XMM0~XMM7

XMM0~XMM15

其中的%esp与%ebp有特殊用途,用来保存指向程序栈中特定位置的指针。

另外还有eflags寄存器,通过位来表示特定的含义,如下图所示。

在HotSpot VM中,表示寄存器的类都继承自AbstractRegisterImpl类,这个类的定义如下:

源代码位置:hotspot/src/share/vm/asm/register.hpp

class AbstractRegisterImpl;
typedef AbstractRegisterImpl* AbstractRegister; class AbstractRegisterImpl {
protected:
int value() const { return (int)(intx)this; }
}; 

AbstractRegisterImpl类的继承体系如下图所示。

另外还有个ConcreteRegisterImpl类也继承了AbstractRegisterImpl,这个灰与C2编译器的实现有关,这里不做过多讲解。

1、RegisterImpl类

RegisterImpl类用来表示通用寄存器,类的定义如下:

源代码位置:cpu/x86/vm/register_x86.hpp

// 使用Register做为RegisterImpl的简称
class RegisterImpl;
typedef RegisterImpl* Register; class RegisterImpl: public AbstractRegisterImpl {
public:
enum {
number_of_registers = 16,
number_of_byte_registers = 16
};
// ...
};

对于64位来说,通用寄存器的位宽为64位,也可以将eax、ebx、ecx和edx的一部分当作8位寄存器来使用,所以可以存储字节的寄存器数量为4。

在HotSpot VM中定义寄存器,如下:

源代码位置:hotspot/src/cpu/x86/vm/register_x86.hpp

CONSTANT_REGISTER_DECLARATION(Register, noreg, (-1)); // noreg_RegisterEnumValue = ((-1))
CONSTANT_REGISTER_DECLARATION(Register, rax, (0)); // rax_RegisterEnumValue = ((0))
CONSTANT_REGISTER_DECLARATION(Register, rcx, (1)); // rcx_RegisterEnumValue = ((1))
CONSTANT_REGISTER_DECLARATION(Register, rdx, (2)); // rdx_RegisterEnumValue = ((2))
CONSTANT_REGISTER_DECLARATION(Register, rbx, (3)); // rbx_RegisterEnumValue = ((3))
CONSTANT_REGISTER_DECLARATION(Register, rsp, (4)); // rsp_RegisterEnumValue = ((4))
CONSTANT_REGISTER_DECLARATION(Register, rbp, (5)); // rbp_RegisterEnumValue = ((5))
CONSTANT_REGISTER_DECLARATION(Register, rsi, (6)); // rsi_RegisterEnumValue = ((6))
CONSTANT_REGISTER_DECLARATION(Register, rdi, (7)); // rdi_RegisterEnumValue = ((7))
CONSTANT_REGISTER_DECLARATION(Register, r8, (8)); // r8_RegisterEnumValue = ((8))
CONSTANT_REGISTER_DECLARATION(Register, r9, (9)); // r9_RegisterEnumValue = ((9))
CONSTANT_REGISTER_DECLARATION(Register, r10, (10)); // r10_RegisterEnumValue = ((10))
CONSTANT_REGISTER_DECLARATION(Register, r11, (11)); // r11_RegisterEnumValue = ((11))
CONSTANT_REGISTER_DECLARATION(Register, r12, (12)); // r12_RegisterEnumValue = ((12))
CONSTANT_REGISTER_DECLARATION(Register, r13, (13)); // r13_RegisterEnumValue = ((13))
CONSTANT_REGISTER_DECLARATION(Register, r14, (14)); // r14_RegisterEnumValue = ((14))
CONSTANT_REGISTER_DECLARATION(Register, r15, (15)); // r15_RegisterEnumValue = ((15))

宏CONSTANT_REGISTER_DECLARATION定义如下:

源代码位置:hotspot/src/share/vm/asm/register.hpp

#define CONSTANT_REGISTER_DECLARATION(type, name, value)   \
extern const type name; \
enum { name##_##type##EnumValue = (value) }

经过宏扩展后如下:

extern const Register  rax;
enum { rax_RegisterEnumValue = ((0)) }
extern const Register rcx;
enum { rcx_RegisterEnumValue = ((1)) }
extern const Register rdx;
enum { rdx_RegisterEnumValue = ((2)) }
extern const Register rbx;
enum { rbx_RegisterEnumValue = ((3)) }
extern const Register rsp;
enum { rsp_RegisterEnumValue = ((4)) }
extern const Register rbp;
enum { rbp_RegisterEnumValue = ((5)) }
extern const Register rsi;
enum { rsi_RegisterEnumValue = ((6)) }
extern const Register rsi;
enum { rdi_RegisterEnumValue = ((7)) }
extern const Register r8;
enum { r8_RegisterEnumValue = ((8)) }
extern const Register r9;
enum { r9_RegisterEnumValue = ((9)) }
extern const Register r10;
enum { r10_RegisterEnumValue = ((10)) }
extern const Register r11;
enum { r11_RegisterEnumValue = ((11)) }
extern const Register r12;
enum { r12_RegisterEnumValue = ((12)) }
extern const Register r13;
enum { r13_RegisterEnumValue = ((13)) }
extern const Register r14;
enum { r14_RegisterEnumValue = ((14)) }
extern const Register r15;
enum { r15_RegisterEnumValue = ((15)) }

如上的枚举类给寄存器指定了一个常量值。

在cpu/x86/vm/register_definitions_x86.cpp文件中定义的寄存器如下:

const Register  noreg = ((Register)noreg_RegisterEnumValue)
const Register rax = ((Register)rax_RegisterEnumValue)
const Register rcx = ((Register)rcx_RegisterEnumValue)
const Register rdx = ((Register)rdx_RegisterEnumValue)
const Register rbx = ((Register)rbx_RegisterEnumValue)
const Register rsp = ((Register)rsp_RegisterEnumValue)
const Register rbp = ((Register)rbp_RegisterEnumValue)
const Register rsi = ((Register)rsi_RegisterEnumValue)
const Register rdi = ((Register)rdi_RegisterEnumValue)
const Register r8 = ((Register)r8_RegisterEnumValue)
const Register r9 = ((Register)r9_RegisterEnumValue)
const Register r10 = ((Register)r10_RegisterEnumValue)
const Register r11 = ((Register)r11_RegisterEnumValue)
const Register r12 = ((Register)r12_RegisterEnumValue)
const Register r13 = ((Register)r13_RegisterEnumValue)
const Register r14 = ((Register)r14_RegisterEnumValue)
const Register r15 = ((Register)r15_RegisterEnumValue)

当我们需要使用通用寄存器时,通过rax、rcx等变量引用就可以了。

2、FloatRegisterImpl

在HotSpot VM中,使用FloatRegisterImpl来表示浮点寄存器,此类的定义如下:

源代码位置:hotspot/src/cpu/x86/vm/register_x86.hpp

// 使用FloatRegister做为简称
class FloatRegisterImpl;
typedef FloatRegisterImpl* FloatRegister; class FloatRegisterImpl: public AbstractRegisterImpl {
public:
enum {
number_of_registers = 8
};
// ...
}

浮点寄存器有8个,分别是st0~st7,这是8个80位寄存器。

这里需要注意的是,还有一种寄存器MMX,MMX并非一种新的寄存器,而是借用了80位浮点寄存器的低64位,也就是说,使用MMX指令集,会影响浮点运算!

3、MMXRegisterImpl

MMX 为一种 SIMD 技术,即可通过一条指令执行多个数据运算,共有8个64位寄存器(借用了80位浮点寄存器的低64位),分别为mm0 – mm7,他与其他普通64位寄存器的区别在于通过它的指令进行运算,可以同时计算2个32位数据,或者4个16位数据等等,可以应用为图像处理过程中图形 颜色的计算。

MMXRegisterImpl类的定义如下:

class MMXRegisterImpl;
typedef MMXRegisterImpl* MMXRegister;

MMX寄存器的定义如下:

CONSTANT_REGISTER_DECLARATION(MMXRegister, mnoreg , (-1));
CONSTANT_REGISTER_DECLARATION(MMXRegister, mmx0 , ( 0));
CONSTANT_REGISTER_DECLARATION(MMXRegister, mmx1 , ( 1));
CONSTANT_REGISTER_DECLARATION(MMXRegister, mmx2 , ( 2));
CONSTANT_REGISTER_DECLARATION(MMXRegister, mmx3 , ( 3));
CONSTANT_REGISTER_DECLARATION(MMXRegister, mmx4 , ( 4));
CONSTANT_REGISTER_DECLARATION(MMXRegister, mmx5 , ( 5));
CONSTANT_REGISTER_DECLARATION(MMXRegister, mmx6 , ( 6));
CONSTANT_REGISTER_DECLARATION(MMXRegister, mmx7 , ( 7));

宏扩展后如下:

extern const MMXRegister  mnoreg;
enum { mnoreg_MMXRegisterEnumValue = ((-1)) }
extern const MMXRegister mmx0;
enum { mmx0_MMXRegisterEnumValue = (( 0)) }
extern const MMXRegister mmx1;
enum { mmx1_MMXRegisterEnumValue = (( 1)) }
extern const MMXRegister mmx2;
enum { mmx2_MMXRegisterEnumValue = (( 2)) }
extern const MMXRegister mmx3;
enum { mmx3_MMXRegisterEnumValue = (( 3)) }
extern const MMXRegister mmx4;
enum { mmx4_MMXRegisterEnumValue = (( 4)) }
extern const MMXRegister mmx5;
enum { mmx5_MMXRegisterEnumValue = (( 5)) }
extern const MMXRegister mmx6;
enum { mmx6_MMXRegisterEnumValue = (( 6)) }
extern const MMXRegister mmx7;
enum { mmx7_MMXRegisterEnumValue = (( 7)) }

MMX Pentium以及Pentium II之后的CPU中有从mm0到mm7共8个64位寄存器。但实际上MMX寄存器和浮点数寄存器是共用的,即无法同时使用浮点数寄存器和MMX寄存器。  

cpu/x86/vm/register_definitions_x86.cpp文件中定义的寄存器变量如下:

const MMXRegister  mnoreg = ((MMXRegister)mnoreg_MMXRegisterEnumValue)
const MMXRegister mmx0 = ((MMXRegister)mmx0_MMXRegisterEnumValue)
const MMXRegister mmx1 = ((MMXRegister)mmx1_MMXRegisterEnumValue)
const MMXRegister mmx2 = ((MMXRegister)mmx2_MMXRegisterEnumValue)
const MMXRegister mmx3 = ((MMXRegister)mmx3_MMXRegisterEnumValue)
const MMXRegister mmx4 = ((MMXRegister)mmx4_MMXRegisterEnumValue)
const MMXRegister mmx5 = ((MMXRegister)mmx5_MMXRegisterEnumValue)
const MMXRegister mmx6 = ((MMXRegister)mmx6_MMXRegisterEnumValue)
const MMXRegister mmx7 = ((MMXRegister)mmx7_MMXRegisterEnumValue)

当我们需要使用MMX寄存器时,通过mmx0、mmx1等变量引用就可以了。

4、XMMRegisterImpl类

XMM寄存器是SSE指令用的寄存器。Pentium iii以及之后的CPU中提供了xmm0到xmm7共8个128位宽的XMM寄存器。另外还有个mxcsr寄存器,这个寄存器用来表示SSE指令的运算状态的寄存器。在HotSpot VM中,通过XMMRegisterImpl类来表示寄存器。这个类的定义如下:

源代码位置:hotspot/src/share/x86/cpu/vm/register_x86.hpp

// 使用XMMRegister寄存器做为简称
class XMMRegisterImpl;
typedef XMMRegisterImpl* XMMRegister; class XMMRegisterImpl: public AbstractRegisterImpl {
public:
enum {
number_of_registers = 16
};
...
}

XMM寄存器的定义如下:

CONSTANT_REGISTER_DECLARATION(XMMRegister, xnoreg , (-1));
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm0 , ( 0));
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm1 , ( 1));
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm2 , ( 2));
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm3 , ( 3));
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm4 , ( 4));
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm5 , ( 5));
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm6 , ( 6));
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm7 , ( 7));
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm8, (8));
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm9, (9));
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm10, (10));
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm11, (11));
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm12, (12));
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm13, (13));
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm14, (14));
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm15, (15));

经过宏扩展后为:

extern const XMMRegister  xnoreg;
enum { xnoreg_XMMRegisterEnumValue = ((-1)) }
extern const XMMRegister xmm0;
enum { xmm0_XMMRegisterEnumValue = (( 0)) }
extern const XMMRegister xmm1;
enum { xmm1_XMMRegisterEnumValue = (( 1)) }
extern const XMMRegister xmm2;
enum { xmm2_XMMRegisterEnumValue = (( 2)) }
extern const XMMRegister xmm3;
enum { xmm3_XMMRegisterEnumValue = (( 3)) }
extern const XMMRegister xmm4;
enum { xmm4_XMMRegisterEnumValue = (( 4)) }
extern const XMMRegister xmm5;
enum { xmm5_XMMRegisterEnumValue = (( 5)) }
extern const XMMRegister xmm6;
enum { xmm6_XMMRegisterEnumValue = (( 6)) }
extern const XMMRegister xmm7;
enum { xmm7_XMMRegisterEnumValue = (( 7)) }
extern const XMMRegister xmm8;
enum { xmm8_XMMRegisterEnumValue = ((8)) }
extern const XMMRegister xmm9;
enum { xmm9_XMMRegisterEnumValue = ((9)) }
extern const XMMRegister xmm10;
enum { xmm10_XMMRegisterEnumValue = ((10)) }
extern const XMMRegister xmm11;
enum { xmm11_XMMRegisterEnumValue = ((11)) }
extern const XMMRegister xmm12;
enum { xmm12_XMMRegisterEnumValue = ((12)) }
extern const XMMRegister xmm13;
enum { xmm13_XMMRegisterEnumValue = ((13)) }
extern const XMMRegister xmm14;
enum { xmm14_XMMRegisterEnumValue = ((14)) }
extern const XMMRegister xmm15;
enum { xmm15_XMMRegisterEnumValue = ((15)) }

在cpu/x86/vm/register_definitions_x86.cpp文件中定义的寄存器变量如下:

const XMMRegister  xnoreg = ((XMMRegister)xnoreg_XMMRegisterEnumValue)
const XMMRegister xmm0 = ((XMMRegister)xmm0_XMMRegisterEnumValue)
const XMMRegister xmm1 = ((XMMRegister)xmm1_XMMRegisterEnumValue)
const XMMRegister xmm2 = ((XMMRegister)xmm2_XMMRegisterEnumValue)
const XMMRegister xmm3 = ((XMMRegister)xmm3_XMMRegisterEnumValue)
const XMMRegister xmm4 = ((XMMRegister)xmm4_XMMRegisterEnumValue)
const XMMRegister xmm5 = ((XMMRegister)xmm5_XMMRegisterEnumValue)
const XMMRegister xmm6 = ((XMMRegister)xmm6_XMMRegisterEnumValue)
const XMMRegister xmm7 = ((XMMRegister)xmm7_XMMRegisterEnumValue)
const XMMRegister xmm8 = ((XMMRegister)xmm8_XMMRegisterEnumValue)
const XMMRegister xmm9 = ((XMMRegister)xmm9_XMMRegisterEnumValue)
const XMMRegister xmm10 = ((XMMRegister)xmm10_XMMRegisterEnumValue)
const XMMRegister xmm11 = ((XMMRegister)xmm11_XMMRegisterEnumValue)
const XMMRegister xmm12 = ((XMMRegister)xmm12_XMMRegisterEnumValue)
const XMMRegister xmm13 = ((XMMRegister)xmm13_XMMRegisterEnumValue)
const XMMRegister xmm14 = ((XMMRegister)xmm14_XMMRegisterEnumValue)
const XMMRegister xmm15 = ((XMMRegister)xmm15_XMMRegisterEnumValue)

当我们需要使用XMM寄存器时,直接通过xmm0、xmm1等变量引用就可以了。

推荐阅读:

第1篇-关于JVM运行时,开篇说的简单些

第2篇-JVM虚拟机这样来调用Java主类的main()方法

第3篇-CallStub新栈帧的创建

第4篇-JVM终于开始调用Java主类的main()方法啦

第5篇-调用Java方法后弹出栈帧及处理返回结果

第6篇-Java方法新栈帧的创建

第7篇-为Java方法创建栈帧

第8篇-dispatch_next()函数分派字节码

第9篇-字节码指令的定义

第10篇-初始化模板表

第11篇-认识Stub与StubQueue

第12篇-认识CodeletMark

第13篇-通过InterpreterCodelet存储机器指令片段

第14篇-生成重要的例程

第15章-解释器及解释器生成器

第16章-虚拟机中的汇编器

如果有问题可直接评论留言或加作者微信mazhimazh

关注公众号,有HotSpot VM源码剖析系列文章!

第17章-x86-64寄存器的更多相关文章

  1. 第18章-x86指令集之常用指令

    x86的指令集可分为以下4种: 通用指令 x87 FPU指令,浮点数运算的指令 SIMD指令,就是SSE指令 系统指令,写OS内核时使用的特殊指令 下面介绍一些通用的指令.指令由标识命令种类的助记符( ...

  2. 第17章 中介者模式(Mediator Pattern)

    原文 第17章 中介者模式(Mediator Pattern) 中介者模式  概述:   在软件开发中,我们有时会碰上许多对象互相联系互相交互的情况,对象之间存在复杂的引用关系,当需求更改时,对系统进 ...

  3. 【RL-TCPnet网络教程】第17章 RL-TCPnet之UDP通信

    第17章      RL-TCPnet之UDP通信 本章节为大家讲解RL-TCPnet的UDP通信实现,学习本章节前,务必要优先学习第16章UDP用户数据报协议基础知识.有了这些基础知识之后,再搞本章 ...

  4. 第17章 EXTI—外部中断/事件控制器

    第17章     EXTI—外部中断/事件控制器 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.co ...

  5. 第17章 EXTI—外部中断/事件控制器—零死角玩转STM32-F429系列

    第17章     EXTI—外部中断/事件控制器 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.co ...

  6. 第5章 什么是寄存器—零死角玩转STM32-F429系列

    第5章     什么是寄存器 集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/firege 本章参考资料 ...

  7. 【STM32H7教程】第17章 STM32H7之GPIO的HAL库API

    完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第17章       STM32H7之GPIO的HAL库API ...

  8. CSS3秘笈第三版涵盖HTML5学习笔记13~17章

    第13章,构建基于浮动的布局 使用的是float(浮动)属性 注:float:none值将取消所有浮动,通常只用来取消元素中已经应用的浮动. 切记:不需要给正文的div设计宽度,即使设计成固定宽度也不 ...

  9. 《深入Java虚拟机学习笔记》- 第17章 异常

    <深入Java虚拟机学习笔记>- 第17章 异常

  10. JavaScript高级程序设计(第三版)学习笔记11、12、17章

    章, DOM扩展 选择符 API Selector API Level1核心方法querySelector .querySelectorAll,兼容的浏览器可以使用 Document,Element  ...

随机推荐

  1. Axure RP 9 Enterprise/Pro/Team for Mac/Windows安装破解版激活教程

    Axure RP 9.0 是一款功能强大的.操作方便.专业可靠的快速原型设计工具.一款能够在这里体验最简单的设计方式,这里有着全新的升级的软件界面,更加的时尚,更加的丰富,专为每一个用户提供了便捷的设 ...

  2. 01MATLAB导论

    MATLAB语言的主要功能 数值计算 符号计算 图形绘制 程序流程控制 工具箱 课程的学习目标 要求理解MATLAB功能实现的数学背景与算法原理 掌握利用MATLAB进行问题求解的基本规律 能够利用M ...

  3. 硬核万字长文,深入理解 Java 字节码指令(建议收藏)

    Java 字节码指令是 JVM 体系中非常难啃的一块硬骨头,我估计有些读者会有这样的疑惑,"Java 字节码难学吗?我能不能学会啊?" 讲良心话,不是我谦虚,一开始学 Java 字 ...

  4. sqli-labs靶机

    第一关   1' 第二关   1 第三关    1') 第四关    1'') 第五关   1'     +         extractvalue报错注入 第六关   1 "  +    ...

  5. YsoSerial 工具常用Payload分析之Common-Collections7(四)

    前言 YsoSerial Common-Collection3.2.1 反序列化利用链终于来到最后一个,回顾一下: 以InvokerTranformer为基础通过动态代理触发AnnotationInv ...

  6. 分布式ID(CosId)之号段链模式性能(1.2亿/s)解析

    分布式ID(CosId)之号段链模式性能(1.2亿/s)解析 上一篇文章<分布式ID生成器(CosId)设计与实现>我们已经简单讨论过CosId的设计与实现全貌. 但是有很多同学有一些疑问 ...

  7. XCTF-simple unpack

    题目提示这是一个加壳的二进制文件,拖到exeinfope,是UPX壳. 这里我们用linux命令upx -d脱壳. 脱完壳之后拉入ida64中分析.找到main函数,可以看到这一句可以是输出flag的 ...

  8. Salesforce Integration 概览(六) UI Update Based on Data Changes(UI自动更新基于数据变更)

    Salesforce用户界面必须由于Salesforce数据的更改而自动更新.这个场景其实在我所经历的项目中用到的不是特别多,因为客户可能直接点击刷新按钮就直接看到了最新的数据,而不是那种一直不刷新然 ...

  9. JAVA 调用第三方短信平台接口发送短信

    做了几个调用三方短信平台发送短信的例子,大部分需要 携带参数,向指定URL发送请求 回顾对接第一个平台时痛苦的乱码经历,这里放一份代码,算是个模版,再用到的时候过来copy一下就OK. 在进入主题之前 ...

  10. 用notepad2代替notepad

    Windows自带的notepad.exe功能比较弱,notepad2是一个比较好的替代方案,但在任何系统调用notepad的时候都能用notepad2代替并不是一件容易的事,下面是一个解决方法: h ...