将 16 位给定的整数以二进制补码形式相加(长整数加法)给定仅 8 位的字

Add integers given by 16 bits in two's complement form (long integer addition) given words of only 8 bits

几个小时以来我一直在为一个问题苦苦挣扎,似乎无法解决问题 我的想法是正确的。

我正在使用一个程序来模拟具有 4 位字节、2 字节字、16 个通用 2 字节寄存器和一个固定的计算机体系结构 4 字节指令格式。字在 2 字节边界上对齐,指令在 4 字节边界上对齐。 整数以二进制补码格式存储。

每个字节都以十六进制形式表示,例如0xff = -1,依此类推。 所以一个词在RAM内存中被看作是ff,01,a1等。

我正在尝试以补码表示法添加两个四字节整数 (长整数加法)。给定两个 16 位字的输入 X1;X0; Y1; Y0 输出一个 16 位字 Z1Z0 = X1X0 + Y1Y0.

我知道整数不适合给定的单词范围, 和我在阅读了很多关于长整数加法的文章后的想法 是应该把它分成更小的部分并添加 "digit" 作为数字。

在这种情况下,只有一个有符号位的八位不会有问题吗?我必须承认此刻我的思绪很迷茫,所以希望这是可以理解的。

最好的问候 好奇心

关于 2 的补码的好处是 - 对于给定的字长 - 无论您将数字视为有符号还是无符号,生成的位模式最终都是相同的,因此您可以使用完全相同的加法算法两种情况。唯一的问题是,当您到达最高字节时,有符号数与无符号数的溢出条件不同。

因此,如果你需要做一个双字节加法,你可以添加最低有效的两个字节,然后检查一个无符号进位,然后添加最高有效的两个字节(如果有的话还有进位)然后才如果数字被视为有符号,您是否需要计算结果是否溢出。

如果你的架构有进位标志,当你需要进位时很容易检测到。如果不是,进行加法的一种方法是,正如您所说,将加法分解为更短的块。所以,如果你有一个 8 位加法器,你可以做两个四位加法检测进位,四位加法的结果设置了位 4(如果这些位标记为 0 - 7)。

检测是否需要进位的另一种可能更好的方法是查看要添加的各个字节的最高位。假设一个 8 位加法器

  • 如果两个最高位都未设置(即位 7 = 0)则没有进位
  • 如果两个最高位都已设置(即第 7 位 = 1),则有一个进位
  • 如果一个置位,一个不置位,如果结果的最高位不置位,则有一个进位。

这样,您就不需要将加法分解为两个加法。

当您完成加法后,最后一个进位显然会发出无符号加法溢出的信号。

有符号加法溢出的信号不同。假设16位加法:

  • 如果两个原始数都是正数(即在两种情况下都清除第 15 位)并且结果为负数(第 15 位已设置)则发生溢出。
  • 如果两个原始数都是负数(即在两种情况下都设置了第 15 位)并且结果为正(第 15 位清零)则发生溢出。
  • 如果一个数是正数,一个数是负数(一个数的第15位被设置,另一个数被清除),就不可能发生有符号溢出。

编辑

评论中有很多问题。这是我尝试回答其中一些问题的尝试。

Is it correct to say that the two's complement form is only how my simulated computer "interprets" the integers when showing them or taking in inputs from my assembly code?

大部分是的。唯一特别的是通常有一个有符号溢出标志,因为有符号整数比无符号整数更早溢出。例如,如果我有 8 位模式 01111111 并添加 00000001,我会得到另一个 8 位模式 11111111。在无符号算术中,这完全没问题。我将 1 加到 127 得到 128。如果我将数字解释为 8 位 2 的补码,我将 1 加到 127 得到 -1。大多数处理器都有一个与进位标志分开的溢出标志,以指示何时发生这种情况。

E.g. say that a negative 8-bit number given in two's complement. Then I don't have to consider the fact that the first bit should be a sign bit, since in my 16 bit integer that I input that 8-bit is a value bit.

所有数字在做算术运算时应该具有相同的宽度。如果你有一个负的 8 位数字并且你想将它添加到一个 16 位数字,你需要将 8 位数字扩展到 16 位,这是通过符号扩展操作完成的。如果 8 位数字的符号位为 0,则通过使新的高 8 位全为零来扩展。如果8位数字的符号为1,则通过使新的高8位全为1来扩展。

What do you mean by an unsigned carry?

我的术语有点误导。真的只是进位而已。

If I first load my the first two bytes into register and the other two that should be added to these in another register. Then to be able to check whether or not the addition of the two first bytes gives a carry, I can bit shift the two registers 4 steps to the left and then back 4 steps. After this I can add the two bytes e.g. 02 and 08 and check for any carry? And then the same with a bit different bit shift pattern. And continue like this until the end where I have to check the last carryout and whether or not this will influence the value represented or not

嗯,不确定你在描述什么。这是一个例子。假设您有一个 8 位加法器、一个进位标志和一个带符号的溢出标志。您想要添加两个 8 位数字,100 和 101。即

01100100
01100101
--------
11001001   

解释为无符号加法,结果为201。解释为有符号加法,答案显然是-55,这显然是错误的。已签名溢出。

我们再试一次

  11111111
  00000001
----------
1 00000000
^-carry

解释为无符号加法,即 255 + 1 = 256,但 256 太大而无法放入 8 位,因此设置了进位标志。解释为带符号的加法,这是 -1 + 1 = 0,这是正确的。没有签名溢出。