1. 程式人生 > >從java反編譯學習位元組碼指令(一)

從java反編譯學習位元組碼指令(一)

最近沉迷於java反編譯,經常看到iconst_1指令,見得多了,也讓我對它感到很好奇,它是不是就是固定代表int 1啊?

做個小測試,從11到0,看看它們分別對應位元組碼什麼?

public class Bytecode {
    public void ByteCode() {
        int eleven = 11;
        int ten = 10;
        int nine = 9;
        int eight = 8;
        int seven = 7;
        int six = 6;
        int five = 5;
        int four = 4;
        int three = 3;
        int two = 2;
        int one = 1;
        int zero = 0;
    }
}

在JDK1.8.0_151的環境下,使用javac編譯上面的檔案,得到Bytecode.class檔案,然後利用javap反編譯這份位元組碼檔案。

 很有意思,從11到9,用到了istore_1, istor_2, istore_3, 其餘都是istore

從11到6,都是bipush, 從5到0,分別用到了iconst_5, iconst_4, iconst_3, iconst_2, iconst_1, iconst_0

為了排除順序的關係,我們把程式碼調整成這樣:

public class Bytecode {
    public void ByteCode() {
        int zero = 0;
        int one = 1;
        int two = 2;
        int three = 3;
        int four = 4;
        int five = 5;
        int six = 6;
        int seven = 7;
        int eight = 8;
        int nine = 9;
        int ten = 10;
        int eleven = 11; 
    }
}

然後再編譯,反編譯看看結果:

看來,istore_1,istore_2,istore_3是和順序有關,但是iconst_0到iconst_5是精準的對應0到5。

再做個這樣的對比:

public class Bytecode {
    public void ByteCode() {
        int one = 1;
        long lone = 1L;
        byte bone = (byte)1;
        double done = 1.0;
    }
}

編譯,然後反編譯,看看結果。

各自對應都不同,倒是byte被“換成”int讓我對jvm又有了無限的遐想了。

到這裡,基本可以印證了,iconst_1就是對應int 1

【總結】:

iconst_0對應int 0

iconst_1對應int 1

iconst_2對應int 2

iconst_3對應int 3

iconst_4對應int 4

iconst_5對應int 5

lconst_1對應long 1L

【問題】:為什麼不歸納dconst_1對應1.0呢?

【思考】:小夥伴們試試boolean T = true, boolean F = false編譯後對應什麼位元組碼,保證有驚喜哦!^_^

相關推薦

java編譯學習位元組指令

