JAVA操做碼相關指令介紹(1)

以前的文章就簡單的給你們介紹了各類鎖的介紹與使用(文末有對應的連接),目前這章爲以後講解鎖的操做底層實現先奠基下基礎。java

JAVA基本類型轉換

JAVA中基本類型的轉換是不涉及操做數的,轉換的值是直接從棧頂端得到,JAVA虛擬機從棧頂彈出一個值,對他進行轉換,而後再把轉換結果壓入棧中。多線程

1.int、long、float、double 類型之間的相互轉換

操做碼 操做數 備註
i2l 將int類型的值轉換爲long類類型
i2f 將int類型的值轉換爲float類類型
i2d 將int類型的值轉換爲double類類型
l2i 將long類型的值轉換爲int類類型
l2f 將long類型的值轉換爲float類類型
l2d 將long類型的值轉換爲double類類型
f2i 將float類型的值轉換爲int類類型
f2l 將float類型的值轉換爲long類類型
f2d 將float類型的值轉換爲double類類型
d2i 將double類型的值轉換爲int類類型
d2l 將double類型的值轉換爲long類類型
d2f 將double類型的值轉換爲float類類型

2.int數據類型向byte、char、short類型的轉換

操做碼 操做數 備註
i2b 將int類型的值轉換爲byte類型值,進行帶符號擴展,恢復爲int類型壓入棧
i2c 將int類型的值轉換爲char類型值,進行零擴展,恢復成int類型壓入棧
i2s 將int類型的值轉換爲short類型值,進行帶符號擴展,恢復成int類型壓入棧

不存在比int類型佔據更小空間的數據類型轉化爲int類型操做碼。由於上面三種才進行壓入棧的時候,就已經轉換爲int類型,而後再對int類型值進行運算,最後獲得int類型值。併發

Demo:ide

public static void main(String[] args) {
		byte a =2;
		byte b =1;
		byte c = (byte) (a+b);
	}
複製代碼
public static void main(java.lang.String[]);
    Code:
       0: iconst_2  //常量2入棧
       1: istore_1  //彈出棧頂元素存入位置1的局部變量
       2: iconst_1  
       3: istore_2  
       4: iload_1   //取出位置1的局部變量值入棧
       5: iload_2 
       6: iadd      //加法運算
       7: i2b       //int類型轉化爲byte類型值
       8: istore_3  //彈出棧頂元素存入位置3的局部變量
       9: return
}
複製代碼

JAVA常量操做

1.常量值隱含包含在操做碼內部

操做碼 操做數 備註
iconst_m1 將int類型值-1壓入棧
iconst_0 將int類型值0壓入棧
iconst_1 將int類型值1壓入棧
iconst_2 將int類型值2壓入棧
iconst_3 將int類型值3壓入棧
fconst_0 將float類型值0壓入棧
fconst_1 將float類型值1壓入棧
fconst_2 將float類型值2壓入棧
lconst_0 將long類型值0壓入棧
lconst_1 將long類型值1壓入棧
dconst_0 將double類型值0壓入棧
dconst_1 將double類型值1壓入棧
aconst_null 將空(null)對象壓入棧

2.常量值在字節碼中跟隨操做碼以後

操做碼 操做數 備註
bipush 一個byte類型的數 將byte類型的數轉換爲int類型的數,而後壓入棧
sipush 一個short類型的數 將short類型的數轉換爲int類型的數,而後壓入棧

3.從常量池中取出常量

操做碼 操做數 備註
ldc 無符號8位數indexbyte 從由indexbyte指向的常量池入口中取出一個字長的值,而後將其壓入棧
ldc_w 無符號16位數indexshort 從由indexbyte指向的常量池入口中取出兩個字長的值,而後將其壓入棧

JAVA通用棧以及局部變量的操做

1.通用棧操做

操做碼 操做數 備註 Demo
nop 不作任何操做 前:...,word
後:...,word,word
pop 從操做數棧彈出棧頂部一個字 前:...,word
後:...
pop2 從棧頂數彈出最頂端的兩個字
swap 交換棧頂部的兩個字 前:...,word2,word1
後:...,word1,word2
dup 複製棧頂部的一個字
dup2 複製棧頂部的兩個字
dup2 複製棧頂部的兩個字
dup_x1 複製棧頂部的一個字,
將複製內容以及原來彈出的兩
個字長的內容壓入棧
前:...,word2,word1
後:...,word1,word2,word1
dup_x2 複製棧頂部的一個字,
將複製內容以及原來彈出的三
個字長的內容壓入棧
前:.,word3,word2,word1
後:.,word1,word3,word2,word1
dup2_x1 複製棧頂部的兩個字,
將複製內容以及原來彈出的三
個字長的內容壓入棧
dup2_x2 複製棧頂部的兩個字,
將複製內容以及原來彈出的四
個字長的內容壓入棧

2.局部變量壓入棧

1.將一個字長的局部變量壓入棧

操做碼 操做數 備註
iload vindex 將位置爲vindex的int類型的局部變量壓入棧
iload_0 將位置爲0的int類型的局部變量壓入棧
iload_1 將位置爲1的int類型的局部變量壓入棧
iload_2 將位置爲2的int類型的局部變量壓入棧
iload_3 將位置爲3的int類型的局部變量壓入棧
fload vindex 將位置爲vindex的float類型的局部變量壓入棧
fload_0 將位置爲0的float類型的局部變量壓入棧
fload_1 將位置爲1的float類型的局部變量壓入棧
fload_2 將位置爲2的float類型的局部變量壓入棧
fload_3 將位置爲3的float類型的局部變量壓入棧

