如何从这个字节中提取操作数?使用二进制补码

How do I extract the operand from this byte? Using two's complement

我目前有代码:

int getOperand(unsigned char b) {
    int operand = b & 0x3F;
    return operand;
}

'b'是从字节文件中读入的8位二进制数。 'b' 的 2 个最高有效位是操作码,最后 6 位是操作数。我目前有这个代码设置来获取 'b' 的最后 6 位并将它们存储在变量 'operand' 中。我目前遇到的问题是我不知道如何将 OPERAND 提取为带符号的操作数。目前返回的数字只是无符号的。因此,我该如何编辑代码,使其 returns 变成一个带符号的数字?

如果我们假设您只是存储适合 6 位带符号值的负字节的最后 6 位,使用您的机器本机 2 的补码约定来表示负数,那么您检查符号位是否设置在你的 6 位值,然后扩展符号位。

return (b & 0x20) ? b | ~0x3F : b & 0x3F;

Try it online!

The problem I am currently having is that I do not know how to extract the OPERAND as a signed operand.

C 标准不强制要求以任何特定方式表示负符号数。在大多数实现中,负符号整数存储在所谓的二进制补码中。存储负符号数的另一种主要方式称为补码。

下面的代码假定输入的数字是作为带符号的数字输入的,其中符号位存储为位 5 (0x20)。这称为一个人的补充表示。对于某些应用程序,以这种方式编写操作数更容易。 示例:

#define NEGATIVE_SIGN      0x0C
#define ONE                0x01
#define TWO                0x02

#define MINUS_ONE    (NEGATIVE_SIGN | ONE)
#define MINUS_TWO    (NEGATIVE_SIGN | TWO)

然后 OPERAND 数被转换为完整的 8 位 signed char 二进制补码表示。

// INPUT: OPERAND in one's complement representation of the negative value.
// Using 6 bits one can represent numbers from  -31 to 31.
// returning `signed char` is presented in two's complement representation.

    signed char getOperand(unsigned char b) {
        unsigned char operand = b & 0x3F;
        unsigned char sign = 0x20 & operand;
        unsigned char number =  0x1F & operand;

        if(sign)
        {
            number = (~number) +1;   // Conversion to Two's Complement     
        }

        return number;
    }


//  5 4 3 2 1 0


int main (){
    printf("%d\n",  getOperand(0x21)); // negative one
    printf("%d\n",  getOperand(0x22)); // -2
    printf("%d\n",  getOperand(0x2F)); // negative 15
    printf("%d\n",  getOperand(0x1F | 0x20 ) ); // negative -31    
    printf("%d\n",  getOperand(0x1F ) );        // positive 31 

  return 0;
}

输出:

-1
-2
-15
-31
31