安全地将2个字节转换为short

时间:2016-05-12 01:59:45

标签: c++ pointers casting byte short

我正在为Intel 8080制作仿真器。其中一个操作码需要一个16位地址,它通过组合bc寄存器(均为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;

有没有更好/更安全的方式来实现我想要做的事情?

4 个答案:

答案 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

Live Example

答案 1 :(得分:1)

short j;
j = state.b;
j <<= 8;
j |= state.c;

如果您需要相反的字节顺序,请反转state.bstate.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>