不同的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等變量引用就可以了。
推薦閱讀:
第2篇-JVM虛擬機這樣來調用Java主類的main()方法
第13篇-通過InterpreterCodelet存儲機器指令片段
如果有問題可直接評論留言或加作者微信mazhimazh
關注公眾號,有HotSpot VM源碼剖析系列文章!