- 浏览: 848225 次
- 性别:
- 来自: 南京
文章分类
最新评论
-
loveseed1989:
您好,我用您的方法运行Cone.java,会给我报java.l ...
vtk学习笔记 --- 编译vtk库和java库 -
60love5:
60love5 写道首先谢谢你的解析,但你这个验证可见性的小程 ...
多线程中共享对象的可见性 -
60love5:
首先谢谢你的解析,但你这个验证可见性的小程序是存在问题的,你的 ...
多线程中共享对象的可见性 -
Gamehu520:
...
java 中的Unsafe -
shanpao1234560:
这个list不是静态的第一种情况下也会有线程安全的问题么,求指 ...
一个看似线程安全的示例
3方法
这一章节将解释如何使用ASM核心API生成和转换编译后的方法。首先介绍编译后的方法的表现形式,然后介绍相关的ASM接口,组件以及工具,结合很多说明性的示例讲解如何生成和转换方法。
3.1结构
在编译后的类中,方法的代码是以字节码指令序列保存的。为了生成和转换这些类,我们必须了解这些指令以及它们如何工作。这个章节将粗略的讲解一下这些指令,但是这已足够我们去编写一些简单的类(我认为这里应该是方法)生成工具和转换工具。如果希望查看这些指令的完整定义,请参看java虚拟机规范。
3.1.1执行模型
在介绍字节码指令之前,需要先介绍一下java虚拟机的执行模型。如你所知,java代码是在线程中被执行的。每个线程都有它自己的执行栈,这个栈由很多帧组成。每个帧代表了一个方法调用:每当一个方法被调用时,就会创建一个新的帧,然后将这个帧放到当前线程的执行栈的栈顶。当这个方法正常返回时,或者发生了异常,这个帧就会从执行栈顶弹出,然后虚拟机会接着执行下一个位于执行栈栈顶的帧。
每个帧都包含两部分:一个局部变量区和一个操作数栈区。局部变量区包含了方法中定义的局部变量,可以通过索引值来随即访问。操作数栈区,如它的名字暗示,它是一个包含操作数的栈,这些数据被字节码指令所使用。这意味着这个栈中的数据只能以后进先出的顺序访问。注意,不要把操作数栈和线程的执行栈混淆:在执行栈中的每个帧都包含它自己的操作数栈。
局部变量区和操作数栈的大小是由方法中的代码决定的。它们的大小是在编译时计算的,然后随着字节码指令一起存储在编译后的类中。结果是,对同一个方法的调用的所有帧的局部变量和操作数栈大小都相同,不同的方法调用的帧的局部变量和操作数栈大小不同。
图3.1 一个包含3个帧的执行栈
图3.1展示了一个简单执行栈,包含3个帧。第一个帧包含3个局部变量,操作数栈大小为4,包含2个值。第二个帧包含2个局部变量,操作数栈中包含2个值。第三个帧位于执行栈的栈顶,包含4个局部变量和2个操作数。
当帧被创建的时候,操作数栈初始化为空,局部变量包含当前对象的引用this(非静态方法)以及方法的参数。例如a.equals(b)会创建一个帧,它包含一个空的操作数栈,第一个和第二个局部变量为a和b(其它的局部变量未被初始化)。
局部变量区和操作数栈区的每一个插槽(图3.1中的方框)都能存储java中的任何值,除了long型和double型的值。因为long和double值需要2个插槽,这增加了局部变量管理的复杂性:例如ith 方法的参数就没必要保存在局部变量i中(有疑问)。Math.max(1L,2L)会创建一个帧,第一个局部变量值为1L,占用前两个插槽,第二个局部变量值为2L,占据第三个和第四个插槽。
3.1.2字节码指令
一个字节码指令由一个指示指令的操作码和固定数量的参数:
- opcode是一个无符号字节数值 – 字节码的名称是由助记符表示。例如,操作码0的助记符为NOP,其对应的指令不做任何事情。
- 参数都是静态的值,定义了精确的指令行为。它们放置在操作码之后。例如,GOTO标签指令,它的操作码是167,需要一个参数label,这个label指定了下一条将被执行的指令。在这里不要将指令参数和指令操作数混淆:这里的参数是静态已知的并且被保存在编译后的代码中,而操作数的值来自操作数栈,它们在运行时才可知。
字节码指令可以划分为两类:将局部变量的值传递到操作数栈的一小部分指令集,另外一部分指令在操作数栈上进行操作:它们取得栈顶上的一些数据,进行计算,获得结果,然后将结果放回栈顶。
ILOAD,LLOAD,FLOAD,DLOAD和ALOAD指令读取一个局部变量的值,然后将它放置到操作数栈,这些指令的参数就是需要读取的局部变量的索引值i。ILOAD被用来加载一个boolean,char,short以及int局部变量。LLOAD,FLOAD和DLOAD用来加载long,float或者double值,注意LLOAD和DLOAD实际加载了i和i+1插槽上的值。最后,ALOAD是用来加载那些非基本类型的值,如对象和数组引用。相对地,ISTORE,LSTORE,FSTORE,DSTORE和ASTORE指令是用来从操作数栈取得相应的数据然后保存会局部变量,它们的参数也是索引值i。
如你前面所见,XLOAD和XSTORE指令是区分类型的(事实上,包括你即将在下面看到的,几乎所有的指令都是区分类型的)。这样做主要是为了确保不进行非法的类型转换。当然,以不同的类型从局部变量中加载一个值也是合法的。例如,ISTORE 1 ALOAD 1这样的序列是合法的。当然,允许保存一个任意的内存地址到一个索引为1局部变量中,然后转换这个地址为一个对象引用。能够以不同于当前存储在局部变量中的类型来保存到另一个变量中,这样做是很完美的。这意味着一个局部变量的类型,或者存储在这个局部变量中值的类型,可以在方法的执行过程中改变。
如上面所说,其它的指令都是仅针对操作数栈进行操作的。它们可以分为以下几类(参看附录A.1):
Stack 这些指令是用来操作栈中的数据:POP弹出栈顶的数据,DUP复制栈顶的数据然后放回栈顶,SWAP交换位于栈顶上的两个数据。
Constants 这些指令用来将一个常量值放置到操作数栈:ACONST_NULL放置null值到栈顶,ICONST_0放置int类型的0到栈顶,FCONST_0放置float类型的0值到栈顶,DCONST_0放置double类型的0值,BIPUSH b放置字节值b到栈顶,SIPUSH s放置short类型的值s到栈顶。LDC cst放置int,float,long,double,String或者class类型的常量cst到栈顶。
算术和逻辑操作 这些指令从操作数栈弹出数值进行计算,然后将结果放回栈顶。它们没有任何参数。XADD,xSUB,Xmul,xDIV,和xREM与算术操作符+,-,*,/和%对应,这里的x为I,L,F或者D。同样地,这里还包含其它的指令,如<<,>>,|,&,^等针对int和long值的指令。
Casts 这些指令从栈弹出一个数据,然后将其转换为另外一个类型,然后返回栈顶。它们与java中的类型转换对应。I2F,F2D,L2D等,将数值从一种类型转换为另外一种类型。CHECKCAST t转换一个引用值类型为t。
Objects 这些指令是用来创建对象,以及锁定对象,测试它们的类型等。例如,NEW type指令创建一个新对象,然后放回栈(type表示内部名称)。
Fields 这些指令用来读取或者写入字段的值。GETFIELD owner name desc弹出一个对象的引用,然后将该对象字段名称为name的值放置到栈中。PUTFIELD owner name desc从栈中弹出一个值和一个对象引用,然后将这个值保存到这个对象的name字段中。在这两种情形中,对象必须是owner类型,它的字段必须是desc描述的类型。GETSTATIC和PUTSTATIC指令与上面指令类型,只是它们用作静态字段。
Methods 这些指令用来调用方法或者构造方法。它们从栈顶弹出方法的参数,以及目标对象,然后将方法执行结果放回栈顶。INVOKEVIRTUAL owner name desc调用类型为owner 方法名为name,并且方法描述符为desc的方法。INVOKESTATIC用来调用静态方法。INVOKESPECIAL用来调用私有方法和构造方法。INVOKEINTERFACE用来调用定义在接口中的方法。
Arrays 这些指令用来读取和写入数组中的值。xALOAD指令从栈上弹出一个索引值和一个数组,然后将索引值所对应的数组元素放回栈。xSTORE指令从站上弹出一个值,一个索引以及一个数组,然后将值保存到索引对应的数组元素中。这里的x可以是I,L,F,D或者A,也可以是B,C或者S。
Jumps 这些指令在某些条件为真或者为假的时候,跳转到任意一条指令。它们是用来编译if,for,do,while,break和continue等指令的。例如,IFEQ label 从栈上弹出一个int值,如果这个值为0,就跳转到label表示的指令(否则执行流程将按正常流程执行下一条指令)。这里还有其它的一些跳转指令,如IFNE,或者IFGE等。最后,TABLESWITCH和LOOKUPSWITCH指令与java中的switch对应。
Return xRETURN和RETURN指令是用来终止一个方法的执行,并将结果返回给调用者。RETURN针对无返回值的方法,而xRETURN针对其它有返回值的方法。
发表评论
-
基于Oracle Streams + Oracle AQ 捕获变更,发布变更(二)
2014-11-21 22:23 3216要求:使用Oracle Streams捕获某个用户下部 ... -
基于Oracle Streams + Oracle AQ 捕获变更,发布变更(一)
2014-11-20 22:23 2806要求:使用Oracle Streams捕获某个用户下部分表 ... -
如何去掉在浏览器中打开java applet时的警告对话框
2013-08-24 12:10 6999好久没更新博客了! 最近,由于项目要求,需要将sw ... -
Android 内存泄露笔记
2013-03-05 23:10 01、大部分内存泄露都是错误的持有了Activity或者Con ... -
java 虚拟机总结 【思维导图】
2012-12-22 20:11 2098java虚拟机总结思维导图: 参考《深入理解jav ... -
Java虚拟机字节码执行引擎 【思维导图】
2012-12-22 19:51 1691java虚拟机字节码执行引擎思维导图总结: 参考《深入理 ... -
java 垃圾回收相关总结 【思维导图】
2012-12-21 19:03 3289java垃圾回收相关总结: 参考《深入理解java ... -
java并发中的延迟初始化
2012-12-12 19:17 4709在《java并发编程实战 ... -
java同步容器与并发容器
2012-12-09 18:07 4365何为同步容器:可以简 ... -
一个看似线程安全的示例
2012-12-09 14:56 5083在《java并发编程实战》第四章4.4.1节给出了一个程序示 ... -
多线程中的long和double
2012-12-08 19:26 4210在看一些代码的时候,会发现在定义long型和double型的 ... -
多线程中共享对象的可见性
2012-12-08 18:52 5161在阅读《java并发编程实战》的第三章的时候,看到书中的一个 ... -
一个快速、轻量级 Collection 库 Trove
2012-12-07 09:35 3769Trove一个快速、轻量级针对java原子类型(byte,i ... -
java 中的Unsafe
2012-12-05 22:25 32764在阅读AtomicInteger的源码时,看到了这个类:su ... -
在ubuntu10上编译Thrift0.8.0
2012-08-01 15:34 2161下载thrift0.8.0 ,地址: http:// ... -
生活小工具--记账小助手1.0发布
2012-05-31 15:08 1762因为自己平时喜欢记账,把每日的消费情况都记录下来,所以希望找 ... -
话费速查升级版v1.3发布
2012-05-04 12:47 1443前段时间开发了一个话费速查的小应用,最近一直保持每周更新一个 ... -
编译zeromq的java绑定:jzmq
2012-05-03 22:47 135521、 下载zeromq源码:http://www.ze ... -
Android软件包静默安装小应用 - 附源码
2012-04-21 20:50 12424老早之前,写了一个android软件包静默安装的应用,放在工 ... -
最方便的联通话费,余额查询软件来了! --- 联通话费速查v1.2
2012-04-12 18:01 4049软件介绍: 联通话费速查是一款针对联通 ...
相关推荐
### ASM3.0指南翻译——深入理解Java字节码引擎库 #### 1. 引言与背景 在软件开发领域,程序分析、生成及转换技术的应用极为广泛,覆盖从语法解析到语义分析,再到代码优化、混淆、调试、性能监控及面向切面编程等...
根据提供的文件信息,以下是关于“ASM4使用指南.pdf”文档中所提及知识点的详细介绍: 1. ASM库介绍: ASM(Java字节码操作和分析框架)是一个Java字节码操作与分析框架。它被设计用于直接以类文件的形式读写和修改...
根据给定的文件信息,我们可以提炼出以下几个关键的知识点,主要围绕着ASM30-LINK30和实用程序用户指南,以及Microchip Technology Inc.的相关信息进行深入解析: ### 1. 微芯科技(Microchip Technology Inc.)...
在压缩包中的"读我.txt"文件,很可能是C32Asm的使用指南或注意事项,它可能包含了安装步骤、配置选项、命令行参数以及一些使用技巧。而"c32asm"可能是个可执行文件,即C32Asm工具本身,或者是一个示例文件,用于演示...
《汇编程序员之代码风格指南》,此书是我自己翻译的中文版,网上已有很多 地方可下载,学习汇编语言而不注意编码风格是很吃亏的事,此书能教你什么时候 该做什么,什么时候不应该做什么。良好的编码风格对于win32...
描述中提到的“汉化了的,好用”,意味着这个win32asm工具已经被翻译成了中文,这对于中文用户来说是一个极大的便利,因为它消除了语言障碍,使得不懂英文的开发者也能轻松使用。通常,反汇编器的界面和文档都是英文...
src DCD 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4 dst DCD 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 END ``` 该程序定义了两个缓冲区`src`和`dst`,并通过循环将`src`中的...
本指南由著名的汇编语言专家Randall Hyde撰写,并由jhkdiy翻译成中文版。该指南旨在帮助程序员理解如何提高他们所编写的汇编代码的可读性。书中通过一系列实例来展示常见的问题及其解决方案,这些实例均来自互联网上...
本中文手册是由一位热心人士翻译整理的,其内容主要摘自GNU C编译器的官方文档。手册旨在为用户提供一个简明扼要的GCC使用指南,特别是针对编译器选项的解释。 #### 二、手册重要声明 1. **免责声明**:手册的内容...
- `ReadMe.txt`:通常包含项目说明、使用指南或者注意事项。 - `ConsoleApplication1`:可能是C++编译生成的可执行程序,包含了汇编和反汇编的功能。 - `汇编与反汇编exe`:这可能是最终生成的汇编和反汇编器的可...
- 中文伪指令.txt 可能包含了易语言中的特殊指令,这些指令在易语言中用中文表示,但被翻译为对应的汇编指令。 - 测试代码.txt 包含了一些示例代码,用于测试软件的功能和性能。 - 高级指令.txt 可能介绍了更复杂或...
### Linux 汇编语言开发指南 #### 一、简介 汇编语言作为一种低级语言,在现代编程领域中虽然不如高级语言那样普及广泛,但它在特定场景下的优势不容忽视。尤其是在Linux环境中,汇编语言被用于优化性能敏感的模块...
全部翻译完了,给我的感觉就是这篇文章是为已有汇编基础但从未接触过Windows汇编编程的读者写的,虽然对我来说这些内容很简单,但也觉得说的很详细了,好过国内许多三言两语的所谓菜鸟教程;但如果读者想全面学习Win...
- `PRO/Emenu_translatyesnopro/enno-yes-both` 可能指的是菜单的翻译设置,用户可以根据需要选择中文、英文或者是双语界面。 - `menu_fontARIAL`:指定菜单使用的字体为Arial,确保了软件界面的一致性和可读性。 ...
2. **限制性使用**:根据许可证协议中的规定,用户不得擅自复制、翻译、广播、修改、授权、传输、分发、展示或表演软件的任何部分,除非许可证协议中有明确规定或许可,或者法律允许的情况。 3. **反向工程禁止**:...
在提供的文件列表中,"huibian.doc"可能是关于ASM乐曲程序设计的一个指南或教程,可能详细介绍了如何编写和调试ASM代码以创建音乐程序。而"www.pudn.com.txt"可能是从一个编程讨论论坛或资源网站下载的资料,可能...
2. **Win32汇编编程指南**: - **Win32环境下的开发工具**:介绍用于编写、编译和调试Win32汇编程序所需的工具链。 - **创建Win32汇编应用程序**:讲解如何从零开始构建一个简单的Win32汇编程序。 - **Win32 API...