【问题标题】:Ruby mimicking C Integer Data types and unionRuby 模仿 C 整数数据类型和联合
【发布时间】:2019-04-21 20:58:04
【问题描述】:

我正在尝试用 Ruby 制作一个 Chip-8 模拟器,就像我的朋友以前用 C++ 做过的那样,但我偶然发现了一些问题,请注意,我对 Ruby 只了解一些,我认为这个项目会是提高我这门语言技能的好方法。

我读过 Marshal 类,但我不知道如何使用它。 http://hackage.haskell.org/package/ruby-marshal-0.1.2/docs/Data-Ruby-Marshal-Int.html

所以基本上芯片 8 操作码是 int16 的,但我需要获取指令的低位和最高位,以便正确解释它。在 C++ 中,他使用 union 和基本的 int 数据类型,如下所示

struct Instruction {
    union {
        uint16_t opcode;
        struct {
            uint8_t lower;
            uint8_t upper;
        } bytes;
    };

如何模仿特定的 uint8_t 和 uint16_t 类型?我不介意工会不得不将工会换成其他东西。

这也是使用和管理内存的最佳方式吗?我实际上不知道下面的代码是否正确并且会编译,因为我只能访问记事本 atm

class Memory
    @memory = Hash.new(Array.new)
    @memory[:system] = Array.new(0x200, 0)
    @memory[:rom] = Array.new(0xCA0, 0)
    @memory[:internal] = Array.new(0x5F, 0)
    @memory[:refresher] = Array.new(0xF0, 0)

    @stack = Array.new(0) #Gotta stick with push/pop
end

class Chip8
    def initialize
        @memory = Memory.new

【问题讨论】:

    标签: c++ c ruby emulation


    【解决方案1】:

    你可以通过按位运算得到一个16位字的高字节和低字节:

    high_byte = opcode >> 8
    low_byte = opcode & 0xFF
    

    以上假设 opcode 已经被限制在 16 位无符号整数的范围内。

    反过来:

    opcode = (high_byte << 8) | low_byte
    

    以上假设high_bytelow_byte 被限制在8 位无符号整数的范围内。

    这种方法在 C++ 中也可以说更好,因为联合依赖于系统字节序(从技术上讲,它首先是一种非标准扩展,尽管受到流行编译器的广泛支持)。

    【讨论】:

    • 联合类型双关不仅依赖于系统字节序;它在技术上也是未定义的行为(尽管一些编译器,例如 GCC,保证直观语义作为特定于供应商的扩展)。
    • 我想我没有问对,我想做的正是一种将整数限制在特定范围内的方法
    • @KayleMeta 很抱歉,但您的问题根本没有暗示这是实际问题,而且我实际上不相信它甚至是问题。例如,如果您从二进制文件中读取操作码或单个字节,则读取部分已经将它们限制在您读取的类型范围内。另一方面,如果您自己形成操作码,那么它们已经受到有效操作码的约束。
    • @KayleMeta 如果您的问题是如何在 Ruby 中获取任意整数并将其限制在该范围内,您可以分别将 x &amp; 0xFFFFx &amp; 0xFF 用于 16 位和 8 位范围,但是您几乎可以肯定没有需要执行此操作的任意整数,并且必须这样做表明您在较早的地方有错误。
    猜你喜欢
    • 2022-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-14
    • 1970-01-01
    • 1970-01-01
    • 2022-07-07
    • 1970-01-01
    相关资源
    最近更新 更多