我正在为Intel 8080制作仿真器。其中一个操作码需要一个16位地址,它通过组合b
和c
寄存器(均为1个字节)。我有一个结构,寄存器彼此相邻。我将两个寄存器组合在一起的方式是:
using byte = char;
struct {
... code
byte b;
byte c;
... code
} state;
...somewhere in code
// memory is an array of byte with a size of 65535
memory[*reinterpret_cast<short*>(&state.b)]
我以为我可以OR
他们在一起,但那不起作用。
short address = state.b | state.c
我尝试这样做的另一种方法是创建一个short,并分别设置2个字节。
short address;
*reinterpret_cast<byte*>(&address) = state.b;
*(reinterpret_cast<byte*>(&address) + 1) = state.c;
有没有更好/更安全的方式来实现我想要做的事情?
答案 0 :(得分:2)
正如其他人所提到的那样,有关于endian-ness的担忧,但你也可以使用一个联合来操纵内存,而不需要做任何转移。
#include <cstdint>
#include <iostream>
using byte = std::uint8_t;
struct Regs
{
union
{
std::uint16_t bc;
struct
{
// The order of these bytes matters
byte c;
byte b;
};
};
};
int main()
{
Regs regs;
regs.b = 1; // 0000 0001
regs.c = 7; // 0000 0111
// Read these vertically to know the value associated with each bit
//
// 2 1
// 5 2631
// 6 8426 8421
//
// The overall binary: 0000 0001 0000 0111
//
// 256 + 4 + 2 + 1 = 263
std::cout << regs.bc << "\n";
return 0;
}
263
答案 1 :(得分:1)
short j;
j = state.b;
j <<= 8;
j |= state.c;
如果您需要相反的字节顺序,请反转state.b
和state.c
。
答案 2 :(得分:1)
short address = ((unsigned short)state.b << 8) | (unsigned char)state.c;
这是便携式的方式。你的方式,reinterpret_cast
并不是那么可怕,只要你明白它只适用于具有正确字符串的架构。
答案 3 :(得分:1)
您可以使用:
unsigned short address = state.b * 0x100u + state.c;
使用乘法而不是移位避免了与移位符号位等有关的所有问题。
address
应为unsigned
否则您将导致超出范围的分配,并且您可能希望使用0到65535作为地址范围,而不是-32768到32767。 / p>