1

我正在用 Java 编写一个 x86 解释器,并有一个 Python 脚本来测试我的 x86 指令实现与使用 NASM 的真实对应物。根据这个测试,除了进位标志之外,所有标志都被正确设置。有趣的部分是:

long result;
    switch (op) {
    case ADD:
        result = Math.abs(x) + Math.abs(y);
        if (result > U_MAX)
            registers.carry_flag = true;
        else
            registers.carry_flag = false;
        break;

其中U_MAX是 4294967295L(所有 32 位设置)。
我发现的所有答案都没有意识到进位和溢出是两个不同的东西。那么,如何在 Java 中正确实现进位标志呢?

4

2 回答 2

2

所有这些绝对值业务都是不必要的,坦率地说是令人困惑的,并且它有一个Math.abs(Integer.MIN_VALUE)负面的边缘情况(当你认真对待它时并不奇怪,但它看起来不像这段代码所期望的那样),你可以计算进位更简单的方法。

例如,使用旧的“结果无符号小于一个操作数”。结果当然只是x + y(as int),符号性与加法无关。然后使用 Java 8,您可以使用Integer.compareUnsigned,否则您可以使用此标识:

x <u y = (x ^ Integer.MIN_VALUE) <s (y ^ Integer.MIN_VALUE)

其中<u<s分别是无符号小于和有符号小于。

您还可以计算(x & 0xffffffffL) + (y & 0xffffffffL)并将其用于结果(强制转换为int)和进位标志(第 33 位)。

于 2015-07-01T21:47:16.587 回答
0

如果 x 和 y 是整数,则 Math.abs(x) 和 Math.abs(y) 是整数。假设 x = y = Integer.MAX_VALUE,则 Math.abs(x)+Math.abs(y) 相加的结果将为负数,如下程序所示:

public class t {
    public static void main(String args[]) {
        int x = Integer.MAX_VALUE;
        int y = Integer.MAX_VALUE;
        System.out.println(x+y);
    }
}

$ javac t.java
$ java t
 -2

因此,您应该制作 x 和 y long,或者long在添加之前强制转换为:result = ((long)Math.abs(x)) + ((long)Math.abs(y));

于 2015-07-01T21:33:41.730 回答