【问题标题】:Assembler : why BCD exists?汇编程序:为什么存在 BCD?
【发布时间】:2011-01-22 12:06:36
【问题描述】:

如果您不了解二进制,我知道 BCD 就像更直观的数据类型。 但是我不知道为什么要使用这种编码,因为它很浪费,所以它没有多大意义 以 4 位表示(当表示大于 9 时)。

另外我认为 x86 只支持直接添加和订阅(您可以通过 FPU 转换它们)。

这可能来自旧机器或其他架构?

【问题讨论】:

    标签: assembly x86 cpu-architecture dataformat bcd


    【解决方案1】:

    BCD 算法对于精确的十进制计算很有用,这通常是金融应用程序、会计等方面的要求。它还使诸如乘以/除以 10 的幂之类的事情变得更容易。现在有更好的选择。

    有一个很好的Wikipedia article 讨论了利弊。

    【讨论】:

    • “更好的选择”?我会在硬件的 BCD 上构建一个 C++ BigDecimal 类型——如果你这样做肯定会很快。我不确定什么会比使用硬件数据类型“更好”。
    • 我怀疑现代 x86 CPU 已经优化了 BCD 实现——它们可能是作为微码实现的,关注的是兼容性,而不是性能。
    • IBM 在其 POWER 6 CPU 中提供对 DECFLOAT 的硬件支持。
    【解决方案2】:

    BCD 在空间上是浪费的,这是真的,但它的优点是是一种“固定间距”格式,可以很容易地找到特定数字的第 n 位。

    另一个优点是允许对任意大小的数字进行精确的算术计算。此外,使用提到的“固定间距”特性,可以轻松地将此类算术运算分块为多个线程(并行处理)。

    【讨论】:

    • 对任意大小的数字的精确算术计算也可以很容易地用普通二进制数对普通二进制数进行。
    • @nubok:使用 BCD,可以读取任意大小的十进制格式值,对其执行计算,然后以十进制格式写出,所有这些都在每个数字的恒定时间内完成。如果任意大小的数字格式使用 2 的幂为基数存储内容,则转换为十进制格式所需的每个数字所需的时间将随着 N 变大而增加。
    • @nubok:在您使用整数之前确实如此。但是如果你换成实数,二进制表示很烂,这就是你所说的浮点数。
    • 不仅仅是转换。如果您使用以 2 为底的(大)整数来表示(大)小数类型,您很快就会发现舍入的速度难以置信慢——您必须除以 10 的某个大幂。所以,最终发生的情况是加法可能很快,但仍需要四舍五入到所需的精度,这意味着您的加法实际上是一个小加法一个大除法。很慢。 BCD 没有这个问题。
    • 多线程参数并不令人信服,除非您的意思是要求访问数字的十进制数字(这对于扩展精度二进制 BigInts 来说非常慢)。如果您可以多线程 BCD 加法或乘法等,您还可以多线程处理 32 位或 64 位二进制大整数块。 (但通常你不能多线程甚至 SIMD,因为添加时需要进位传播。)
    【解决方案3】:

    BCD 存在于现代 x86 CPU 中,因为它存在于原始 8086 处理器中,并且所有 x86 CPU 都与 8086 兼容。 x86 中的 BCD 操作在当时用于支持业务应用程序。处理器本身的 BCD 支持实际上已不再使用。

    请注意,BCD 是十进制数的精确表示,而浮点不是,并且在硬件中实现 BCD 比实现浮点要简单得多。当处理器只有不到一百万个运行在几兆赫兹的晶体管时,这类事情就更重要了。

    【讨论】:

    • @Michael:我不记得 BCD 的 x86 指令了。请你提醒我一下好吗?
    • @John,我可以想到 DAA、DAS(小数调整 [后] 加/减)。可能还有其他一些,有一段时间我没有玩过它;-)
    • @mjv:谢谢。我完全忘记了那些。我几乎不记得曾经看过使用这些的例子 - 这不是一个真实的例子。
    【解决方案4】:

    BCD 在电子频谱的极低端非常有用,当寄存器中的值由某些输出设备显示时。例如,假设您有一个带有多个七段显示器的计算器,这些显示器显示一个数字。如果每个显示都由单独的位控制,那会很方便。

    现代 x86 处理器将用于具有此类显示器的设备中似乎令人难以置信,但 x86 可以追溯到 很长 路,并且 ISA 保持了大量的向后兼容性。

    【讨论】:

    • 这是最好的答案。在 7 段显示器或类似显示器上显示非 BCD 数字是逻辑上的噩梦。
    【解决方案5】:

    我确信前面链接到的 Wiki 文章更详细,但我在 IBM 大型机编程(PL/I 中)中使用了 BCD。 BCD 不仅保证您可以查看字节的特定区域以找到单个数字 - 这有时很有用 - 而且还允许硬件应用简单的规则来计算所需的精度和比例,例如将两个数字相加或相乘。

    我记得,有人告诉我,在大型机上,对 BCD 的支持是在硬件中实现的,当时,这是我们表示浮点数的唯一选择。 (我们说的是 18 年!)

    【讨论】:

    • 6502 的一些浮点格式是基于十进制的。 MOS Technologies 的 KIMath 软件(以印刷形式发布)使用未压缩的十进制尾数和二进制指数进行计算,并使用压缩十进制进行存储。
    • 我当时用BCD整合PC和大型机系统。
    【解决方案6】:

    30 多年前我上大学时,有人告诉我为什么 BCD(COBOL 中的 COMP-3)是一种很好的格式。

    这些原因都与现代硬件无关。我们有快速的二进制定点算法。我们不再需要通过向每个 BCD 数字添加偏移量来将 BCD 转换为可显示的格式。我们很少将数字存储为每位 8 位,因此 BCD 每位仅占用 4 位这一事实并不是很有趣。

    BCD 是遗物,应该留在过去,属于它的地方。

    【讨论】:

      【解决方案7】:

      我认为 BCD 对很多事情都有用,原因如上所述。似乎被忽略的一件显而易见的事情是提供从二进制到 BCD 的指令,反之亦然。这对于将 ASCII 数字转换为二进制以进行算术运算非常有用。

      其中一个发帖人错误地认为数字经常以 ASCII 格式存储,实际上很多二进制数存储已经完成,因为它更有效。将 ASCII 转换为二进制有点复杂。 BCD 有点介于 ASCII 和二进制之间,如果有 bsdtoint 和 inttobcd 指令,它会使转换变得非常容易。所有 ASCII 值都必须转换为二进制以进行算术运算。所以,BCD 在 ASCII 到二进制的转换中实际上很有用。

      【讨论】:

        【解决方案8】:

        现在,通常以二进制格式存储数字,并将它们转换为十进制格式以供显示,但转换确实需要一些时间。如果数字的主要目的是显示或添加到将要显示的数字,则以十进制格式执行计算可能比以二进制执行计算并转换为十进制更实用。许多具有数字读数的设备和许多视频游戏都以压缩 BCD 格式存储数字,每个字节存储两位数字。这就是为什么许多分数计数器在 1,000,000 点而不是某个二次方值时溢出的原因。如果硬件不支持压缩 BCD 算术,则替代方案将不是使用二进制,而是使用非压缩十进制。在显示时将压缩的 BCD 转换为未压缩的十进制可以轻松地一次完成一个数字。相比之下,将二进制转换为十进制要慢得多,并且需要对整个数量进行运算。

        顺便说一句,8086 指令集是我见过的唯一一个带有“ASCII 调整除法”和“ASCII 调整乘法”的指令集,其中一个将一个字节乘以 10,另一个将一个字节除以 10 .奇怪的是,值“0A”是机器指令的一部分,替换不同的数字会导致这些指令乘以或除以其他数量,但这些指令并未记录为通用乘法/除以常数指令.我想知道为什么没有记录该功能,因为它可能很有用?

        注意到处理器用于加减压缩 BCD 的各种方法也很有趣。许多执行二进制加法,但使用标志来跟踪在加法期间是否从位 3 到位 4 发生进位;然后他们可能期望代码清理结果(例如 PIC),提供一个操作码来清理加法而不是减法,提供一个操作码来清理加法和另一个用于减法(例如 x86),或者使用一个标志来跟踪最后一个操作是加法或减法,并使用相同的操作码来清理两者(例如 Z80)。有些使用单独的操作码进行 BCD 算术(例如 68000),有些使用标志来指示加/减运算应该使用二进制还是 BCD(例如 6502 导数)。有趣的是,最初的 6502 以与二进制数学相同的速度执行 BCD 数学运算,但它的 CMOS 导数需要一个额外的周期来进行 BCD 运算。

        【讨论】:

        • 在 x87 中也有 FBLD and FLSTP 来加载和存储 BCD 数字。一些现代架构具有对十进制浮点数的硬件支持,例如 Power6 和 IBM z10
        【解决方案9】:

        很少有人可以计算以六进制表示的数量,因此以十进制显示或至少允许查看中间结果很有用。特别是在财务或会计领域。

        【讨论】:

        • 请记住,问题是关于汇编程序“数据类型”的。在低级别使用 BCD 没有太大意义,这是我问题的核心。如今,大多数软件开发都是使用高级语言完成的,这些语言将以人类可读的形式显示信息。
        • 我认为它更像是固件问题。您不能坐在机器前等待超过 3 秒的时间来等待答案。最后,真正重要的是最终用户得到的响应。
        • 现代计算机只需几十纳秒即可将二进制整数转换为 ASCII 十进制数字字符串。以二进制形式存储数字不会限制您向用户显示它的方式。 (BCD 使转换为十进制 ASCII 非常便宜,但在具有更快二进制 add/sub/mul/div 的现代计算机上,除了最小的整数之外的所有计算都变得更加昂贵。)
        【解决方案10】:

        现代计算强调捕获设计逻辑的编码,而不是在这里或那里优化几个 CPU 周期。节省的时间和/或内存的价值通常不值得编写特殊的位级例程。

        话虽如此,BCD 仍然偶尔有用。

        我能想到的一个例子是当你有一个巨大的数据库平面文件或其他像 CSV 这样的 ASCII 格式的大数据时。如果您所做的只是在某些限制之间寻找价值,那么 BCD 就很棒。在扫描所有数据时转换所有值会大大增加处理时间。

        【讨论】:

          猜你喜欢
          • 2010-11-02
          • 1970-01-01
          • 2011-03-12
          • 2010-10-30
          • 2010-11-28
          • 2011-07-02
          • 2018-12-05
          • 2010-10-21
          • 2013-10-01
          相关资源
          最近更新 更多