CPU是如何做减法的?

发布于 2024-11-03 10:44:06 字数 567 浏览 4 评论 0原文

我有一些基本的疑问,但每次我坐下来尝试面试问题时,这些问题和我的疑问就会出现。

假设 A = 5,B = -2。假设A和B都是4字节,那么CPU如何进行A + B加法呢?

我知道 A 的符号位 (MSB) 为 0 表示正值 B 的符号位为 1,表示负整数。

现在在C++程序中,我想打印A + B,ALU(算术逻辑单元)的加法模块是否首先检查符号位,然后决定进行减法,然后按照以下过程减法。如何进行减法将是我的下一个问题。

A = 5
B = 2

我想做A - B。计算机将取 B 的 2 补码并添加 A + B 的 2 补码并返回(在丢弃左侧多余的位之后)?

A = 2
B = 5

执行A - B。在这种情况下计算机会如何表现?

我知道任何 if-then 等条件逻辑都将在 ALU 内部的硬件中完成。计算 2 的补码等,丢弃多余的位,所有这些都将在 ALU 内部的硬件中完成。 ALU 的这个组件是什么样子的?

I have some basic doubts, but every time I sit to try my hands at interview questions, these questions and my doubts pop up.

Say A = 5, B = -2. Assuming that A and B are 4-bytes, how does the CPU do the A + B addition?

I understand that A will have sign bit (MSB) as 0 to signify a positive value
and B will have sign bit as 1 to signify a negative integer.

Now when in C++ program, I want to print A + B, does the addition module of the ALU (Arithmetic Logic Unit) first check for sign bit and then decide to do subtraction and then follow the procedure of subtraction. How subtraction is done will be my next question.

A = 5
B = 2

I want to do A - B. The computer will take 2's complement of B and add A + 2's complement of B and return this (after discarding the extra bit on left)?

A = 2
B = 5

to do A - B. How does the computer do in this case?

I understand that any if-then etc kind of conditional logic all will be done in hardware inside ALU. computing 2s complement etc,discarding extra bit all will be done in hardware inside ALU. How does this component of ALU look like?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

携余温的黄昏 2024-11-10 10:44:06

我们使用 2's-complement 的全部原因是,无论数字是正数,加法都是相同的或负面 - 没有需要考虑的特殊情况,例如 1 的补码有符号幅度 表示。

因此,要找到 AB,我们只需对 B 求反并添加即可;也就是说,我们找到 A + (-B),并且因为我们使用的是 2 的补码,所以我们不必担心 (-B) 是正数还是负数,因为无论哪种方式,加法算法的工作原理都是相同的。

The whole reason we use 2's-complement is that addition is the same whether the numbers are positive or negative - there are no special cases to consider, like there are with 1's-complement or signed-magnitude representations.

So to find A-B, we can just negate B and add; that is, we find A + (-B), and because we're using 2's-complement, we don't worry if (-B) is positive or negative, because the addition-algorithm works the same either way.

枕头说它不想醒 2024-11-10 10:44:06

以两位或三位为单位进行思考,然后了解这些内容可扩展到 32 或 64 或任意位数。

首先,让我们从十进制开始

 99
+22
===

为了做到这一点,我们将进行一些“携带一个”。

11
 99
+22
===
121

9 加 2 是 1 进位 1,1 加 9 加 2 是 2 进位 1...

重点是要注意,要添加两个数字,我实际上需要三行,至少其中一些我可能需要能够将三个数字相加。与 ALU 中的加法器相同,每列或位通道、单位加法器需要能够将两个输入加上一位进位,并且输出是一位结果和一位进位。

既然你使用了 5 和 2,让我们做一些 4 位二进制数学运算,

 0101
+0010
=====
 0111

我们不需要进位,但你可以看到数学是有效的,5 + 2 = 7。

如果我们想将 5 和 -2 加起来

11
 0101
+1110
=====
 0011

,答案是3 正如预期的那样,并不令人惊讶,但我们有一个执行。由于这是一个带有负数的二进制补码加法,所以一切都有效,然后没有 if 符号位,二进制补码就可以了,所以我们不关心只向加法器提供两个操作数。

