После того, как я решил свою проблему до этого вопроса Я продолжил расширять эту версию своего кода, чтобы включить объединения полей данных из моих предыдущих версий шаблона с этой версией, и у меня это пока :
main.cpp
#include <iostream>
#include <type_traits>
#include "Register.h"
int main() {
using namespace vpc;
std::cout << std::boolalpha;
std::cout << "std::bitset<64> is trivially copyable "
<< std::is_trivially_copyable<std::bitset<64>>::value << '\n'
<< "QWord is trivially copyable "
<< std::is_trivially_copyable<QWord>::value << '\n'
<< "DWord is trivially copyable "
<< std::is_trivially_copyable<DWord>::value << '\n'
<< "Word is trivially copyable "
<< std::is_trivially_copyable<Word>::value << '\n'
<< "Byte is trivially copyable "
<< std::is_trivially_copyable<Byte>::value << '\n'
// << "Bits is trivially copyable "
//<< std::is_trivially_copyable<Bits>::value << '\n'
<< "My Register is trivially copyable "
<< std::is_trivially_copyable<Register>::value << "\n\n";
std::cout << "sizeof(std::bitset<Byte>) = " << sizeof(Byte) << " bytes\n";
std::cout << "sizeof(std::bitset<Word>) = " << sizeof(Word) << " bytes\n";
std::cout << "sizeof(std::bitset<DWord>) = " << sizeof(DWord) << " bytes\n";
std::cout << "sizeof(std::bitset<QWord>) = " << sizeof(QWord) << " bytes\n";
std::cout << "sizeof(Register) = " << sizeof(Register) << " bytes\n\n";
Register r;
std::cout << "sizeof(Register::byte) = " << sizeof(r.byte) << " bytes\n";
std::cout << "sizeof(Register::Byte) = " << sizeof(r.byte) / sizeof(r.byte[0]) << " bytes\n";
std::cout << "sizeof(Register::word) = " << sizeof(r.word) << " bytes\n";
std::cout << "sizeof(Register::Word) = " << sizeof(r.word) / sizeof(r.word[0]) << " bytes\n";
std::cout << "sizeof(Register::dword) = " << sizeof(r.dword) << " bytes\n";
std::cout << "sizeof(Register::DWord) = " << sizeof(r.dword) / sizeof(r.dword[0]) << " bytes\n";
std::cout << "sizeof(Register::value) = " << sizeof(r.value) << " bytes\n";
std::cout << "sizeof(Register) = " << sizeof(r) << " bytes\n\n";
r.value = 0xFFFFFFFFFFFFFFFF;
std::cout << "value = " << r.value.to_ullong() << '\n' << r.value << '\n';
for (std::uint16_t i = 0; i < 8; i++) {
std::cout << "byte_" << i << " : " << r.byte[i] << '\n';
}
return EXIT_SUCCESS;
}
Register.h
#pragma once
#include <algorithm>
#include <bitset>
#include <string>
#include <vector> // include for typedefs below.
namespace vpc {
typedef std::int8_t i8;
typedef std::int16_t i16;
typedef std::int32_t i32;
typedef std::int64_t i64;
const std::uint16_t BYTE = 0x08;
const std::uint16_t WORD = 0x10;
const std::uint16_t DWORD = 0x20;
const std::uint16_t QWORD = 0x40;
typedef std::bitset<BYTE> Byte;
typedef std::bitset<WORD> Word;
typedef std::bitset<DWORD> DWord;
typedef std::bitset<QWORD> QWord;
struct Register {
union {
QWord value{ 0 };
union {
DWord dword[2];
struct {
DWord dword0;
DWord dword1;
};
};
union {
Word word[4];
struct {
Word word0;
Word word1;
Word word2;
Word word3;
};
};
union {
Byte byte[8];
struct {
Byte byte0;
Byte byte1;
Byte byte2;
Byte byte3;
Byte byte4;
Byte byte5;
Byte byte6;
Byte byte7;
};
};
};
Register() : value{ 0 } {}
};
Register reverseBitOrder(Register& reg, bool copy = false);
} // namespace vpc
Register.cpp
#include "Register.h"
namespace vpc {
Register reverseBitOrder(Register& reg, bool copy) {
auto str = reg.value.to_string();
std::reverse(str.begin(), str.end());
if (copy) { // return a copy
Register cpy;
cpy.value = QWord(str);
return cpy;
}
else {
reg.value = QWord(str);
return {};
}
}
} // namespace vpc
выход
std::bitset<64> is trivially copyable true
QWord is trivially copyable true
DWord is trivially copyable true
Word is trivially copyable true
Byte is trivially copyable true
My Register is trivially copyable true
sizeof(std::bitset<Byte>) = 4 bytes
sizeof(std::bitset<Word>) = 4 bytes
sizeof(std::bitset<DWord>) = 4 bytes
sizeof(std::bitset<QWord>) = 8 bytes
sizeof(Register) = 32 bytes
sizeof(Register::byte) = 16 bytes
sizeof(Register::Byte) = 4 bytes
sizeof(Register::word) = 16 bytes
sizeof(Register::Word) = 4 bytes
sizeof(Register::dword) = 8 bytes
sizeof(Register::DWord) = 2 bytes
sizeof(Register::value) = 8 bytes
sizeof(Register) = 32 bytes
value = 18446744073709551615
1111111111111111111111111111111111111111111111111111111111111111
byte_0 : 11111111
byte_1 : 11111111
byte_2 : 11001100
byte_3 : 11001100
byte_4 : 11001100
byte_5 : 11001100
byte_6 : 11001100
byte_7 : 11001100
После просмотра распечатанных данных о размерах типов bitset
и сравнения их с фактическими размерами в качестве членов структуры внутри объединения. Я пытаюсь выяснить, что здесь происходит под капотом.
Я не уверен, правильно ли я выполняю вычисления sizeof, если это связано с внутренним хранилищем bitset
Я пытаюсь понять выравнивание данных в контексте союзов как членов структуры, в которой базовым типом является тип std::bitset
типов. Из заголовка видно, что существует 4 варианта: bitset<8> = Byte
, bitset<16> = Word
, bitset<32> = DWord
& bitset<64> = QWord
В сущностях должно быть делимое отображение этих:
// each [] = 1 byte or 8 bits for simplicity
bitset<64> = [] [] [] [] [] [] [] []
bitset<32> = [] [] [] []
bitset<16> = [] []
bitset<8> = []
Поэтому, когда я пытаюсь использовать их в союзе как таковой:
union {
QWord q;
union {
DWord d[2];
struct {
DWord d_0;
DWord d_1;
};
};
union {
Word w[4];
struct {
Word w_0;
Word w_1;
Word w_2;
Word w_3;
};
};
union {
Byte b[8];
struct {
Byte b_0;
Byte b_1;
Byte b_2;
Byte b_3;
Byte b_4;
Byte b_5;
Byte b_6;
Byte b_7;
};
};
};
Я бы подумал, что, используя шаблон, который я показал над этим объединением, я смогу упаковать данные в выравнивание размера байта:
// each inner [] = 1 byte or 8 bits
// and each outer [] = index into array
0 1 2 3 4 5 6 7
value = [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ]
0 1
dword[2] = [[] [] [] []], [[] [] [] []]
0 1 2 3
word[4] = [[] []], [[] []], [[] []], [[] []]
0 1 2 3 4 5 6 7
byte[8] = [[ ]] [[ ]] [[ ]] [[ ]] [[ ]] [[ ]] [[ ]] [[ ]]
Однако, похоже, это не происходит так, как я ожидал.
Моя общая цель состоит в том, чтобы смоделировать шаблон, который я изложил выше, так, чтобы базовый размер регистра составлял 64 бита или 8 байтов в ширину, и с помощью объединений я мог получить доступ к суббайтам, слову или словам из полное слово.
Не могли бы вы уточнить, что мне здесь не хватает? Я не уверен, связано ли это с тем, как std::bitset
хранится в памяти, связано ли это с выравниванием структур или с самими союзами.