2.將兩個字長的局部變量壓入棧

操做碼 操做數 備註
lload vindex 將位置爲vindex和(vindex+1)的long類型的局部變量壓入棧
lload_0 將位置爲0和1的long類型的局部變量壓入棧
lload_1 將位置爲1和2的long類型的局部變量壓入棧
lload_2 將位置爲2和3的long類型的局部變量壓入棧
lload_3 將位置爲3和4的long類型的局部變量壓入棧
dload vindex 將位置爲vindex和(vindex+1)的double類型的局部變量壓入棧
dload_0 將位置爲0和1的double類型的局部變量壓入棧
dload_1 將位置爲1和2的double類型的局部變量壓入棧
dload_2 將位置爲2和3的double類型的局部變量壓入棧
dload_3 將位置爲3和4的double類型的局部變量壓入棧

3.將對象引用局部變量壓入棧

操做碼 操做數 備註
aload vindex 將位置爲vindex的對象引用局部變量壓入棧
aload_0 將位置爲0的對象引用局部變量壓入棧
aload_1 將位置爲1的對象引用局部變量壓入棧
aload_2 將位置爲2的對象引用局部變量壓入棧
aload_3 將位置爲3的對象引用局部變量壓入棧

4.彈出棧頂元素,賦值局部變量

移動一個字長的操做:post

操做碼 操做數 備註
istore vindex 從棧中彈出int類型值,而後存到位置爲vindex的局部變量中
istore_0 從棧中彈出int類型值,而後存到位置爲0的局部變量中
istore_1 從棧中彈出int類型值,而後存到位置爲1的局部變量中
istore_2 從棧中彈出int類型值,而後存到位置爲2的局部變量中
istore_3 從棧中彈出int類型值,而後存到位置爲3的局部變量中
fstore vindex 從棧中彈出float類型值,而後存到位置爲vindex的局部變量中
fstore_0 從棧中彈出float類型值,而後存到位置爲0的局部變量中
fstore_1 從棧中彈出float類型值,而後存到位置爲1的局部變量中
fstore_2 從棧中彈出float類型值,而後存到位置爲2的局部變量中
fstore_3 從棧中彈出float類型值,而後存到位置爲3的局部變量中

移動兩個字長的操做:spa

操做碼 操做數 備註
lstore vindex 從棧中彈出long類型值,而後存到位置爲vindex和(vindex+1)的局部變量中
lstore_0 從棧中彈出long類型值,而後存到位置爲0和1的局部變量中
lstore_1 從棧中彈出long類型值,而後存到位置爲1和2的局部變量中
lstore_2 從棧中彈出long類型值,而後存到位置爲2和3的局部變量中
lstore_3 從棧中彈出long類型值,而後存到位置爲3和4的局部變量中
dstore vindex 從棧中彈出double類型值,而後存到位置爲vindex和(vindex+1)的局部變量中
dstore_0 從棧中彈出double類型值,而後存到位置爲0和1的局部變量中
dstore_1 從棧中彈出double類型值,而後存到位置爲1和2的局部變量中
dstore_2 從棧中彈出double類型值,而後存到位置爲2和3的局部變量中
dstore_3 從棧中彈出double類型值,而後存到位置爲3和4的局部變量中

移動引用的操做: 移動兩個字長的操做:線程

操做碼 操做數 備註
astore vindex 從棧中彈出對象引用,而後存到位置爲vindex的局部變量中
astore_0 從棧中彈出對象引用,而後存到位置爲0的局部變量中
astore_1 從棧中彈出對象引用,而後存到位置爲1的局部變量中
astore_2 從棧中彈出對象引用,而後存到位置爲2的局部變量中
astore_3 從棧中彈出對象引用,而後存到位置爲3的局部變量中

5.wide指令

無符號8位局部變量索引,把方法中局部變量數的限制在256如下。一條單獨的wide指令能夠將8位的索引再擴展8位。跳轉指令並不容許直接跳轉到被wide指令修改過的操做碼。3d

操做碼 操做數 備註
wide iload,index 從局部變量位置爲index的地方取出int類型值,並將其壓入棧
wide lload,index 從局部變量位置爲index的地方取出long類型值,並將其壓入棧
wide fload,index 從局部變量位置爲index的地方取出float類型值,並將其壓入棧
wide dload,index 從局部變量位置爲index的地方取出double類型值,並將其壓入棧
wide aload,index 從局部變量位置爲index的地方取出對象引用,並將其壓入棧
wide istore,index 從棧中彈出int類型值,將其存入位置爲index的局部變量中
wide lstore,index 從棧中彈出long類型值,將其存入位置爲index的局部變量中
wide lstore,index 從棧中彈出long類型值,將其存入位置爲index的局部變量中
wide fstore,index 從棧中彈出float類型值,將其存入位置爲index的局部變量中
wide dstore,index 從棧中彈出double類型值,將其存入位置爲index的局部變量中
wide astore,index 從棧中彈出對象引用,將其存入位置爲index的局部變量中

以上先介紹一部分JAVA字節碼中的一些命令,接下來還有一些方法調用等等指令,下一篇文章給你們介紹下。code

相關文章
相關標籤/搜索