现在,如果你想做出细微的差别,如果你想从 5 中减去 2,你可以选择减法指令而不是加法。我们都知道,二进制补码求反意味着取反并加一。我们在上面看到,两个输入加法器确实需要第三个输入进行进位,以便它可以级联到加法器需要的宽度。因此,我们不需要进行两次加法运算,而是将取反并加 1 作为第一个加法,真正的加法我们所要做的就是取反并设置进位:

了解没有减法逻辑,它会添加您输入的任何内容的负数。

    v this bit is normally zero, for a subtract we set this carry in bit
11 11
 0101 five
+1101 ones complement of 2
=====
 0011

你知道吗,我们得到了相同的答案……任一操作数的实际值是什么并不重要。如果是加法运算,则在进位位上放一个零并将其送入加法器。如果是减法运算,则将第二个操作数反转并在进位上放一个 1,然后将其送入同一个加法器。掉下来的东西都会掉下来。如果你的逻辑有足够的位来保存结果,那么一切都会起作用,如果你没有足够的空间,那么就会溢出。

溢出有两种,无符号溢出和有符号溢出。无符号很简单,它是进位位。有符号溢出与将 msbit 列上的进位输入位与该列的进位输出位进行比较有关。对于上面的数学运算,您会看到该 msbit 列的进位和进位是相同的,都是 1。通过检查我们碰巧知道 4 位系统有足够的空间来正确表示数字 +5、-2 和 +3。 4 位系统可以表示+7 到-8 的数字。因此,如果您将 5 和 5 相加,或者 -6 和 -3 相加,您将得到有符号溢出。

01 1
 0101
+0101
=====
 1010

了解相同的加法逻辑用于有符号和无符号数学,这取决于您的代码,而不是虚拟定义这些位是否被视为二进制补码有符号或无符号的逻辑。

在上面的 5 + 5 情况下,您会看到 msbit 列上的进位是 1,但进位是 0,这意味着 V 标志(有符号溢出标志)将由逻辑设置。同时,该位(即 C 标志进位标志)的进位将不会被设置。当认为无符号 4 位可以容纳数字 0 到 15 时,因此 5 + 5 = 10 不会溢出。但是,当认为有符号 4 位可以容纳 +7 到 -8 且 5 + 5 = 10 是有符号溢出时,因此设置了 V 标志。

如果/当您有带进位的加法指令时,它们采用相同的加法器电路,并且不是将进位送入零,而是将进位标志送入。与借位减法类似,进位不是输入 1,而是根据状态寄存器中进位标志的状态输入 1 或 0。

乘法则完全是另一回事,二进制使乘法比十进制数学更容易,但您必须有不同的无符号和有符号乘法指令。除法是它自己独立的野兽,这就是为什么大多数指令集没有除法。许多计算机没有乘法器,因为它会烧毁许多门或时钟。

Think in terms of two or three bits and then understand that these things scale up to 32 or 64 or howevermany bits.

First, lets start with decimal

 99
+22
===

In order to do this we are going to have some "Carry the one's" going on.

11
 99
+22
===
121

9 plus 2 is 1 carry the one, 1 plus 9 plus 2 is 2 carry the one...

The point being though to notice that to add two numbers I actually needed three rows, for at least some of it I might need to be able to add three numbers. Same thing with an adder in an alu, each column or bit lane, single bit adder, needs to be able to add two inputs plus a carry in bit, and the output is a one bit result and a one bit carry.

Since you used 5 and 2 lets do some 4 bit binary math

 0101
+0010
=====
 0111

We didnt need a carry on this one, but you can see the math worked, 5 + 2 = 7.

And if we want to add 5 and -2

11
 0101
+1110
=====
 0011

And the answer is 3 as expected, not really surprising but we had a carry out. And since this was an add with a minus number in twos complement it all worked, there was no if sign bit then, twos complement makes it so we dont care just feed the adder the two operands.

Now if you want to make a subtle difference, what if you want to subtract 2 from 5, you select the subtract instruction not add. Well we all learned that negating in twos complement means invert and add one. And we saw above that a two input adder really needs a third input for carry in so that it can be cascaded to however wide the adder needs to be. So instead of doing two add operations, invert and add 1 being the first add the real add all we have to do is invert and set the carry in:

