代码之家  ›  专栏  ›  技术社区  ›  Leedehai

汇编:有符号和无符号的数值运算是否不同?[副本]

  •  0
  • Leedehai  · 技术社区  · 7 年前

    我正在设计一个简单的玩具指令集和附带的仿真器,我试图找出什么指令支持。在算术方面,我现在有无符号的加、减、乘和除。然而,我似乎找不到一个明确的答案来回答以下问题:哪些算术运算符需要有符号的版本,哪些是无符号的和2的补码有符号的版本?

    例如,2的补码中的1111等于-1。如果你给它加1,假装它是一个无符号数,你得到0000,这是正确的,即使当它认为是-1。然而,这适用于所有的数字吗?其他三种运算(减法、乘法、除法)呢?

    0 回复  |  直到 7 年前
        1
  •  2
  •   Paul R    12 年前

    加法和减法对于有符号和无符号的2s补码是相同的,假设您将以正常的方式处理大多数cpu的溢出/下溢,即仅环绕。乘和除是不同的。所以你只需要一个加法例程和一个减法例程,不管是否有符号,但是你需要单独的有符号和无符号乘除。

        2
  •  2
  •   plugwash    8 年前

    加法、减法和乘法是相同的,前提是:

    1. 您的输入和输出大小相同
    2. 你在溢出上的行为是模2的环绕

    分工不同。

    许多指令集提供输出大于输入的乘法运算,有符号和无符号的乘法运算也是不同的。

    此外,如果您正在用C编写仿真器,则需要注意该语言的一些错误特性。

    1. C中有符号算术的溢出是未定义的行为。得到可靠的模2 必须使用无符号类型执行行为算术。
    2. C将把小于int的类型提升为int。需要非常小心地避免这种提升(在计算开始时加0u或乘1u是一种方法)。
    3. 从unsigned类型到signed类型的转换是实现定义的,我看到的实现做了明智的事情,但可能有一些没有。
        3
  •  0
  •   Guntram Blohm    12 年前

    所有操作都需要溢出检查,否则在某些情况下会返回不正确的值。这些检查的无符号版本与有符号版本不同,因此需要分别实现每个例程。