最近沉迷於java反編譯,經常看到iconst_1指令,見得多了,也讓我對它感到很好奇,它是不是就是固定代表int 1啊? 做個小測試,從11到0,看看它們分別對應位元組碼什麼? public class Bytecode { public void ByteCo

Java位元組詳解位元組指令

一、概述 Java虛擬機器採用基於棧的架構,其指令由操作碼和運算元組成。 操作碼:一個位元組長度(0~255),意味著指令集的操作碼個數不能操作256條。 運算元:一條指令可以有零或者多個運算元,且運算元可以是1個或者多個位元組。編譯後的程式碼沒有采用運算元長

vue.js實戰學習——內置指令

name 初始 節點 刪除 html元素 data post 編譯 16px 註:此內容摘抄自:梁灝的《Vue.js實戰》 註:記得要引入vue.js才能運行哦,文章中貼出的代碼直接復制是不行的,html css js 都放在了一起,而且也沒有引用vue.js。 1.v

python程式設計:入門到實踐學習筆記Django入門

  建立應用程式 django專案由一系列應用程式組成,他們協同工作,讓專案稱謂一個整體。首先我們執行命令python manage.py startapp learning_logs。     定義模型 開啟剛剛我們建立的資料夾,並修改mod

java並發學習--線程池

第一個 down holding scheduled class 缺點 有關 maximum 設計 關於java中的線程池,我一開始覺得就是為了避免頻繁的創建和銷毀線程吧,先創建一定量的線程,然後再進行復用。但是要具體說一下如何做到的,自己又說不出一個一二三來了,這大概就是

編譯常見工具及用法

首先把baksmali-1.4.1.jar和smali-1.4.1.jar檔案放到Android sdk安裝路徑下的tools裡面,把apk用WinRAR解壓並提取classes.dex檔案,也放入tools裡面,然後用命令列,cd tools目錄下,輸入Java命令

死磕 java集合之TreeMap源分析

過程 tree structure 有序 準備 紅色 復雜度 繼承 lower 歡迎關註我的公眾號“彤哥讀源碼”,查看更多源碼系列文章, 與彤哥一起暢遊源碼的海洋。 簡介 TreeMap使用紅黑樹存儲元素,可以保證元素按key值的大小進行遍歷。 繼承體系 TreeMap實

死磕 java集合之ConcurrentHashMap源分析

為什麽 取整 http lean else nsf 遷移 fault 運行 開篇問題 (1)ConcurrentHashMap與HashMap的數據結構是否一樣? (2)HashMap在多線程環境下何時會出現並發安全問題? (3)ConcurrentHashMap是怎麽解決

Java方法呼叫的位元組指令學習

Java1.8環境下,我們在編寫程式時會進行各種方法呼叫,虛擬機器在執行這些呼叫的時候會用到不同的位元組碼指令,共有如下五種:

[三] java虛擬機器 JVM位元組 指令集 bytecode 操作 指令分類用法 助記符

上面關於dup的描述摘自 虛擬機器規範,很難理解看起來是非常難以理解的,不妨換一個角度我們知道區域性變數的空間分配分為兩種long 和 double 佔用2個slot  其他佔用一個運算元棧,每個單位可以表示虛擬機器支援的任何的一個數據型別不過運算元棧其實同區域性變數一樣,他也是被組織一個數組, 每個元素的資

8.5java學習筆記8.5 位元組操作javassist

一、javassist   javassist讓我們操作位元組碼更加簡單,它是一個類庫,允許我們修改位元組碼。它允許java程式動態的建立、修改類。   javassist提供了兩個層次的API,基於原始碼級別的和位元組碼級別的。     二、javassist建立類   1.獲取類池

python編譯位元組

如果你曾經寫過或者用過 Python,你可能已經習慣了看到 Python 原始碼檔案;它們的名稱以.Py 結尾。你可能還見過另一種型別的檔案是 .pyc 結尾的,它們就是 Python “位元組碼”檔案。(在 Python3 的時候這個 .pyc 字尾的檔案不太好找了,它在一個名為__pycache__的子目

Android對apk源代的改動--編譯+源代改動+又次打包+簽名【附HelloWorld的改動實例】

str 技術 命令行 文章 color 不同的 pop ogl 方法 最近遇到了須要改動apk源代碼的問題,於是上網查了下相關資料。編寫了HelloWorld進行改動看看可行性,經過實驗證明此方案可行,而且後來也成功用這種方法對目標apk進行了改動,僅僅只是

Java位元組淺析

英文原文連結,譯文連結,原文作者:James Bloom,譯者:有孚 條件語句 像if-else, switch這樣的流程控制的條件語句,是通過用一條指令來進行兩個值的比較,然後根據結果跳轉到另一條位元組碼來實現的。 迴圈語句包括for迴圈,while迴圈,它們的實現方式也很類似,但有一點不同

Java位元組淺析

英文原文連結,譯文連結,原文作者:James Bloom,譯者:有孚 從Java7開始,switch語句增加了對String型別的支援。不過位元組碼中的switch指令還是隻支援int型別,並沒有增加對其它型別的支援。事實上switch語句對String的支援是分成兩個步驟來完成的。首先,將每

零開始學習區塊鏈技術--原始碼編譯比特幣

寫在開始之前,為什麼你一定要學習區塊鏈技術? 技術的變革和迭代一直在飛速發展中,作為有著15年程式開發經驗的我,常常在思考現在的我們到底改如何做,到底應該學習些什麼,才能跟上新的時代變革,保持自身的競爭力,並且能為這個世界帶來更好的改變呢? 答案是,學習

java位元組入門

由於dload_n 只支援0..3, 所以用了dload index 指令。虛擬機器子所以提供dload_n,而不是隻用dload index, 是因為前者只佔用一個位元組,dload_n, 在位元組碼中,分別是0x38,0x39,0x40,0x41.(將在下一節簡要介紹位元組碼指令集),dload指令是

java 位元組操作javassist

用javassist生成一個類(位元組碼檔案) /** * 使用javassist生成一個新的類 * @author L J */ public class JavassistDemo { public static void main(Stri

Java】【Flume】Flume-NG啟動過程源代分析

code extends fix tar top 依據 oid article gif 從bin/flume 這個shell腳本能夠看到Flume的起始於org.apache.flume.node.Application類,這是flume的main函數所在。   m

Django重新學習 驗證註冊

第三方庫 sim imp 4.6 .com alt logs blog log 下載驗證碼第三方庫 pip install django-simple-captcha==0.4.6 Django重新學習 驗證碼註冊(六)