Understand that there is no subtract logic, it adds the negative of whatever you feed it.

    v this bit is normally zero, for a subtract we set this carry in bit
11 11
 0101 five
+1101 ones complement of 2
=====
 0011

And what do you know we get the same answer...It doesnt matter what the actual values are for either of the operands. if it is an add operation you put a zero on the carry in bit and feed it to the adder. If it is a subtract operation you invert the second operand and put a one on the carry in and feed it to the same adder. Whatever falls out falls out. If your logic has enough bits to hold the result then it all works, if you do not have enough room then you overflow.

There are two kinds of overflow, unsigned, and signed. Unsigned is simple it is the carry bit. Signed overflow has to do with comparing the carry in bit on the msbit column with the carry out bit for that column. For our math above you see that the carry and carry out of that msbit column is the same, both are a one. And we happen to know by inspection that a 4 bit system has enough room to properly represent the numbers +5, -2, and +3. A 4 bit system can represent the numbers +7 down to -8. So if you were to add 5 and 5 or -6 and -3 you would get a signed overflow.

01 1
 0101
+0101
=====
 1010

Understand that the SAME addition logic is used for signed and unsigned math, it is up to your code not the logic to virtually define if those bits were considered twos complement signed or unsigned.

With the 5 + 5 case above you see that the carry in on the msbit column is a 1, but the carry out is a 0 that means the V flag, the signed overflow flag, will be set by the logic. At the same time the carry out of that bit which is the C flag the carry flag, will not be set. When thinking unsigned 4 bits can hold the numbers 0 to 15 so 5 + 5 = 10 does not overflow. But when thinking signed 4 bits can hold +7 to -8 and 5 + 5 = 10 is a signed overflow so the V flag is set.

if/when you have an add with carry instruction they take the SAME adder circuit and instead of feeding the carry in a zero it is fed the carry flag. Likewise a subtract with borrow, instead of feeding the carry in a 1 the carry in is either a 1 or 0 based on the state of the carry flag in the status register.

Multiplication is whole other story, binary makes multiplication much easier than when done with decimal math, but you DO have to have different unsigned and signed multiplication instructions. And division is its own separate beast, which is why most instruction sets do not have a divide. Many do not have a multiply because of the number of gates or clocks it burns.

萝莉病 2024-11-10 10:44:06

你在符号位部分有点错误。它不仅仅是一个符号位 - 每个负数都会转换为 2 的补码。如果你这样写:

B = -2

编译器在将其编译为二进制时会生成:

1111 1111 1111 1111 1111 1111 1111 1110

现在,当它想要加 5 时,ALU 会获取 2 个数字并将它们相加,这是一个简单的加法。

当 ALU 收到减法命令时,它会得到 2 个数字 - 它对第二个数字的每一位进行 NOT 运算,并进行简单的加法并再加 1(因为 2 的补码并不对每一位进行 +1)。

这里要记住的基本一点是,选择 2 的补码的目的正是为了不必对 2+3 和 2+(-3) 进行 2 个单独的过程。

You are a bit wrong in the sign bit part. It's not just a sign bit - every negative number is converted to 2's complement. If you write:

B = -2

The compiler when compiling it to binary will make it:

1111 1111 1111 1111 1111 1111 1111 1110

Now when it wants to add 5, the ALU gets 2 numbers and adds them, a simple addition.

