操作數棧管理相關的字節碼指令如下表所示。
0x57 |
pop |
將棧頂數值彈出 (數值不能是long或double類型的) |
0x58 |
pop2 |
將棧頂的一個(long或double類型的)或兩個數值彈出(其它) |
0x59 |
dup |
復制棧頂數值並將復制值壓入棧頂 |
0x5a |
dup_x1 |
復制棧頂數值並將兩個復制值壓入棧頂 |
0x5b |
dup_x2 |
復制棧頂數值並將三個(或兩個)復制值壓入棧頂 |
0x5c |
dup2 |
復制棧頂一個(long或double類型的)或兩個(其它)數值並將復制值壓入棧頂 |
0x5d |
dup2_x1 |
dup_x1 指令的雙倍版本 |
0x5e |
dup2_x2 |
dup_x2 指令的雙倍版本 |
0x5f |
swap |
將棧最頂端的兩個數值互換(數值不能是long或double類型的) |
字節碼指令對應的模板定義如下:
def(Bytecodes::_pop , ____|____|____|____, vtos, vtos, pop , _ ); def(Bytecodes::_pop2 , ____|____|____|____, vtos, vtos, pop2 , _ ); def(Bytecodes::_dup , ____|____|____|____, vtos, vtos, dup , _ ); def(Bytecodes::_dup_x1 , ____|____|____|____, vtos, vtos, dup_x1 , _ ); def(Bytecodes::_dup_x2 , ____|____|____|____, vtos, vtos, dup_x2 , _ ); def(Bytecodes::_dup2 , ____|____|____|____, vtos, vtos, dup2 , _ ); def(Bytecodes::_dup2_x1 , ____|____|____|____, vtos, vtos, dup2_x1 , _ ); def(Bytecodes::_dup2_x2 , ____|____|____|____, vtos, vtos, dup2_x2 , _ ); def(Bytecodes::_swap , ____|____|____|____, vtos, vtos, swap , _ );
pop指令將棧頂數值彈出。對應的匯編代碼如下:
add $0x8,%rsp
pop2指令將棧頂數值彈出。對應的匯編代碼如下:
add $0x10,%rsp
dup指令復制棧頂數值並將復制值壓入棧頂。對應的匯編代碼如下:
mov (%rsp),%rax push %rax
swap指令將棧最頂端的兩個數值互換(數值不能是long或double類型的)。對應的匯編代碼如下:
mov 0x8(%rsp),%rcx mov (%rsp),%rax mov %rcx,(%rsp) mov %rax,0x8(%rsp)
指令的執行邏輯比較簡單,這里不再過多介紹。
推薦閱讀:
第2篇-JVM虛擬機這樣來調用Java主類的main()方法
第13篇-通過InterpreterCodelet存儲機器指令片段
第20篇-加載與存儲指令之ldc與_fast_aldc指令(2)
第21篇-加載與存儲指令之iload、_fast_iload等(3)