2014-01-18 32 views
1

我有一個名爲DescriptorByte位域結構對齊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; 

由於位域結構對齊到1個字節我應該得到的OpcodeList表的第5個元素,但我不知道如何使這個在C++我只知道如何使它在ASM:/

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

謝謝。

回答

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對象具有不同的尺寸時才使用它。

關於初始化,確實如此,這比您所擁有的更加冗長/醜陋,但這是值得管理的值得努力。

+0

我擔心的表現,有餘地在Intel x86和x64超過510個操作碼,所以我希望我可以使用一些指針和一個它的位移。 – ffenix

+0

不會有任何區別。 (編輯:如果你使用'std :: array') – tenfour

+0

如何在向量中添加如下成員: DescriptorByte ADD_8_OI = {TRUE,FALSE,TRUE,OPBASE + IMMED_8}; 等 我需要使用vector.assing列表中的每一個? :/ – ffenix

1

你也可以做到這一點使用您的struct

OpcodeList opcodelist; 
BYTE count = 5; 
void* p1 = &opcodelist; 
DescriptorByte* p2 = (DescriptorByte*)p1; 
DescriptorByte = *(p2 + count);