When the ALU gets a command to subtract it is given 2 numbers - it makes a NOT to every bit of the second number and makes a simple addition and adds 1 more (because 2's complement is NOT to every bit +1).

The basic thing here to remember is that 2's complement was selected for exactly the purpose of not having to make 2 separate procedures for 2+3 and for 2+(-3).

逆光下的微笑 2024-11-10 10:44:06

ALU(算术逻辑单元)的加法模块是否先检查符号位,然后决定进行减法,然后执行减法的过程

否,在一个和两个补码中,加/减正负之间没有区别数量。对于正值和负值的任何组合,ALU 的工作方式都是相同的

因此,ALU 基本上对 A - B 执行 A + (-B),但它不需要一个单独的否定步骤。 设计者使用了一个巧妙的技巧,通过仅添加 复用器 和 NOT 门以及新输入 Binvert 以便有条件地反转第二个输入。这是一个简单的 ALU 示例,可以执行 AND/OR/ADD/SUB

Full-adder

计算机体系结构 - 全加器

真正的加法器只是一个在 ⊞ 内有加号的盒子,它将 ab~b 相加,并且进位,生成总和进位。它的工作原理是实现补码 -b = ~b + 1,因此 a - b = a + ~b + 1。这意味着我们只需将进位设置为1(或否定借入的进位)并反转第二个输入(即b >)。这种类型的 ALU 可以在各种计算机体系结构书籍中找到,例如

RISC-V ALU

补码-b = ~b 所以当你想减法时不要设置进位,否则设计是一样的。然而,二进制补码还有另一个优点:对有符号和无符号值的操作也以相同的方式工作,因此您甚至不需要区分有符号和无符号类型。作为补码,您需要将进位位添加回最低有效位,如果类型是有符号的

通过对上述 ALU 进行一些简单的修改,它们现在可以执行 6 种不同的操作:ADD、SUB、SLT、AND、OR、NOR

6-function ALU

CSE 675.02:计算机体系结构简介

多个位运算是通过连接上面的多个单位 ALU 来完成的。实际上,ALU 能够执行更多操作,但它们的设计目的是为了节省空间,原理类似

does the addition module of ALU (Arithmetic Logic Unit) first check for sign bit and then decide to do subtraction and then follow the procedure of subtraction

No, in one's and two's complement there's no differentiation between adding/subtracting a positive or negative number. The ALU works the same for any combination of positive and negative values

So the ALU is basically doing A + (-B) for A - B, but it doesn't need a separate negation step. Designers use a clever trick to make adders do both add and sub in the same cycle length by adding only a muxer and a NOT gate along with the new input Binvert in order to conditionally invert the second input. Here's a simple ALU example which can do AND/OR/ADD/SUB

Full-adder

Computer Architecture - Full Adder

The real adder is just a box with the plus sign inside ⊞ which adds a with b or ~b and carry in, producing the sum and carry out. It works by realizing that in two's complement -b = ~b + 1, so a - b = a + ~b + 1. That means we just need to set the carry in to 1 (or negate the carry in for borrow in) and invert the second input (i.e. b). This type of ALU can be found in various computer architecture books like

RISC-V ALU

In one's complement -b = ~b so you don't set the carry in when you want to subtract, otherwise the design is the same. However two's complement has another advantage: operations on signed and unsigned values also work the same, so you don't even need to distinguish between signed and unsigned types. For one's complement you'll need to add the carry bit back to the least significant bit if the type is signed

With some simple simple modification to the above ALU they can now do 6 different operations: ADD, SUB, SLT, AND, OR, NOR

6-function ALU

CSE 675.02: Introduction to Computer Architecture

Multiple-bit operations are done by concatenating multiple single-bit ALUs above. In reality ALUs are able to do a lot more operations but they're made to save space with the similar principle

我一向站在原地 2024-11-10 10:44:06

在 2 的补码表示法中:not B = -B -1-B = (not B) + 1。可以在计算机上或在纸上检查。

因此 A - B = A + (not B) + 1 可以通过以下方式执行:

  • 1 按位非
  • 1 递增
  • 1 加法

有一个技巧可以仅使用非和否定来低效地递增和递减。

例如,如果您在寄存器中从数字 0 开始并执行:

not, neg, not, neg, not, neg, ...,寄存器将具有以下值:

-1, 1, -2, 2, -3, 3, ...

或者作为另外 2 个公式:

not(-A) = A - 1
-(not A) = A + 1

In 2's-complement notation: not B = -B -1 or -B = (not B) + 1. It can be checked on a computer or on paper.

So A - B = A + (not B) + 1 which can be performed with:

  • 1 bitwise not
  • 1 increment
  • 1 addition

There's a trick to inefficiently increment and decrement using just nots and negations.

For example if you start with the number 0 in a register and perform:

not, neg, not, neg, not, neg, ... the register will have values:

-1, 1, -2, 2, -3, 3, ...

Or as another 2 formulas:

not(-A) = A - 1
-(not A) = A + 1
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文