负数在内存中存储为2的补码,CPU如何知道它是负数还是正数?

时间:2011-10-06 22:05:06

标签: binary numeric unsigned sign microprocessors

-1可以用4位二进制表示为(2的补码)1111

15也表示为1111。

那么,当CPU从内存中获取值时,CPU如何区分15和-1?

6 个答案:

答案 0 :(得分:16)

当CPU从一个地方移动到另一个地方时,CPU不关心字节是保持-1还是15。没有“签名移动”这样的东西(到相同大小的位置 - 有更大或更小目的地的签名移动)。

当CPU对字节进行算术运算时,它只关心表示。 CPU根据您(或代表您的编译器)选择的操作码知道是否进行有符号或无符号算术。

答案 1 :(得分:9)

以前的大多数答案都提到了单独的操作码。对于像乘法和除法这样的更复杂的操作,这可能是正确的,但对于简单的加法和减法而言,这可能不是CPU的工作方式。

CPU在其标志寄存器中保存有关指令结果的数据。在x86(我最熟悉的地方)这里最重要的两个标志是"溢出"并且"携带"标志。

基本上,如果数字是有符号或无符号的,CPU并不关心它们是否相同。当数字超过它可以包含的最高无符号值时,将设置进位标志。溢出标志在超过或低于无符号数的范围时设置。如果使用无符号数字,则检查进位标志并忽略溢出标志。如果您正在使用带符号的数字,请检查溢出标志并忽略进位标志。

以下是一些例子:

无符号:

1111(15)+ 1111(15)= 1110(14)

你现在做的是检查进位标志,在这种情况下包含一个给出最终结果的标志

1 1110(30)

签名:

1111(-1)+ 1111(-1)= 1110(-2)

在这种情况下,您忽略进位标志,溢出标志应设置为零。

无符号:

0111(7)+ 0111(7)= 1110(14)

检查进位标志时,它应为零。

签名:

0111(7)+ 0111(7)= 1110(-2)

在这种情况下,将设置溢出标志,表示添加中存在错误。

总而言之,根据您对数字的解释,数字只有签名或无符号,CPU为您提供了区分它们的工具,但并不能区分它们。

答案 2 :(得分:7)

CPU不知道号码是签名还是未签名。当编译器创建机器语言文件时,它会选择要执行的正确操作以使用该编号进行数学运算。例如,如果您将变量声明为有符号类型,那么以机器语言执行的操作将是将该内存位置视为有符号值的操作。

在任何类型的软件中,总是在您解释您赋予其意义的数据时。内存中的字节可以是有符号或无符号数字,或字符,音乐文件的一部分,或图片中的像素等。赋予它意义的是你如何使用该字节。

答案 3 :(得分:2)

在编译器级别,区分基于数据类型。如果数据类型为int,则为该变量分配4个字节(在C中)。所以15 in 2的补码是00000000 00000000 00000000 00000000 00001111而-1是11111111 11111111 11111111 11111111。然后,编译器将其转换为CPU的相应操作码。 CPU执行此操作码,在此级别,所有内容都是1和0的形式。

答案 4 :(得分:0)

最小的可访问单位是1个字节。那是8位。在8位表示中,15被存储为00001111.编译器从符号位区分正数和负数。 MSB是一个标志位。如果是0则表示正数。如果是1表示负数。 15的二进制表示的MSB是0.它表示正数,00001111对应于+15。 8位二进制-1为11111111,因为其MSB为1,所以取负数。编译器首先使用其2的补码,然后用负号显示数字。请记住,如果存储数字为8位,则可以存储的最大值为(2 ^ 7)-1,其表示为7位。这意味着MSB对于正数始终为零。在您的问题中,如果我们假设需要4位来存储数字,则可以使用3位来存储该值,因为最后一位是保留符号的保留。对于3位,可以存储的最大值是(2 ^ 3)-1 = 7。这意味着15不能以4比特存储。因此编译器始终将1111视为-1。

按照以下链接访问有这些棘手问题的YouTube频道。 www.YouTube。 COM /手表?V = ZxRHOT3pzx4

答案 5 :(得分:0)

在代表15的2的补码中,我们需要5位,2'的范围是2 -16到15,所以这里的值变为01111,MSB位为0,所以-1的正值为11111