就在我虽然对 Java 如何将所有整数/字节等视为有符号数字有一定的了解时,它又用另一个曲线球击中了我,让我思考我是否真的了解这种处理方式。
这是一段汇编代码,如果满足条件(确实满足),它应该跳转到一个地址。PC 就在跳转之前C838h,然后在条件检查之后,它应该是:C838h + FCh(h = hex),我认为它会被视为有符号,因此 PC 会向后跳转:FCh = -4 in two's compliment negative number。但令我惊讶的是,java ADDED FCh 到 PC 使其错误地跳转到C934h而不是返回到C834h.
C832: LD B,04 06 0004 (PC=C834)
C834: LD (HL), A 77 9800 (PC=C835)
C835: INC L:00 2C 0001 (PC=C836)
C836: JR NZ, n 20 00FC (PC=C934)
Run Code Online (Sandbox Code Playgroud)
我在 Java 代码中对此进行了测试,结果确实相同:
int a = 0xC838;
int b = 0xFC;
int result = a + b;
System.out.printf("%04X\n", result); //prints C934 (incorrect)
Run Code Online (Sandbox Code Playgroud)
为了解决这个问题,我必须在检查第一位是否为 1 后将 FCh 转换为一个字节,它是: 11111100
int a = 0xC838;
int b = (byte) 0xFC;
int result = a + b;
System.out.printf("%04X\n", result); //prints C834 (correct)
Run Code Online (Sandbox Code Playgroud)
简而言之,我想我的问题是我认为 java 会知道 FCh 是一个负数,但情况并非如此,除非我将它转换为一个字节。为什么?对不起,我知道这个问题被问了很多次,我自己似乎也问了很多。
0xfc是一个正数。如果你想要一个负数,那么写一个负数。-0x4会做的很好。
但是,如果您想将其应用于非常量数据,则需要告诉 Java 您希望以某种方式对其进行符号扩展。
问题的核心是您有一个 32 位有符号整数,但您希望将其视为 8 位有符号整数。实现这一目标的最简单方法就是byte像上面那样使用。
如果你真的不想写byte,你可以写(0xfc << 24) >> 24:
class Main
{
public static void main(String[] args)
{
int a = 0xC838;
int b = (0xfc << 24) >> 24;
int result = a + b;
System.out.printf("%04X\n", result);
}
}
Run Code Online (Sandbox Code Playgroud)
(24源自int(32 位)和byte(8 位)的大小差异)。
| 归档时间: |
|
| 查看次数: |
67 次 |
| 最近记录: |