1. 程式人生 > >JVM指令集介紹

JVM指令集介紹

fse inf clas -s val 轉載 signed sig icm

轉載自:http://glutinit.iteye.com/blog/1263446

延伸參考 JVM接收參數和方法調用

void spin() {
int i;
for (i = 0; i < 100; i++) {
; // Loop body is empty
}
}

編譯後的代碼如下 (與《Java虛擬機規範(java SE 7)》上看到的不一樣,不知道是不是JDK版本的問題)

void spin();
Code:
0: iconst_0
1: istore_1
2: iload_1
3: bipush 100

5: if_icmpge 14
8: iinc 1, 1
11: goto 2
14: return

調用一個新的方法,就產生一個新的幀棧(Frame),如下圖,在一個幀棧中,含有操作數棧(Operand Stack)和局部變量表(Local Variables),註意,此圖只是用來表示在此期間發生的操作,並不直觀的表示內存中的實際狀態。

STEP1--> 0: iconst_0
技術分享圖片

Code[]數組的第0行,表示把int型的0值壓入操作數棧,註意,在局部變量表中,索引為0的位置存放的局部變量是指向調用當前方法的類實例的指針,即this指針

指令iconst_<i> 中的i表示的int 常量 −1、0、1、2、3、4、5


STEP2--> 1: istore_1
技術分享圖片

從操作數棧中彈出一個int型的操作數(即常量0),然後將其放置在局部變量1號位置(0號位置已被this占據)

註意:物理上講出棧後原來的數還在,只是程序告訴用戶這個格子可以用了,我們就拿它當空格子用,下次入棧的時候寫個新的數就把原來的數覆蓋掉。凡是可以隨便寫的格子,不管裏面原來有什麽,都被認為是空格子。

STEP3--> 2: iload_1
技術分享圖片

從局部變量表中獲得1號位置變量的值,將其壓入操作數棧

STEP4--> 3: bipush 100


技術分享圖片

在操作數棧中加入int型的常量100

STEP5--> 5: if_icmpge 14
技術分享圖片

該命令和《Java虛擬機規範》得到的不太一樣,但起到的功能是一樣的,可以查一下JVM 的在線文檔,發現此命令的介紹如下:

if_icmpge pops the top two ints off the stack and compares them. If value2 is greater than or equal to value1, execution branches to the address (pc + branchoffset), where pc is the address of the if_icmpge opcode in the bytecode and branchoffset is a 16-bit signed integer parameter following the if_icmpge opcode in the bytecode. If value2 is less than value1, execution continues at the next instruction.

即將操作數棧中的兩個int值彈出棧,然後比較它們,如果value2(即這裏的0)大於或等於value1(即這裏的100),則跳轉至14行執行,否則就繼續執行。很顯然,這裏0<100,所以繼續執行下面的代碼。


STEP6--> 8: iinc 1, 1
技術分享圖片

該命令給局部變量表的1號位置的int值增加1,如圖,原來的0變成了1

STEP7--> 11: goto 2
很顯然,這一條的命令就是讓下一條執行語句跳至2,即 iload_1,然後便繼
續執行…



STEP8--> 14: return
當局部變量1號位置的值(即程序中的i)大於100後,便滿足了5: if_icmpge 14這條語句的條件,程序跳到14,遇到了return命令,該方法完成

JVM指令集介紹