C 中的移位运算符前置一个而不是零

Shift operator in C prepends ones instead of zeros

代码如下:

#define u8 char
#define u32 unsigned int

typedef struct {
    //decoded instruction fields
    u8 cond; // Condition (f.ex. 1110 for always true)
    u8 instruction_code; // Is a constant since we only use branch
    u32 offset; // Offset from current PC
} dcdinst;

u8 mem[1024];

mem[0x0] = 0b11101010;

u8* instruction_addr = &mem[pc];

if (instruction_addr == NULL) {
    return false;
}

unsigned int first_part = instruction_addr[0];

// Here is the code that presents a problem:
// I try to get the upper part of the first byte
inst.cond = first_part >> 4;

first_part是后面的字节:11101010。 inst.cond 变成 11111110,但我需要它是 00001110。

所以,我的实际问题是我想获取从地址 instruction_addr 开始的指令的前 4 位。我试图通过使用右移运算符 >> 来做到这一点,但问题是它没有在字节的左侧添加 0,而是添加了 1。

我在 Whosebug 上发现我首先必须将值转换为无符号值,这就是我使用变量 first_part 所做的,但我仍然遇到同样的问题。我不明白为什么这种转变似乎 "see" 我的变量是负数,而它的类型具体是 "unsigned".

有人知道吗?

您的 u8 类型正在使用 char 而未指定符号,这意味着它具有未定义的符号。您的编译器可能默认使用 signed char 。因此,您在运营期间和促销期间需要进行符号扩展。

变化:

#define u8 char
#define u32 unsigned int

至:

typedef unsigned char u8;
typedef unsigned int u32;

(或正确使用 stdint.h 类型),并且您的存储实际上应该是未签名的。

使用 typedefs 还意味着编译器涉及此别名,它不仅仅是预处理器文本替换,消除了 class 细微错误。