减去二进制数时确定“借用”

时间:2012-10-13 04:50:35

标签: c# binary-data

我正在尝试用C#编写一个chip8模拟器。有必要在软件中模拟真实芯片上硬件中发生的操作。

有一个操作码需要检测在减去两个二进制数期间是否发生了借位。

Byte1 - Byte2

有没有人对如何使用C#判断是否发生借用有任何想法?

3 个答案:

答案 0 :(得分:4)

Wikipedia中搜索您未提及的神秘操作码,并寻找一些实现。我可以得出结论,操作码8XY5和8XY7(其中X和Y是寄存器标识符)将进行减法。

对于8XY5,寄存器X将被设置为寄存器X的值减去寄存器Y的值。如果寄存器Y的值大于或等于值Y,则寄存器F将被设置为1。寄存器X(否则为0)。

对于8XY7,寄存器X将被设置为寄存器Y的值减去寄存器X的值。如果寄存器X的值大于或等于值X,寄存器F将被设置为1寄存器Y(否则为0)。

这是8XY5的“伪”代码:

x = opcode[1]
y = opcode[2]
if (register[x] >= register[y])
    register[0xF] = 1
else
    register[0xF] = 0
result = register[x] - register[y]
if result < 0
    result += 256
register[x] = result

这是8XY7的“伪”代码:

x = opcode[1]
y = opcode[2]
if (register[y] >= register[x])
    register[0xF] = 1
else
    register[0xF] = 0
result = register[y] - register[x]
if result < 0
    result += 256
register[x] = result

这是一个C#实现:

const byte B_0 = 0x0;
const byte B_1 = 0x1;
const byte B_F = 0xF;

static void Main()
{
    byte[] registers = new byte[16];
    registers[0x1] = 255;
    registers[0x2] = 127;
    Opcode8XY5(registers, 1, 2);
    Console.WriteLine(registers[0x1]);
    Console.WriteLine(registers[0x2]);
    Console.WriteLine(registers[0xF]);
    Opcode8XY7(registers, 1, 2);
    Console.WriteLine(registers[0x1]);
    Console.WriteLine(registers[0x2]);
    Console.WriteLine(registers[0xF]);
    Console.ReadLine();
}

static void Opcode8XY5(byte[] registers, byte x, byte y)
{
    registers[B_F] = registers[x] >= registers[y] ? B_1 : B_0;
    registers[x] = (byte)(registers[x] - registers[y]);
}

static void Opcode8XY7(byte[] registers, byte x, byte y)
{
    registers[B_F] = registers[y] >= registers[x] ? B_1 : B_0;
    registers[x] = (byte)(registers[y] - registers[x]);
}

检查this实施以供参考。

答案 1 :(得分:2)

您需要比较每个字节的位...如果第二个字节位已设置但不是第一个,则您有借用条件:

static void Main(string[] args) {
    byte b1 = byte.Parse(args[0]);
    byte b2 = byte.Parse(args[1]);

    bool borrow = false;
    for (int mask = 0x01; mask <= 0x80; mask <<= 1) {
        if ((b2 & mask) > (b1 & mask)) {
            borrow = true;
        }
    }

    Console.WriteLine(Convert.ToString(b1, 2).PadLeft(8, '0'));
    Console.WriteLine(Convert.ToString(b2, 2).PadLeft(8, '0'));
    Console.WriteLine("borrowed: {0}", borrow);
}

可能有一个非常聪明的布尔逻辑可以给你答案,但我现在无法想出来。

答案 2 :(得分:1)

如果类型转换没有符号传播,您需要使用更宽的类型进行数学运算。然后检查结果是否将第8位设置为1.如果已设置,则进行借用。然后将结果保存为byte。