ASMSupport4.6 生成位运算符

Stella981
• 阅读 475

在java中我们经常用到为运算符,我们假设有如下代码:

public static void main(String\[\] args) { String\[\] binary = { "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" }; int a = 3; int b = 6; int c = a | b; int d = a & b; int e = a ^ b; int f = (a ^ 0xFFFFFFFF) & b | a & (b ^ 0xFFFFFFFF); int g = (a ^ 0xFFFFFFFF) & 0xF; System.out.println(" a = " + binary\[a\]); System.out.println(" b = " + binary\[b\]); System.out.println(" a|b = " + binary\[c\]); System.out.println(" a&b = " + binary\[d\]); System.out.println(" a^b = " + binary\[e\]); System.out.println("~a&b|a&~b = " + binary\[f\]); System.out.println(" ~a = " + binary\[g\]); }

那么我们用asmsupport生成上面的字节码的代码如下

package example.operators;

import org.objectweb.asm.Opcodes;

import jw.asmsupport.block.method.common.StaticMethodBody; import jw.asmsupport.clazz.AClass; import jw.asmsupport.clazz.AClassFactory; import jw.asmsupport.creator.ClassCreator; import jw.asmsupport.definition.value.Value; import jw.asmsupport.definition.variable.LocalVariable;

import example.AbstractExample;

public class BitwiseOperatorGenerate extends AbstractExample {

/**
 * @param args
 */
public static void main(String[] args) {
    
    ClassCreator creator = new ClassCreator(Opcodes.V1_5, Opcodes.ACC_PUBLIC , "generated.operators.BitwiseOperatorGenerateExample", null, null);
    
    /*
     * 生成一个main方法,方法内容和main1内容相同
     */
    creator.createStaticMethod("main", new AClass[]{AClassFactory.getProductClass(String[].class)}, new String[]{"args"}, null, null,
            Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, new StaticMethodBody(){

        @Override
        public void generateBody(LocalVariable... argus) {
            /*String binary[] = {
              "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
              "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"
            };*/
            LocalVariable binary = createArrayVariable("binary", AClassFactory.getArrayClass(String[].class), false, 
                    newArrayWithValue(AClassFactory.getArrayClass(String[].class), stringValueArray(new String[]{
                      "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
                      "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"})));
            //int a = 3; 
            LocalVariable a = createVariable("a", AClass.INT_ACLASS, false, Value.value(3));
            
            //int b = 6; 
            LocalVariable b = createVariable("b", AClass.INT_ACLASS, false, Value.value(6));
            
            //int c = a | b;
            LocalVariable c = createVariable("c", AClass.INT_ACLASS, false, this.bitOr(a, b));
            
            //int d = a & b;
            LocalVariable d = createVariable("d", AClass.INT_ACLASS, false, this.bitAnd(a, b));
            
            //int e = a ^ b;
            LocalVariable e = createVariable("e", AClass.INT_ACLASS, false, this.bitXor(a, b));
            
            //int f = (~a & b) | (a & ~b);
            LocalVariable f = createVariable("f", AClass.INT_ACLASS, false, bitOr(bitAnd(inverts(a), b), bitAnd(a, inverts(b))));
            
            //int g = ~a & 0x0f;
            LocalVariable g = createVariable("g", AClass.INT_ACLASS, false, this.bitAnd(inverts(a), Value.value(0x0f)));
            
            //System.out.println("        a = " + binary[a]);
            invoke(systemOut, "println", append(Value.value("        a = "), arrayLoad(binary, a)));
            
            //System.out.println("        b = " + binary[b]);
            invoke(systemOut, "println", append(Value.value("        b = "), arrayLoad(binary, b)));
            
            //System.out.println("      a|b = " + binary[c]);
            invoke(systemOut, "println", append(Value.value("      a|b = "), arrayLoad(binary, c)));
            
            //System.out.println("      a&b = " + binary[d]);
            invoke(systemOut, "println", append(Value.value("      a&b = "), arrayLoad(binary, d)));
            
            //System.out.println("      a^b = " + binary[e]);
            invoke(systemOut, "println", append(Value.value("      a^b = "), arrayLoad(binary, e)));
            
            //System.out.println("~a&b|a&~b = " + binary[f]);
            invoke(systemOut, "println", append(Value.value("~a&b|a&~b = "), arrayLoad(binary, f)));
            
            //System.out.println("       ~a = " + binary[g]);
            invoke(systemOut, "println", append(Value.value("       ~a = "), arrayLoad(binary, g)));
            
            runReturn();
        }
    });
    generate(creator);
}

public static Value[] stringValueArray(String[] strs){
    Value[] vals = new Value[strs.length];
    for(int i=0; i<vals.length; i++){
        vals[i] = Value.value(strs[i]);
    }
    return vals;
}

}

这里我们主要关注下面这几行代码:

LocalVariable c = createVariable("c", AClass.INT\_ACLASS, false, this.bitOr(a, b))

这段代码的作用是创建一个名为”c”的int类型的变量,并且将a和b做或(|)运算的结果保存到这个变量。

LocalVariable d = createVariable("d", AClass.INT\_ACLASS, false, this.bitAnd(a, b));

这段代码的作用是创建一个名为”d”的int类型的变量,并且将a和b做与(&)运算的结果保存到这个变量。

LocalVariable e = createVariable("e", AClass.INT\_ACLASS, false, this.bitXor(a, b));

这段代码的作用是创建一个名为”e”的int类型的变量,并且将a和b做异或(^)运算的结果保存到这个变量。

LocalVariable f = createVariable("f", AClass.INT\_ACLASS, false, bitOr(bitAnd(inverts(a), b), bitAnd(a, inverts(b))));

这段代码的作用是创建一个名为”f”的int类型的变量,至于他的值,稍微复杂点,不过也是运算上多几个步骤,他是先将a取反(~),再和b做与(&)操作获得结果1;再将a和取反(~)后的b做与(&)操作得到结果2,然后再将结果1和结果2做或(^)操作将结果赋予f,对应的java代码就是~a&b|a&~b

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
AndroidStudio封装SDK的那些事
<divclass"markdown\_views"<!flowchart箭头图标勿删<svgxmlns"http://www.w3.org/2000/svg"style"display:none;"<pathstrokelinecap"round"d"M5,00,2.55,5z"id"raphael
Wesley13 Wesley13
2年前
thinkphp3.2.3模板渲染支持三元表达式
thinkphp3.2.3模板渲染支持三元表达式{$status?'正常':'错误'}{$info'status'?$info'msg':$info'error'}注意:三元运算符中暂时不支持点语法。如下:           <divclass"modalhidefade"id'myModa
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这