How can I make members point to other members in a class?

I'm trying to build a simple virtual machine. I have a couple 8 bit registers that can also be accessed as 16 bit registers when paired. I can easily do this outside of a class but can't figure out how I would do it once a class is instanced.


Here's an example:

1
2
3
4
5
//16-Bit Register
unsigned short AB_reg;
//8-Bit Register
unsigned char A_reg = * ((unsigned char *)(&AB_reg)+1); //High Byte
unsigned char B_reg = * ((unsigned char *)&AB_reg); //Low Byte 


This does not work within a class unfortunately and I understand why, but how would I do this?

I also realize I can byte shift the AB_reg before it's used for the 8-bit registers, but it will take much more code to do so.
Last edited on
You have a couple of ways around this:
1) Lines 4 & 5: Make A_reg and B_reg into pointers. To do that you have the * in the wrong place.
1
2
unsigned char * A_reg = ((unsigned char *)(&AB_reg)+1); //High Byte
unsigned char * B_reg = ((unsigned char *)&AB_reg); //Low Byte  


2) Use a union. Caution - This approach might not portable to other architectures.
1
2
3
4
5
6
7
8
9
10
11
union REGS
{   //16-Bit Register
    unsigned short AB_reg;
    struct 
    {   //8-Bit Register
        unsigned char A_reg; //High Byte
        unsigned char B_reg; //Low Byte 
    };        
};

REGS registers;





Last edited on

1) Lines 4 & 5: Make A_reg and B_reg into pointers. To do that you have the * in the wrong place.
[code]
unsigned char * A_reg = ((unsigned char *)(&AB_reg)+1); //High Byte
unsigned char * B_reg = ((unsigned char *)&AB_reg); //Low Byte
[/code


This works well, I just have to remember to deference when accessing the member.

I'm trying to avoid unions for that exact reason... Thanks.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <cstdint>
#include <iomanip>
#include <iostream>

#define IS_BIG_ENDIAN64 (*(const uint64_t*)"\0\0\0\0\xFF\xFF\xFF\xFF" == 0)
#define IS_BIG_ENDIAN32 (*(const uint32_t*)"\0\0\xFF\xFF" == 0)
#define IS_BIG_ENDIAN16 (*(const uint32_t*)"\0\xFF" == 0)

struct Register
{
  uint64_t& value;
  
  uint32_t& L;
  uint32_t& H;
  
  uint16_t& LL;
  uint16_t& LH;
  uint16_t& HL;
  uint16_t& HH;
  
  uint8_t& LLL;
  uint8_t& LLH;
  uint8_t& LHL;
  uint8_t& LHH;
  uint8_t& HLL;
  uint8_t& HLH;
  uint8_t& HHL;
  uint8_t& HHH;
  
  Register( uint64_t& value ):
    value(value),
      L( (*((uint32_t*)(&value) +  IS_BIG_ENDIAN64)) ),
      H( (*((uint32_t*)(&value) + !IS_BIG_ENDIAN64)) ),
     LL( (*((uint16_t*)(&L)     +  IS_BIG_ENDIAN32)) ),
     LH( (*((uint16_t*)(&L)     + !IS_BIG_ENDIAN32)) ),
     HL( (*((uint16_t*)(&H)     +  IS_BIG_ENDIAN32)) ),
     HH( (*((uint16_t*)(&H)     + !IS_BIG_ENDIAN32)) ),
    LLL( (*((uint8_t*)(&LL)     +  IS_BIG_ENDIAN16)) ),
    LLH( (*((uint8_t*)(&LL)     + !IS_BIG_ENDIAN16)) ),
    LHL( (*((uint8_t*)(&LH)     +  IS_BIG_ENDIAN16)) ),
    LHH( (*((uint8_t*)(&LH)     + !IS_BIG_ENDIAN16)) ),
    HLL( (*((uint8_t*)(&HL)     +  IS_BIG_ENDIAN16)) ),
    HLH( (*((uint8_t*)(&HL)     + !IS_BIG_ENDIAN16)) ),
    HHL( (*((uint8_t*)(&HH)     +  IS_BIG_ENDIAN16)) ),
    HHH( (*((uint8_t*)(&HH)     + !IS_BIG_ENDIAN16)) )
  { }
};

int main()
{
  uint64_t values[ 4 ] = { 0 };
  Register RAX( values[0] );
  Register RBX( values[1] );
  Register RDX( values[2] );
  Register RCX( values[3] );
  
  std::cout << std::hex << std::setfill( '0' );
  RAX.LLL = 0xFF; std::cout << std::setw( 16 ) << RAX.value << "\n";
  RAX.LLH = 0xFF; std::cout << std::setw( 16 ) << RAX.value << "\n";
  RAX.LHL = 0xFF; std::cout << std::setw( 16 ) << RAX.value << "\n";
  RAX.LHH = 0xFF; std::cout << std::setw( 16 ) << RAX.value << "\n";
  RAX.HLL = 0xFF; std::cout << std::setw( 16 ) << RAX.value << "\n";
  RAX.HLH = 0xFF; std::cout << std::setw( 16 ) << RAX.value << "\n";
  RAX.HHL = 0xFF; std::cout << std::setw( 16 ) << RAX.value << "\n";
  RAX.HHH = 0xFF; std::cout << std::setw( 16 ) << RAX.value << "\n";
}
00000000000000ff
000000000000ffff
0000000000ffffff
00000000ffffffff
000000ffffffffff
0000ffffffffffff
00ffffffffffffff
ffffffffffffffff
Last edited on
Topic archived. No new replies allowed.