用反编译理解程序
2006-01-19 15:56
211 查看
用反编译理解程序
以前看过很多汇编高手,在汇编领域学到一定的程度之后,在学习其他语言是,真的能学的更快,理解的更深,比如c, java ,c++ 等等。。。。
我这里也有一个用java自带命令帮助我们理解程序的方法。
下面这段代码是关于(zt)变态java面试题中的第一个,问你下面这段代码#mmm处的运行结果?
我补充了一下,顺便用运行在虚拟机上的代码简单的说明下。
public class TestExamMethod {
public static void main(String[] args){
TestExamMethod instance = new TestExamMethod();
instance.test1();
}
public void test1(){
int x=4;
System.out.println("value is " +((x>4)?99.9:9)); //#mmm
System.out.println("value is " +((x>4)?99:9)); //#nnn
}
}
-------------------------------------------------------------------------------------------------------------
E:/wytest>javap -c TestExamMethod
Compiled from "TestExamMethod.java"
public class test.thinkinjava.TestExamMethod extends java.lang.Object{
public test.thinkinjava.TestExamMethod();
Code:
0: aload_0
1: invokespecial #9; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #2; //class test/thinkinjava/TestExamMethod
3: dup
4: invokespecial #16; //Method "<init>":()V
7: astore_1
8: aload_1
9: invokevirtual #19; //Method test1:()V
12: return
public void test1();
Code:
0: iconst_4
1: istore_1
2: getstatic #28; //Field java/lang/System.out:Ljava/io/PrintStream;
5: new #30; //class java/lang/StringBuffer
8: dup
9: ldc #32; //String value is
11: invokespecial #35; //Method java/lang/StringBuffer."<init>":(Ljava/lan
g/String;)V
14: iload_1
15: iconst_4
16: if_icmple 25
19: ldc2_w #36; //double 99.9d
22: goto 28
25: ldc2_w #38; //double 9.0d
28: invokevirtual #43; //Method java/lang/StringBuffer.append:(D)Ljava/lan
g/StringBuffer;
31: invokevirtual #47; //Method java/lang/StringBuffer.toString:()Ljava/la
ng/String;
34: invokevirtual #52; //Method java/io/PrintStream.println:(Ljava/lang/St
ring;)V
37: getstatic #28; //Field java/lang/System.out:Ljava/io/PrintStream;
40: new #30; //class java/lang/StringBuffer
43: dup
44: ldc #32; //String value is
46: invokespecial #35; //Method java/lang/StringBuffer."<init>":(Ljava/lan
g/String;)V
49: iload_1
50: iconst_4
51: if_icmple 59
54: bipush 99
56: goto 61
59: bipush 9
61: invokevirtual #55; //Method java/lang/StringBuffer.append:(I)Ljava/lan
g/StringBuffer;
64: invokevirtual #47; //Method java/lang/StringBuffer.toString:()Ljava/la
ng/String;
67: invokevirtual #52; //Method java/io/PrintStream.println:(Ljava/lang/St
ring;)V
70: return
}
-----------------------------------------------------------------------------------
主要看test1()方法,先说明下概念:
1、bipush :将8位带符号的整数入栈,但要先将8位扩展为int需要的位数。
2、if_icmple :你可以简单的先理解为if()条件语句。。。
3、iconst_4 :将int类型常量4压入栈
4、iload_1 :从局部变量1中装载int
5、ldc2_w :把常量池中的long/double类型的项压入栈。
其他具体内容你可以查看 《深入Java虚拟机》查找。
借助反编译代码说明源代码运行结果:
System.out.println("value is " +((x>4)?99:9)); //#nnn
他在运行时,99 ---> int 类型,先压入栈 [ bipush 99 ]
然后 9 ----> int 类型 在压入栈 [bipush 9]
当然取出来运行的结果自然是: value is 9
System.out.println("value is " +((x>4)?99.9:9)); //#mmm
他在运行时,99.9 ---> double 类型,先压入栈 [ dc2_w #36; //double 99.9d ]
然后 9----> int类型, 但虚拟机这时将?前后的类型转型,规则和我们写 int + double 时一样。
所以这里 9 ---> 9.0 ---> double类型压入栈,[ ldc2_w #38; //double 9.0d ]
当然取出来运行的结果自然是: value is 9.0
同样,如果我们这是要运行 System.out.println("value is " +((x==4)?99:9.0));
结果应该是99.0 规则同样和 int + double 一样。
在java实现论坛上有10到类试面试题目,这里我个人认为这只是一种分析程序的方法,不过当程序过于庞大复杂时,将不再试用。
以前看过很多汇编高手,在汇编领域学到一定的程度之后,在学习其他语言是,真的能学的更快,理解的更深,比如c, java ,c++ 等等。。。。
我这里也有一个用java自带命令帮助我们理解程序的方法。
下面这段代码是关于(zt)变态java面试题中的第一个,问你下面这段代码#mmm处的运行结果?
我补充了一下,顺便用运行在虚拟机上的代码简单的说明下。
public class TestExamMethod {
public static void main(String[] args){
TestExamMethod instance = new TestExamMethod();
instance.test1();
}
public void test1(){
int x=4;
System.out.println("value is " +((x>4)?99.9:9)); //#mmm
System.out.println("value is " +((x>4)?99:9)); //#nnn
}
}
-------------------------------------------------------------------------------------------------------------
E:/wytest>javap -c TestExamMethod
Compiled from "TestExamMethod.java"
public class test.thinkinjava.TestExamMethod extends java.lang.Object{
public test.thinkinjava.TestExamMethod();
Code:
0: aload_0
1: invokespecial #9; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #2; //class test/thinkinjava/TestExamMethod
3: dup
4: invokespecial #16; //Method "<init>":()V
7: astore_1
8: aload_1
9: invokevirtual #19; //Method test1:()V
12: return
public void test1();
Code:
0: iconst_4
1: istore_1
2: getstatic #28; //Field java/lang/System.out:Ljava/io/PrintStream;
5: new #30; //class java/lang/StringBuffer
8: dup
9: ldc #32; //String value is
11: invokespecial #35; //Method java/lang/StringBuffer."<init>":(Ljava/lan
g/String;)V
14: iload_1
15: iconst_4
16: if_icmple 25
19: ldc2_w #36; //double 99.9d
22: goto 28
25: ldc2_w #38; //double 9.0d
28: invokevirtual #43; //Method java/lang/StringBuffer.append:(D)Ljava/lan
g/StringBuffer;
31: invokevirtual #47; //Method java/lang/StringBuffer.toString:()Ljava/la
ng/String;
34: invokevirtual #52; //Method java/io/PrintStream.println:(Ljava/lang/St
ring;)V
37: getstatic #28; //Field java/lang/System.out:Ljava/io/PrintStream;
40: new #30; //class java/lang/StringBuffer
43: dup
44: ldc #32; //String value is
46: invokespecial #35; //Method java/lang/StringBuffer."<init>":(Ljava/lan
g/String;)V
49: iload_1
50: iconst_4
51: if_icmple 59
54: bipush 99
56: goto 61
59: bipush 9
61: invokevirtual #55; //Method java/lang/StringBuffer.append:(I)Ljava/lan
g/StringBuffer;
64: invokevirtual #47; //Method java/lang/StringBuffer.toString:()Ljava/la
ng/String;
67: invokevirtual #52; //Method java/io/PrintStream.println:(Ljava/lang/St
ring;)V
70: return
}
-----------------------------------------------------------------------------------
主要看test1()方法,先说明下概念:
1、bipush :将8位带符号的整数入栈,但要先将8位扩展为int需要的位数。
2、if_icmple :你可以简单的先理解为if()条件语句。。。
3、iconst_4 :将int类型常量4压入栈
4、iload_1 :从局部变量1中装载int
5、ldc2_w :把常量池中的long/double类型的项压入栈。
其他具体内容你可以查看 《深入Java虚拟机》查找。
借助反编译代码说明源代码运行结果:
System.out.println("value is " +((x>4)?99:9)); //#nnn
他在运行时,99 ---> int 类型,先压入栈 [ bipush 99 ]
然后 9 ----> int 类型 在压入栈 [bipush 9]
当然取出来运行的结果自然是: value is 9
System.out.println("value is " +((x>4)?99.9:9)); //#mmm
他在运行时,99.9 ---> double 类型,先压入栈 [ dc2_w #36; //double 99.9d ]
然后 9----> int类型, 但虚拟机这时将?前后的类型转型,规则和我们写 int + double 时一样。
所以这里 9 ---> 9.0 ---> double类型压入栈,[ ldc2_w #38; //double 9.0d ]
当然取出来运行的结果自然是: value is 9.0
同样,如果我们这是要运行 System.out.println("value is " +((x==4)?99:9.0));
结果应该是99.0 规则同样和 int + double 一样。
在java实现论坛上有10到类试面试题目,这里我个人认为这只是一种分析程序的方法,不过当程序过于庞大复杂时,将不再试用。
相关文章推荐
- Integer示例程序反编译代码的分析,附带“==”的再次理解
- 用反编译理解程序(续)
- 第十四周项目6-阅读程序1(对continue的理解)
- 谈谈自己对“将Python嵌入到C/C++程序,让你的程序的用户获得"脚本化"的能力”一这句话中脚本化的理解
- 纠正以前的错误理解,总以为进程是个划分的很小的一个东西。其实进程和程序的区别不大。
- 白话讲山寨SOA,少一些迷惑、多一些理解,你的程序架构SOA了吗?
- 2013级C++第12周程序阅读项目——理解函数
- 对于c语言存储分配程序(malloc函数)实现的理解
- 【算法】KMP算法超详好懂理解(附全程序模拟过程)
- 深入理解计算机系统读书笔记之一个简单汇编程序的调试分析
- 【理解】如何定时运行程序
- 深入理解计算机系统(第二版)----之一:(一:程序的结构和执行)计算机系统漫游
- C++中虚函数和多态的理解和测试程序
- Android程序反编译、签名详解、打包
- 谁能把这个程序的输出写出来,他对宏的理解就不是很差了!
- 程序员面试宝典13.1的单链表所有程序,包括注释理解
- 深入理解计算机系统学习之程序编译过程
- 深入理解计算机系统--优化程序性能
- 通过反编译一个简单的C程序,解释堆栈的变化
- 第一周:通过汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的