riss:
下面这些函数从字节码中提取对应类型的值:
代码
//this.b是字节码数组
public int readInt (final int index) {
byte[] b = this.b;
return ((b[index] & 0xFF) << 24) |
((b[index + 1] & 0xFF) << 16) |
((b[index + 2] & 0xFF) <<
|
(b[index + 3] & 0xFF);
}
public short readShort (final int index) {
byte[] b = this.b;
return (short)(((b[index] & 0xFF) <<
| (b[index + 1] & 0xFF));
}
public long readLong (final int index) {
long l1 = readInt(index);
long l0 = readInt(index + 4) & 0xFFFFFFFFL;
return (l1 << 32) | l0;
}
.......
就拿readInt来说:
代码
public int readInt (final int index) {
byte[] b = this.b;
return ((b[index] & 0xFF) << 24) |
((b[index + 1] & 0xFF) << 16) |
((b[index + 2] & 0xFF) <<
|
(b[index + 3] & 0xFF);
}
问题1:b[index]&0xFF有啥意义(11100111&11111111=11100111)与0xFF不是多此一举吗?
问题2:
第一种理解(还算说的过去):(b[index] & 0xFF) << 24,(11100111<<24=00000000)这里要说的是左移24位--根据我的理解--b[index] & 0xFF的结果首先放入一个整形变量中(应该说是压入这个方法的栈帧中),左移24位就放在最高的一个字节,这样就得到这个整形值的最高的一个字节(XXXXXXXXXXXXXXXXXXXXXXXX11100111<<24=11100111000000000000000000000000),依次类推(左移16,8,0位)后把他们的值相"或"就可以得到一个完整的整形值并放入retrunaddress指向的区域.
第二种理解(说不过去):b[index] 是字节类型,那么b[index] & 0xFF结果类型该是字节类型,左移24位等于什么(00000000),所以让我疑惑的是JVM怎么知道把(b[index] & 0xFF)的结果放入一个整形大小的区域呢?
问题3:此问题与主题不相关,在<深入Java虚拟机>中说到可以(按它说的)得到版本号,可我把我的类文件打开看这些字节确是"0000 002E",如何解释?
那位兄弟可以帮我解开这个迷团,谢谢!
------------------------------------------------------------------------------------------------------------------------------------------
zgli:
代码
int result=0;
int tmp=b[index];
tmp=tmp<<24;
tmp=tmp&0xFF000000;
result=result+tmp;
tmp=b[index+1];
tmp=tmp<<16;
tmp=tmp&0x00FF0000;
result=result+tmp;
tmp=b[index+2];
tmp=tmp<<8;
tmp=tmp&0x0000FF00;
result=result+tmp;
tmp=b[index+3];
tmp=tmp&0x000000FF;
result=result+tmp;
同意否?
------------------------------------------------------------------------------------------------------------------------------------------
riss:
这里很明显,tmp就是整形变量,byte转向int类型是理所当然的。
在这里,b[index]&0xFF完全可在存储在一个字节的大小的区域里(8bit)那么现在就是说为什么它知道强制放在4字节的区域里(int:32bit).(把tmp改为byte类型照常工作,只是结果不正确罢了!).再对比,readShort和readLong,这个说法好像是说不过去。
------------------------------------------------------------------------------------------------------------------------------------------
zgli:
java 的位运算符最小工作在int下啊,这好象是规定
代码
byte a=23;
byte b=a & 0xFF;
在eclipse下提示:Type mismatch: cannot convert from int to byte
说明 a & 0xFF 的结果是整数
其他的问题也就不用说的
有了这个结论另两个就合理了
------------------------------------------------------------------------------------------------------------------------------------------
dwangel:
因为0xff是整型,
byte[] aa;
aa[index] & 0xff 向大的数据类型靠拢,就是整型了。
------------------------------------------------------------------------------------------------------------------------------------------
dazuiba:
1 .java中的byte 是sign的
2 所以 将一个负byte强制转换成int,就会损坏原来的binary表示,例如:
byte bb=(byte) 0xf1; //11110001
printBinary((int)bb);//11111111111111111111111111110001
所以要用0xff操作一下, readInt(index + 4) & 0xFFFFFFFF; 同样的道理
3 因为2,所以你程序中的第一个byte可以强制转换为int,而结果不会收到影响
4 要转为int的原因是你的返回值是int,而不是因为jvm默认int.
-----------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------
riss:
看了这么多,终于明白了,谢谢各位的帮忙。
基础不扎实,学的全还给老师了。
那么问题3,对于明白的该不是什么问题吧!只是看书上的好像不正确,是不是Java更新换代了,这个的解析方法也变了?
再次感谢!谢谢!
------------------------------------------------------------------------------------------------------------------------------------------
riss:
问题3已经解决。但是想不明白,为什么要这样规定:
1.1的前面两字节是3而1.2以后的版本都是0。这个谁可以解释来听听啊!想不通!要不一真沿用3,要不一开始就弄成0不好吗?
什么乱七八糟的!sun不知天天在想些什么?也许是我误解,但是还是想了解一下是怎么个回事?
分享到:
相关推荐
- **说明**:此函数可以从混合文本中提取所有数字。 - **应用场景**:适用于从订单编号、产品编码等字符串中提取数字部分。 5. **函数作用:从形如"ABCD12455EDF"的字符串中取出数字** - **说明**:与第4个函数...
- **函数描述**:根据指定的分隔符类型,从给定的范围名称中提取起始位置。 - **应用场景**:在处理Excel中的范围名称时,可以用来解析这些名称以获取有用的信息。 #### 7. 函数作用:将金额数字转成中文大写 - **...
函数作用:提取定串中汉字...........................81 '64.函数作用:搜索重复数据(选定范围)...................81 '65.函数作用:字符型转数字型...........................82 '66.函数作用:小写人民币转大写...
这类函数能够从包含字母和数字的字符串中精确提取数字部分,适用于各种需要解析复杂数据格式的场景,如订单号、账号等。 #### 5. 同上,但针对不同格式的字符串 与前一个函数类似,但针对不同结构的字符串,提供了...
50.对多个用同一分隔符分隔的待查找元素,逐一在表区域首列内搜索,将返回选定单元格的值相加,相当于多个vlookup函数相加,对于查找不到的元素在批注中添加,以提醒用户。 51.根据个人所得税(工资)反算工资数 52....
- **解释**:这些操作是实现复杂查询的基础,能够帮助用户从数据库中提取所需的信息。 ### 15. 控件选择 - **控件类型**:`RadioButtonList`适合用于表示互斥的选择项,如性别或婚姻状态。 - **优点**:可以方便地...
- **描述**: 计算机硬件中的一种缓存类型,位于主内存和处理器之间,用于提高数据访问速度。 ### 27. 辅助存储器 (2次記憶) - **中文**: 辅助存储器 - **描述**: 除了主内存之外的其他存储设备,如硬盘驱动器、光盘...
- **用途**:编译是将源代码转换为机器码或字节码的过程。Java程序通常需要经过编译才能运行。 #### Compilation n. 编辑 [,k.mpi'lei..n] - **中文释义**:编译 - **用途**:与“compile”含义相同,特指将源代码...
可能包括编码规则的定义、字符串处理函数以及用于嵌入和提取水印的辅助函数。 在实际应用中,这一实现可能涉及到以下步骤: 1. 将原始文本(包括中文)转换为莫斯代码。 2. 使用加密算法对莫斯代码进行处理,提高...
- **定义**: 从输入中提取有意义的信息。 - **示例**: 识别变量名。 **2.9 标识符 (Identifier)** - **定义**: 用于标识变量、函数等的名字。 - **示例**: 变量名 “x”。 **2.10 分析 (Analyses)** - **定义**: ...
- 使用`SUBSTR`函数从字符串中提取子串,结合`LEFT`和`RIGHT`函数可以从字符串的不同位置提取特定长度的子串。 #### 文件属性查看 - 在Windows操作系统中,不能直接通过文件属性查看文件的具体内容,如字数和行数等...
19. **函数返回类型**:在C语言中,如果没有显式指定函数的返回类型,默认情况下该函数的返回类型为`int`。 #### 硬盘存储容量 20. **硬盘存储容量**:20GB的硬盘表示其存储容量大约为200亿个字节(20 × 1024 × ...
- **应用场景**:在软件开发过程中,实际参数是指在函数调用时传递的真实值,区别于形式参数。 #### 3. Adapter 适配器 - **定义**:适配器是一种硬件或软件组件,用于使不兼容的接口之间能够相互通信。 - **应用...
- **应用场景**:例如,如果想要知道某个表中有多少条记录,或者满足某种条件的记录数量,就可以使用`COUNT`函数。 ### 9. Java 中的十六进制赋值 - **知识点**:在Java中,要将一个十六进制值赋给一个`long`型...
- **解析**: 选择、投影和连接是关系数据库中最常见的三种特殊运算,它们用于从数据库中提取所需的数据。 #### 22. 输入掩码的使用 - **知识点**: 输入掩码是用于指导用户输入数据的一种方式。 - **解析**: 掩码...
特征码,全称代码特征码,是通过特定算法从二进制程序中提取的一段具有唯一性的标识符。这些标识符可以是连续的字节序列或经过某种模式匹配得到的非连续字节组合。在恶意软件检测领域,特征码常被用来识别已知的病毒...
- 文件:Linux中的文件被视为无结构的字符流形式,存储在某种介质上。 - 文件名:由字母、数字、下划线和圆点组成,长度限制在255个字符以内。 - 扩展名:用于分类文件,例如 `.txt` 表示文本文件。 - **文件类型...
7. **实战经验**:通过实践,逐步熟悉WASM模块的运行流程,如何从代码中提取有用信息,以及如何利用这些信息来解决问题。 在"京麒CTF2024-Re-easy-wasm"的挑战中,参与者可能需要下载并分析`index.html`和`static`...