鱼C论坛

 找回密码
 立即注册
查看: 2727|回复: 7

关于有符号数,无符号数的问题

[复制链接]
发表于 2013-11-2 16:30:03 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
如果在debug下输入
mov al,f0
add  al,88

计算机会把f0和88,由16进制转化为二进制补码的形式存放在cpu中,那么cpu怎么判断
f0 和88是有符号数还是无符号数呢,具体的转换及运算过程能详细讲解一下吗?
小女子感激不尽
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-11-2 16:45:46 | 显示全部楼层
是不是我们输入的数,计算机都会转成二进制补码的形式存放起来?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2013-11-2 17:11:10 | 显示全部楼层
输入的数都会按照机器码表示,只不过要看你怎么解释它。比如说,0xff可以解释为-1也可以解释为255。你可以深入理解一下机器码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2013-11-2 22:05:02 | 显示全部楼层
本帖最后由 福禄娃娃 于 2013-11-2 22:20 编辑

由于-128的原码用8位无法表示,所以必须扩展到16位去表示,然后对16位的原码计算出16位的反码和补码,最后对16位的补码作低8位的截断,截断的低8位的值就是-128的补码了。

// 8位所能表示的  原码 的范围-127到+127
// 8位所能表示的  反码 的范围-127到+127
// 8位所能表示的  补码 的范围-128到+127

// 计算机当中,是规定-128的补码是1000 0000
// 算的时候则需要扩展到16位来算。否则,第8位到底表示符号还是表示数值2的7次方呢?所以,8位就按8位的通常看法来看, -128  的补码是  1000 0000
// 是难以理解的。只能扩展后来看。 

// -128  原码 1000 0000 1000 0000
// -128  反码 1111 1111 0111 1111
// -128  补码 1111 1111 1000 0000

// -129  原码 1000 0000 1000 0001
// -129  反码 1111 1111 0111 1110
// -129  补码 1111 1111 0111 1111

int main(int argc, char* argv[])
{
    char ch = -129; // warning C4309: 'initializing' : truncation of constant value
    char ch2 = -128; // no warning
    return 0;
}

注意:由于char能表示的范围是:-128~127,如果将-129赋给char,编译的时候是会产生warning的,并会截断,截断后的值是0x7f(127)。

浅析为什么char类型的范围是 —128~+127.rar

3.5 KB, 下载次数: 4

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-11-2 23:29:43 | 显示全部楼层

恩,还有个问题

在debug 下输入一个数例如f0,那么cpu 是认为它是有符号的还是无符号的呢?
它在内存中的存储数据是多少?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2013-11-2 23:46:38 | 显示全部楼层
1735485012 发表于 2013-11-2 23:29
恩,还有个问题

在debug 下输入一个数例如f0,那么cpu 是认为它是有符号的还是无符号的呢?

CPU不知道内存中的数据到底是什么类型的。

实际上内存中的数据就是没有类型的,你想怎么存就怎么存(不过要区分小尾和大尾方式),想怎么理解就怎么理解。

有符号整型最高位代表符号位,而无符号整型最高位仍然用来表示整数的一部分。

这就是为什么同样字节数的存储空间,无符号整型的可表示最大正值是有符号整型最大正值两倍+1的原因,如无符号8位最大可以表示1111 1111即255,而有符号因为最高位要表示符号,所以最大正值为0111 1111即127。

程序最终到了处理器级别就不知道内存中的数据到底是什么类型了,有所不同的是处理机执行的指令(OPCode)一厢情愿地把内存中的数据当成对应的数据类型在用而已。如果你知道处理机执行的指令,又知道它要访问的内存地址,你就可以人为地修改这些地址中的数据来达到你要的效果。缓冲区溢出也就是这样被利用的。

由于无符号数的加法与有符号数(补码)的加法是一致的,因此完全没有必要去区分指令的操作数是有符号数还是无符号数。关键在于运算结果你自己如何看待。
例如:
  al=1001 1100(9C),bl=1110 0111(E7),则
  add al,bl 
  运算结果是:
  al=1000 0011(83) 且进位标志CY=1,溢出标志OV=0.

  对于这个结果,你可以把它作为无符号数运算,即有:
  al=9Ch=156d,bl=E7h=231d,运算结果al=83h=131d,考虑到进位,运算结果应为131+256=387,而al+bl=156+231=387.正确。

  同样对于这个结果,你也可以把它作为有符号数的运算,即有:
  al=9Ch=-100d,bl=E7h=-25d,(注意有符号数均看成补码,9Ch是-100的补码,下同)。
  而运算结果al=83h= -125d,因为没有溢出(有符号数是不考虑进位的),运算结果可用。
  而al+bl=9Ch+E7h=(-100)+(-25)=-125.可见结果亦完全正确。

  由上例可见,无符号数的加法与有符号数的补码加法是完全一致的。CPU没有必要去区分。关键在于程序员如何去看待。CPU的运算结果将同时影响进位标志与溢出标志。如果程序员认为这是无符号数运算,则只考虑进位标志而忽略溢出标志。反之,如果程序员认为这是有符号数运算,则只考虑溢出标志而忽略进位标志。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-11-3 07:22:32 | 显示全部楼层
福禄娃娃 发表于 2013-11-2 23:46
CPU不知道内存中的数据到底是什么类型的。

实际上内存中的数据就是没有类型的,你想怎么存就怎么存(不 ...

多谢你了,说的很详细
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-11-3 08:35:44 | 显示全部楼层
福禄娃娃 发表于 2013-11-2 23:46
CPU不知道内存中的数据到底是什么类型的。

实际上内存中的数据就是没有类型的,你想怎么存就怎么存(不 ...

“al=9Ch=-100d,bl=E7h=-25d,(注意有符号数均看成补码,9Ch是-100的补码,下同”

意思就是说,我们输入的16进制数,计算机是直接转换位二进制,当做补码直接存储在内存单元中的,是这个意思吧?

我之前想的是,计算机再计算出 这个16进制数的补码,然后再存储,我想的是错的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-28 19:16

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表