结构中的位是否得到保证

时间:2019-08-01 11:02:11

标签: c structure mips endianness mips32

我有一个与结构位字段有关的问题,请参阅下面的内容,因为我对应该使用哪个关键字来最好地描述我的问题一无所知:

上下文:我正在为MIPS R3000A汇编指令编写反汇编程序,该指令在2000年初用于Playstation程序。

问题:我想知道是否在此代码中:

struct Instruction {
    u32 other:26;
    u32 op:6;
};

//main:
Instruction instruction = *(Instruction*)(data + pc);
printf("%02x\n", instruction.op);

可以确保所有编译器使用很少的字节序,将始终使用op:6位字段来存储前6个MSB? (这很直观,您会假设最后6位存储在op位字段中)

它是以下代码的替代方法:

static uint32_t get_op_code(uint32_t data) {
    uint16_t mask = (1 << 6) - 1;
    return (data >> 26) & mask;
}

//main:
uint32_t instruction = *(uint32_t*)(data + pc);
uint32_t op = get_op_code(instruction);
printf("%02x\n", op);

这对我来说很好用,使用结构方法似乎更快一些,更不用说它更直观,更清晰了,但是我担心不能保证将6个第一位存储在结构的第二个位域“ op”。

1 个答案:

答案 0 :(得分:4)

C标准不保证位域的排列方式。它确实需要每个实现来定义它,因此它应该在编译器的文档中。 Per C 2018 6.7.2.1 11:

  

实现可以分配任何足够大的可寻址存储单元来容纳位字段。如果有足够的空间,则应将紧随结构中另一个位域之后的位域打包到同一单元的相邻位中。如果剩余空间不足,则将实现不适当的位字段放入下一个单元还是与相邻单元重叠。单位内的位域分配顺序(从高位到低位或从低位到高位)由实现定义。未指定可寻址存储单元的对齐方式。