基於棧的指令集與基於寄存器的指令集的區別,JVM指令集實例


現代JVM在執行Java代碼的時候,通常都會將解釋執行與編譯執行兩者結合起來
所謂解釋執行,就是通過解釋器來讀取字節碼,遇到相應的指令就去執行該指令。
所謂編譯執行,就是通過即時編譯器(Just In Time,JIT) 將字節碼轉為本地機器碼來執行;現代JVM會根據代碼熱點來生成相應的本地機器碼。

基於棧的指令集與基於寄存器的指令集直接的關系
1、JVM執行指令時所采取的方式是基於棧的指令集
2、基於棧的指令集主要的操作有入棧與出棧兩種。
3、基於棧的指令集的優勢在於它可以在不同平台之間進行移植,而基於寄存器的指令集是與硬件架構緊密關聯的,無法做到可移植。
4、基於棧的指令集的缺點在於完成相同的操作,指令數量通常要比基於寄存器的指令集數量要多;基於棧的指令集是在內存中完成操作的,
而基於寄存器的指令集是直接由CPU來執行的,它是在高速緩沖區進行執行的,速度要快很多。雖然虛擬機可以采用一些優化手段,
但總體來說,基於棧的指令集的執行速度要慢一些。

 

如對數字2-1的操作,基於棧和基於寄存器的區別

基於棧的指令
1.iconst_1 //將減數1壓入棧頂
2.iconst_2 //將被減數2壓入棧頂
3.isub //將棧中最上面的兩個元素(2和1)彈出來,執行2-1的操作,將2-1的結果1壓入棧頂
4.istore_0 //將1放入局部變量表的第0個位置上。


基於寄存器
mov 將2放入寄存器,
sub 后面跟一個參數1,在現有的寄存器上減去1,在把結果放回寄存器。

 

JVM指令集實例

創建MyTest8.java類

public class MyTest8 {

    public int myCalculate(){
        int a = 1;
        int b = 2;
        int c = 3;
        int d = 4;
        int result = (a + b - c) * d;
        return  result;
    }
}

  使用jclasslib查看myCalculate方法

這21條指令就是myCalculat方法的操作步驟

0 iconst_1   //將1放入操作數棧頂
1 istore_1   //彈出操作數棧頂元素,並把元素的值復制到本地變量表索引為1的位置。
2 iconst_2   //將2放入操作數棧頂
3 istore_2   //彈出操作數棧頂元素,並把元素的值復制到本地變量表索引為2的位置。
4 iconst_3   //將3放入操作數棧頂
5 istore_3   //彈出操作數棧頂元素,並把元素的值復制到本地變量表索引為3的位置。
6 iconst_4   //將4放入操作數棧頂
7 istore 4     //彈出操作數棧頂元素,並把元素的值復制到本地變量表索引為4的位置。
9 iload_1     //從本地變量表中索引為1的值壓入操作數棧
10 iload_2   //從本地變量表中索引為2的值壓入操作數棧
11 iadd  //彈出操作數棧最上層的兩個元素,進行加操作(1+2),將結果3壓入操作數棧
12 iload_3   //從本地變量表中索引為3的值壓入操作數棧
13 isub        //彈出操作數棧最上層的兩個元素,進行減操作(3-3),將結果0壓入操作數棧
14 iload 4    //從本地變量表中索引為4的值壓入操作數棧
16 imul       //彈出操作數棧最上層的兩個元素,進行乘法操作(0 * 4),將結果0壓入操作數棧
17 istore 5    //彈出操作數棧頂元素,並把元素的值復制到本地變量表索引為5的位置。
19 iload 5    //從本地變量表中索引為5的值壓入操作數棧
21 ireturn    //彈出當前操作數棧頂元素,將值壓到調用者的操作數棧中。當前操作數棧的所有元素都將被丟棄。

 

本地變量表如下圖

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM