深入理解JAVA虛擬機學習筆記13——字節碼指令1(加載和存儲)

一個忙碌的週末又過去了,時間不能阻止我們前進的腳步,每天進步一點點!

上一篇在方法體中,方法體被編譯成了指令,我們已經初步瞭解了每條字節碼指令佔用一個字節, 大概有200餘種字節碼指令。

虛擬機的解釋器的工作流程大致如下圖僞代碼所示。

對於這麼多字節碼命令,可以分爲幾個部分。

一.  加載和存儲指令:用於將數據在局部變量表和操作數棧之間傳輸。

1、將一個局部變量加載到操作棧:iload、iload_<n>、lload、lload_<n>、fload、fload_<n>、dload、dload_<n>、aload、aload_<n>。

2、將一個數值從操作數棧存儲到局部變量表:istore、istore_<n>、lstore、lstore_<n>、fstore、fstore_<n>、dstore、dstore_<n>、astore、astore_<n>。

3、將一個常量加載到操作數棧:bipush、sipush、ldc、ldc_w、ldc2_w、aconst_null、iconst_m1、iconst_<i>、lconst_<l>、fconst_<f>、dconst_<d>。

4、擴充局部變量表的訪問索引的指令:wide。

下面我們通過一段代碼,簡單地看一下,字節碼命令是什麼樣的,代碼如下。

執行結果如下圖所示,這裏就只以整形爲例。

0:bipush——將常量10加載到操作數棧中;可是爲什麼不用iconst呢?如果截圖截全一些,我們就會看到這個時存的是“a”,也就是-128到127之間用的是bipush;

2:istore_1——將10存儲到局部變量表;

21:ldc——將a加載到操作數棧。

26:iload_1——將局部變量表中的10加載到操作數棧。

對於這部分不知道大家有沒有注意到,以各種load爲例,這麼多load只是首字母不同,爲什麼又這麼多呢?

其實首字母代表的是數據類型,以i開頭代表int類型,l代表long,s代表short,b代表byte,c代表char,f代表float,d代表double,a代表reference。

對於不同的指令,都會針對不同的數據類型,提供不同的指令。

如上圖所示,通過使用數據類型列所代表的特殊字符替換 opcode 列的指令模板中的 T,就可以得到一個具體的字節碼指令。

如果在表中指令模板與數據類型兩列共同確定的格爲空,則說明虛擬機不支持這種數據類型執行這項操作。

另外對於以<n>結尾的一些命令,適用與本地變量少於4個,當超過四個的時候,需要在後面增加對應的參數。

這裏就以load爲例,聲明四個局部變量。

喜歡文章或想一起學習的朋友可以關注我,給我點贊,我將會持續更新,有什麼疑問或文中有不當之處請給我留言,真誠地希望能與大家一起交流探討,學習進步。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章