麻烦迭代结构

时间:2014-01-18 00:19:03

标签: c++ oop

我有一个名为DescriptorByte的bitfield结构,对齐到1个字节,还有一个结构,用于保存大量的DescriptorByte,如下所示:

struct DescriptorByte
{
    unsigned char IsImmedCalc : 1;
    unsigned char IsPrefix : 1;
    unsigned char NoMemOp : 1;
    unsigned char Size : 5;
};

struct OpcodeList
{
    DescriptorByte ADD_EB_GB;
    DescriptorByte ADD_EV_GV;
    DescriptorByte ADD_GB_EB;
    DescriptorByte ADD_GV_EV;
    DescriptorByte ADD_8_OI =   { TRUE, FALSE, TRUE, OPBASE + IMMED_8 };
    DescriptorByte ADD_32_OI =  { TRUE, FALSE, TRUE, OPBASE + IMMED_32 };
    DescriptorByte PUSH_ES =    { TRUE, FALSE, TRUE, OPBASE };
    DescriptorByte POP_ES =     { TRUE, FALSE, TRUE, OPBASE };
    DescriptorByte OR_EB_GB;
        //ETC
};

我想要做的是基于迭代结构的数字(字节),如下所示:

OpcodeList opcodelist;
BYTE count = 5;
DescriptorByte = opcodelist + count;

由于bitfield结构与1字节对齐,我应该得到OpcodeList表的第5个元素,但我不知道如何在C ++上实现这一点我只知道如何在ASM中实现:/

LEA EAX, OPCODELIST
MOV ECX, COUNT
MOV EAX, DWORD PTR [EAX+ECX];
AND EAX, 0FF;

感谢。

2 个答案:

答案 0 :(得分:3)

您尝试以多种方式访问​​此“列表”:按名称(如ADD_EB_GB)和索引。你不能用结构来做这件事。

我建议使用std::vector<DescriptorByte>(或std::array)。这样您就可以通过索引访问。如果您仍然需要按名称访问,请将您的名称作为常量索引放入此向量中。

有点像这样:

typedef std::array<DescriptorByte, 9> OpcodeList;

enum OpcodeIndex
{
    ADD_EB_GB = 0,
    ADD_EV_GV,
    ADD_GB_EB,
    ADD_GV_EV,
    ADD_8_OI,
    ADD_32_OI,
    PUSH_ES,
    POP_ES,
    OR_EB_GB
}

...

// instantiate & initialize an opcode list.
OpcodeList opcodeList =
{
    { ... },// ADD_EB_GB,
    { ... },// ADD_EV_GV,
    { ... },// ADD_GB_EB,
    { ... },// ADD_GV_EV,
    { TRUE, FALSE, TRUE, OPBASE + IMMED_8 },// ADD_8_OI,
    { TRUE, FALSE, TRUE, OPBASE + IMMED_32 },// ADD_32_OI,
    { TRUE, FALSE, TRUE, OPBASE },// PUSH_ES,
    { TRUE, FALSE, TRUE, OPBASE },// POP_ES,
    { ... }// OR_EB_GB
};

// to access by symbol:
DescriptorByte someOpcode = opcodeList[ADD_GV_EV];
// to access by symbol + offset:
DescriptorByte anotherOpcode = opcodeList[ADD_GV_EV + 5];

注意性能。在机器代码级别,结构和静态大小的数组将执行完全相同的操作。它们是ptr +偏移字段。这正是std::array将编译成的内容。 std::vector会有更多的开销,因为它支持不同的大小,所以只有在你拥有不同大小的OpcodeList个对象时才使用它。

关于初始化,它确实比你所拥有的更冗长/更丑陋,但是为了让事情易于管理是值得的。

答案 1 :(得分:1)

您也可以使用struct

执行此操作
OpcodeList opcodelist;
BYTE count = 5;
void* p1 = &opcodelist;
DescriptorByte* p2 = (DescriptorByte*)p1;
DescriptorByte = *(p2 + count);