安全地将2个字节转换为短整型

4
我正在制作Intel 8080的模拟器。其中一个操作码需要通过组合bc寄存器(均为1字节)来获得16位地址。我有一个将寄存器相邻排列的结构体。我组合这两个寄存器的方式是:
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

另一种尝试的方法是创建一个简短的内容,并逐个设置这2个字节。
short address;
*reinterpret_cast<byte*>(&address) = state.b;
*(reinterpret_cast<byte*>(&address) + 1) = state.c;

有没有更好/更安全的方法来实现我想做的事情?
4个回答

2
short address = ((unsigned short)state.b << 8) | (unsigned char)state.c;

这是一种可移植的方式。您使用 reinterpret_cast 的方式并不是非常糟糕,只要您理解它只能在具有正确字节序的架构上工作。


对齐问题比字节序问题更为严重。 - David Schwartz
好的,short将会被适当地对齐,所以我在那里看不出问题。 - Sam Varshavchik
1
我在回应你的最后一句话,这就像是说过马路不看两边也没关系,因为你很少会被飞机撞到。你指出了一个小问题,却忽略了一个重要的问题。 - David Schwartz
reinterpret_cast<short *> 的方式违反了严格别名规则,因此是未定义行为。 - M.M

2

您可以使用:

unsigned short address = state.b * 0x100u + state.c;

使用乘法而不是移位可以避免与移位符号位等相关的所有问题。
地址应该是无符号的,否则会导致超出范围的赋值错误,并且您可能想要使用0到65535作为地址范围,而不是-32768到32767。

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

如果需要反向字节序,请对 state.bstate.c 进行反转。


这可能会导致未定义的行为。 - M.M
@M.M 怎么会呢?你是说因为 short 是有符号的吗? - David Schwartz

2

正如其他人提到的那样,大小端存在一些问题,但您也可以使用联合体来操作内存,而无需进行任何移位。

示例代码

#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

实时示例

(相关的IT技术)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接