微机原理

转]浅读《溢出及其判断方法》 Xinsoft,2004-05-09 22:54:57

其实所谓溢出原理:即是数据存储过程中超过数据结构所能容纳的实际长度都可成为溢出。我认为要浅显读懂该文必须了解计算机语言,计算机数制相关知识。如果要深入研究溢出则必须深入学习计算机程序设计相关知识,比如计算机数据结构,计算机编译原理,微机接口与组成原理等等。这里取前者,浅显谈谈计算机语言,计算机数制相关知识。


一。浅谈计算机语言
众所周知,计算机是0,1的二进制数字世界,所谓电子计算机乃是用电的低电平表示0,高电平表示1,来实现数字世界的。计算机工作必须要接受人的操作和控制,人们为了让计算机按自己的意愿工作,就必须与计算机交流信息,这个交流信息的工具就是计算机语言。所以计算机语言(Computer Lnguage)指用于人与计算机之间通讯的语言。语言分为自然语言与人工语言两大类。自然语言是人类在自身发展的过程中形成的语言,是人与人之间传递信息的媒介。人工语言指的是人们为了某种目的而自行设计的语言。计算机语言就是人工语言的一语。计算机语言是人与计算机之间传递信息的媒介。
计算机是不能识别与执行人类的自然语言的,要使计算机执行人们的意志,必须使计算机能识别指令。电脑每做的一次动作,一个步骤,都是按照以经用计算机语言编好的程序来执行的,程序是计算机要执行的指令的集合,而程序全部都是用我们所掌握的语言来编写的。所以人们要控制计算机一定要通过计算机语言向计算机发出命令。众所周知,计算机内部存储数据和指令是采用二进制(0和1)方式的。人们在设计某一类型计算机时,同时为它设计了一套“指令系统”,即事先规定好用指定的一个二进制指令代表一种操作。例如在16位机上,由16位二进制数据组成的一个指令代表一种操作。如用1011011000000000作为一条加法指令,计算机在接收此指令后就执行一次加法,用1011010100000000作为减法指令,使计算机执行一次减法。16个0和1可组成各种排列组合,通过线路转换为电信号,使计算机执行各种不同的操作。这种由0和1组成的指令,称为“机器指令”。一种计算机系统的全部指令的集合称为该计算机的“机器语言”。 计算机所能识别的语言只有机器语言,即由0和1构成的代码。在计算机诞生初期,为了使计算机能按照人们的意志工作,人们必须用机器语言编写好程序(程序是由若干条指令组成的,用于实现一个专门的目的)。但是机器语言难学、难记、难写,只有少数计算机专业人员才会使用它。
后来,出现了“汇编语言”,

用一组易记的符号代表一个机器指令,如用“ADD 1,2”代表一次加法,用“SUB 1,2”代表一次减法,汇编语言中的一条指令一般与一条机器指令相对应。机器语言和汇编语言都是面向具体计算机的语言,每一种类型的计算机都有自己的机器语言和汇编语言,不同机器之间互不相通。由于它们依赖于具体的计算机,被称为“低级语言。
汇编语言的实质和机器语言是相同的,都是直接对硬件操作,只不过指令采用了英文缩写的标识符,更容易识别和记忆。它同样需要编程者将每一步具体的操作用命令的形式写出来。汇编程序通常由三部分组成:指令、伪指令和宏指令。汇编程序的每一句指令只能对应实际操作过程中的一个很细微的动作,例如移动、自增,因此汇编源程序一般比较冗长、复杂、容易出错,而且使用汇编语言编程需要有更多的计算机专业知识,但汇编语言的优点也是显而易见的,用汇编语言所能完成的操作不是一般高级语言所能实现的,而且源程序经汇编生成的可执行文件不仅比较小,而且执行速度很快。
20世纪50年代,出现了“高级语言”。它不依赖于具体的计算机,而是在各种计算机上都通用的一种计算机语言。高级语言接近人们习惯使用的自然语言和数学语言,使人们易于学习和使用,人们认为,高级语言的出现是计算机发展史上一次惊人的成就,使千万非专业人员能方便地编写程序,操纵使用计算机按人们的指令进行工作。
高级语言是目前绝大多数编程者的选择。和汇编语言相比,它不但将许多相关的机器指令合成为单条指令,并且去掉了与具体操作有关但与完成工作无关的细节,例如使用堆栈、寄存器等,这样就大大简化了程序中的指令。同时,由于省略了很多细节,编程者也就不需要有太多的专业知识。
高级语言主要是相对于汇编语言而言,它并不是特指某一种具体的语言,而是包括了很多编程语言,如目前流行的VB、VC、FoxPro、Delphi等,这些语言的语法、命令格式都各不相同。计算机本身是不能直接识别高级语言的,必须将高级语言的程序翻译成计算机能识别的机器指令,计算机才能执行。这个翻译的工作是由“编译系统”软件来完成的。不同类型的计算机上使用的翻译软件是不同的。因此,在一台计算机上能运行某一种高级语言程序的条件是:必须在此计算机系统上配有此语言的编译系统。例如要在一台微机上运行C语言程序,必须先将为该微机设计的C编译系统装入计算机内。故此高级语言所编制的程序,必须经过转换才能被计算机执行,按转换方式可将它们分为两类:
解释类:执行方式

类似于我们日常生活中的“同声翻译”,应用程序源代码一边由相应语言的解释器“翻译”成目标代码(机器语言),一边执行,因此效率比较低,而且不能生成可独立执行的可执行文件,应用程序不能脱离其解释器,但这种方式比较灵活,可以动态地调整、修改应用程序。
编译类:编译是指在应用源程序执行之前,就将程序源代码“翻译”成目标代码(机器语言),因此其目标程序可以脱离其语言环境独立执行,使用比较方便、效率较高。但应用程序一旦需要修改,必须先修改源代码,再重新编译生成新的目标文件(* .OBJ)才能执行,只有目标文件而没有源代码,修改很不方便。现在大多数的编程语言都是编译型的,例如Visual C++、Visual Foxpro、Delphi等。
常用的高级语言有:BASIC(适合初学者应用)、FOPTRAN(用于数据计算)、COBOL(用于商业管理)、PASCAL(用于教学)、C(用于编写系统软件)、Ada(用于编写大型软件)、LISP(用于人工智能)等。不同的语言有其不同的功能,人们可根据不同领域的需要选用不同的语言。
二.一些重要相关的名词解释
1、二进制数:
基数为2,即每一位只能取用0或1两个数字.
位权(这个数位能表示的最大的十进制值)为2i
例如:10110B=1*24+0*23+1*22+1*21+0*20
=22
2、十六进制数:
基数为16:即每一位可取用0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F十六个数字
位权为16i
例如:110H=1*162+1*161+0*160
=256+16
=272
各种数制之间的转换:
例1:100110.101B= H
“以小数点为界,四位合一位”
第一步: 100110.101B=0010 0110. 1010B
第二步:按十六进制数读出:26.AH
例2:0A7.2H= B
“一拆四”
A前的0是说明,A是数字,而不是寄存器名
读出:1010 0111.0010B
可写成:10100111.001B
十进制转换成二进制/十六进制
整数:用除以X取余法;
小数:用乘以X取整法。
例:42.25=101010.01B=00101010.0100B=2A.4H
解: 42
ASCII码
用7位二进制数表示一个符号的编码
包括:数字0~9,英文字母A~Z、a~z,标点符号,控制符号等128个符号
扩展ASCII码用8位二进制数,可表示256种符号
请记住:
ASCII字符 ASCII码 ASCII字符 ASCII码
’0’ 30H ’1’ 31H
’9’ 39H ’A’ 41H
’F’ 46H ’a’ 61H
一个ASCII字符用一个字节的内存单元存放,最高位是奇偶校验位,通常看作0。
二进制编码的十进制数
BCD码:BCD码指每位十进制数用4位二进制数编码表示的方法。4567的BCD码是:0100010101100111
机器数及其真值
在计算机中,一个数连同它的符号都用二进制的编码形式来表示,这种数称为机器数。
一个机器数对应的十进制数值称为这个机器数的真值
无符号数(unsigned )和带符号数(

signed )
所有的数位都用于表示数值。这种方式表示的数是无符号数。
最高位作符号位,剩余的位作数值位。这种方式表示的数是带符号数。
字长为8位时,能表示的无符号数的范围是00H~0FFH。
带符号数的三种表示形式
原码:由于任何信息在计算机中只能用0和1的组合来表示,所以数的正负号也得通过0和1加以区分。通常规定一个数的最高位作为符号位。若该位为0,则表示正数,若为1,则表示负数。这样一来,数的符号也数字化了。这种数的符号也数字化了的二进制数称为“机器数”,而称原来带正负号的数为“真值”。 用最高位表示数的符号,数值部分为真值的绝对值,这种表示方法就是原码。
反码:(one’s complement) (radix-1 complement)
正数的反码=正数的原码
负数的反码=负数原码的数值位按位取反
补码: (two’s complement) (radix complement)
正数的补码=正数的原码
负数的补码=负数的反码加1
或者: [X]补=2n+X
原码、反码和补码
十进制 原码 反码 补码
+ 0 0000 0000B 0000 0000B 0000 0000B
+4 0000 0100B 0000 0100B 0000 0100B
+127 0111 1111B 0111 1111B 0111 1111B
-0 1000 0000B 1111 1111B 0000 0000B
-4 1000 0100B 1111 1011B 1111 1100B
-127 1111 1111B 1000 0000B 1000 0001B
-128 字长8位无法表示 1000 0000B
补码运算规则:
[ [X]补]补= [X]原
[X+Y]补= [X]补+ [Y]补
三.计算机算中数的表示方法:
1.定点表示和浮点表示
(Fixed-Point/Float-Point Representation of Number)
对于任意一个二进制数N可表示成带幂指数形式: N=2E*M
其中E是一个二进制整数,称为数N 的阶码(或首数:Exponent);M 是二进制纯小数,称为数N 的尾数。它们的含义是:M 表示N 的全部有效数码,E 指明N 的小数点位置。
(例如101.01=211*0.10101)
(1).定点小数
若取E =0,则N = NSN-1N-2....N-m为纯小数,小数点固定在最高数位前。
其值范围为: |N|≤1-2-m (NS = 0/1 分别表示“+”/“-”符号)
例如: -0.1010101 的定点表示机器数为 11010101
(2).定点整数
若取E = n(尾数的位数n),则N = NSNnNn-1....N0为整数,小数点固定在N0之后。
其值范围为: |N|≤2n-1 (NS = 0/1 分别表示“+”/“-”符号)
例如: +1010101 的定点表示机器数为 01010101
用计算机做定点数运算时,要特别注意数的“溢出”(Overflow)问题。例如一个字节二进制表示时,所以参与运算的数据、结果均须在-127到+127范围内。
有时,当所表示的数全是正数时,可以省略符号位,扩充有效数位,即“无符号数”。
(3).浮点表示法
1)浮点数格式
若E 不是常数,则小数点可浮动、不固定,N=2E*M是浮点数,须给出尾数和阶码两部分,数N 的机器数表示为:(IEEE浮点格式)
1位数符m位阶码n位

尾数
浮点数也可表示为:
EM
将数符放在尾数第一位。例如:N = +101.0 = 2+11*(+0.1010)在机器中表示为:
0 1 1 0 1 0 1 0
阶符 阶码 数符 尾数
对非负数也可用无符号阶码、尾数。
2)规格化处理
由于浮点数表示不是唯一的,为便于运算、比较,规定计算机内浮点数的尾数部分必须用纯小数形式给出。
当一浮点数的尾数为0 ,或阶码小于可表示范围时,浮点数为机器零。
2.原码表示法
1.定义:设X为纯小数(定点小数),机器数最高位表示符号(0/1表示+/-)
[X]原 = X (0≤X <1)
1-X (-1< X≤0)
2.真值零的表示:有正零和负零两种表示(设五位二进制表示)
[+0]原=00000; [-0]原=10000
3.原码能表示的数值范围:
(1)对n位定点小数(包括一位符号位)可表示 -(1-2-(n-1))----+(1-2-(n-1))
例如:n=8时为 -127/128 ---- +127/128
(2)对n位定点整数(一位符号)可表示 -(2(n-1)-1)----+(2(n-1)-1)
例如:n=8时为 -127 ----- +127
4.特点:容易实现乘法和除法,但处理加减运算比较复杂。
3.反码表示法
1.定义:正数的反码同原码,负数的数值位按位取反,定义式为(仅讨论纯小数):
[X]反 = X (0≤X <1)
(2-2-n)+X (-1< X≤0)
2.反码的符号位定义与原码相同,且也有两个零,[+0]反=00000; [-0]反=11111
3.逻辑实现方便(非门),便于计算补码(详见后)。
4.补码表示法
1.模数的概念
关于补码的概念,在日常生活及数学中已遇到过。例如把时钟从10点钟拨到9点正,显然可以用两种方法:一是逆时针方向把时针拨一格,相当于做减法10-1=9;另一种方法是顺时针方向拨11格,这相当于做加法,即10+11=21=12+9,由于钟面是十二进制,所以逢12产生进位、12自动丢失,时针指向9点。可见,在一定条件下,减法可以转换为加法来做,所谓条件就是“-1”转换为它的补码,即“-1”关于12的补码为11,这里12 称为模。
模数M 的大小:字长是固定的,模数的值已超出范围,在机器中自动丢失,如n 位定点整数(包括1位符号)的模数为2n ;而n 位定点小数(包括1位符号)的模数为2。
2.定义式: 任意一数X 的补码为 [X]补= M + X (mod M )
对n 位定点小数 [X]补 = X ( 0≤X < 1)
2+X (-1≤ X < 0)
3.补码表示的范围
真值零的补码表示为唯一的编码:[0]补=[-0]补=00000
n 位定点小数补码表示范围为: -1 ---- +(1-2-(n-1))
例如:n = 8 ,可表示 -1 ---- +0.1111111
n 位定点整数补码表示范围为: -2(n-1) ---- +2(n-1)-1
例如:n = 8 ,可表示 -128 ---- +127
4.求补码的方法
正数的补码与原码、反码相同,负数补码可按下述方法之一获取。
(1)方法1:由定义式计算出

X = -0.1010 则[X]补=2-0.1010=10110
(2)方法2:先计算出反码,再在最低位加1
例 X = -0.1010 则[X]反=10101 所以[X]补=10110
(3)方法3:保持最右边的1及其右边的0不变,左边各位取反,符号位为1
例 X = -0.1010 则[X]补=10110
5.补码运算
(1)根据补码定义可证明: [X+Y] 补 = [X] 补+[Y] 补
[X-Y] 补 = [X] 补+ [-Y] 补
加减运算可先求出补码,再把符号位与数位同等处理,进行加减运算,最后对补码运算结果取补,即得运算结果真值。
例: X=+0.1010, Y=-0.0101 求 X+Y,X-Y,Y-X 真值
答:[X+Y] 补 = [X] 补+[Y] 补 = 01010 + 11011 = 1 00101(其中1自动丢失)
所以X+Y = +0.0101
[X-Y] 补 = [X] 补+ [-Y] 补 =01010 + 00101 =01111
所以 X-Y = +0.1111
[-X+Y] 补 = [-X] 补+[Y] 补 = 10110 +11011 = 1 10001 (其中1自动丢失)
所以 -X+Y = -0.1111
加减运算结果不能超出补码能表示的范围,否则就溢出出错。
例: X=-0.1010, Y=-0.1010
[X+Y] 补 = [X] 补+[Y] 补 = 10110 + 10110 = 1 01100 (其中1自动丢失)
而 X+Y = +0.1100 是错误结果(负数太小,超出可表示范围)。
(2)易于实现乘2和除2运算
将补码的符号位与数值位一起右移一位,并且保持原符号位不变,可实现除2功能;将补码的符号位与数值位一起左移数位,可实现乘2功能(此时若符号位变化,则说明乘积溢出)。
例: X=+0.0110, Y=-0.0110
[X] 补 = 0.0110 [Y] 补 =1.1010
[X/2] 补 = 00011 [Y/2] 补 =11101
所以 X/2 = +0.0011 , Y/2 = -0.0011
[2X] 补 = 01100 [2Y] 补 =10100
所以 2X = +0.1100 , 2Y = -0.1100
[4X] 补 = 11000 而 4X = -0.1000 为错误结果。
6.变形补码(模4 补码或称双符号位补码)
定义: [X]补 = X ( 0≤X < 1)
4+X (-1≤ X < 0)
例: X=+0.1011, Y=-0.1011 则[X] 补 = 001011 [Y] 补 = 110101
[X+Y] 补 = [X] 补+[Y] 补 = 001011 + 110101 = 00 0000 即X+Y=0
[X-Y] 补 = [X] 补+ [-Y] 补= 001011 + 001011 = 01 0110 结果溢出
运算结果两符号位不同,数据发生溢出。
模4补码的特点:
(1)符号位 :00表示正号,11表示负号
(2)当符号位为01或10时,表示数据溢出:
01----结果大于等于1,产生上溢;10----结果小于-1,产生下溢
(3)零有唯一的编码
 
上述原码、反码和补码的讨论一般以定点小数为例,对定点整数亦可作类似定义,如n 位定点整数补码(mod 2)定义为:
当(X≥0)时,[X]补=X;当(X <0)时,[X]补=2n+X
若n=8 补码可表示范围为[-128 ,+127],而原码、反码可表示范围为[-127, +127]。至于特点和运算规则均相同。
不带符号定点数的整个机器码表示数值部分,其符号可隐含“+”,相同长度的不带符号定点数可表示的数值范围比带符号定点数大。
一个机器数根据不同的定义,可看作多个真值的表示。例如机器数80H,若表示定点

整数补码,对应真值-128;表示定点小数补码,对应真值-1;表示定点小数原码,对应真值-0;表示不带符号整数为128,纯小数为0.5。(还可表示机器码指令)
 
5.移码(增码)表示法
定义:对由1位符号、n位数值的二进制整数,[X]移=2n+X(-2n≤X <2n)
移码主要用于表示浮点数的阶码。它与补码的区别在于两者符号定义正好相反。
例1: X=+1011,则 [X]补=01011,而[X]移=11011
Y=-1011,则 [Y]补=10101,而[Y]移=00101
例2: 对机器数 1 010 1 110 (阶符 阶码 数符 尾数)
若阶码为移码,尾数为补码,以2为基数,则机器数对应的真值为-0.01*22=-1
例3: 求0.0101的机器数,浮点数格式同例2
解: 0.0101=0.101*2-1 则机器数应为:0 111 0 101
(规格化数据:对实数用规格化格式进行表示,即尾数部分为纯小数表示)






附文章原文《溢出及其判断方法》

溢出及其判断方法
(一)什么叫溢出
所谓溢出是指带符号数的补码运算溢出。例如,字长为n位的带符号数,用最
高位表示符号,其余n-1位用来表示数值。它能表示的补码运算的范围为-2n-1~+

2n-1-1。如果运算结果超出此范围,就叫补码溢出,简称溢出。在溢出时,将造成

运算错误。
例如,在字长为8位的二进制数用补码表示时,其范围为-28-1~+28-1-1即

-128~+127。如果运算结果超出此范围,就会产生溢出。


例1 已知X=01000000,Y=01000001,进行补码的加

法运算。
 〔X〕补=01000000 (+64的补码)
 + 〔Y〕补=01000001 (+65的补码)
〔X〕补+〔Y〕补=10000001 (-127的补码)
符号↑
即 〔X+Y〕补=10000001
X+Y=-1111111 (-127)
两正数相加,其结果应为正数,且为+129,但运算结果为负数(-127),这显然是错误
的。其原因是和数+129>+127,即超出了8位正数所能表示的最大值,使数值部分占据了
符号位的位置,产生了溢出错误。
例2 已知X=-1111111,Y=-0000010,进行补码的加

法运算。
〔X〕补= 10000001 (-127的补码)
 +〔Y〕补= 11111110 (-2的补码)
〔X〕 补+〔Y〕补=101111111 (+127的补码)
自动丢失  符号

↑
即 〔X+Y〕补=01111111 (+127)
两负数相加,其结果应为负数,且为-129,但运算结果为正数(+127),这显然是错误
的,其原因是和数-129<-128,即超出了8位负数所能表示的最小值,也产生了溢出错
误。
(二)判断溢出的方法
判断溢出的方法较多,例如以上两例根据参

加运算的两个数的符号及运算结果的符号可以
判断溢出;此外,利用双进位的状态也是常用的一种判断方法。这种方法是利用符号位相加

和数值部分的最高位相加的进位状态来判断。即利用
V=D7CD6C
判别式来判断。当D7C与D6C“异或”结果为1,即V=1,表示有溢出,当“异

或”结果为0,即V=0,表示无溢出。
如上述例1与例2,V分别为:V=01=1,与V=10=1,故两种运算均产生溢出。

(三)溢出与进位
进位是指运算结果的最高位向更高位的进位。如有进位,则Cy=1;无进位,则Cy

=0。当Cy=1,即D7C=1时,若D6C=1,
则V=D7CD6C=11=0,表示无溢出;若D6C=0,则V=10=1,

表示有溢出。当Cy=0,即D7C=0时,若D6C=1,则V=01=1,表示有

溢出;若D6C=0,则V=00=0,
表示无溢出。可见,进位与溢出是两个不同性质的概念,不能混淆。
例如上述例2中,既有进位也有溢出;而例1中,虽无进位却有溢出。可见,两者没有必然
的联系。在微机中,都有检测溢出的办法。为避免产生溢出错误,可用多字节表示更大的
数。
对于字长为16位的二进制数用补码表示时,其范围为-216-1~+216-1-1

即-32768~+32767。判断溢出的双进位式为:
V=D15cD14c
习 题 2
21 为什么说计算机只能“识别”二进制数,并且计算机内部数的存储及运算也都采用二

进制?
22 在进位计数制中,“基数”和“位权(或权)”的含义是什么?一个以b为基数的任

意进制数N,它按位权展开式求值的一般通式是如何描述的?
23 将下列十进制数分别转换为二进制数。
(1)147 (2)4095 (3)0625 (4)015625
24 将下列二进制数分别转换为BCD码。
(1)1011 (2)001 (3)10101101 (4)11011001
25 将下列二进制数分别转换为八进制数和十六进制数。
(1)10101011B (2)1011110011B
(3)001101011B (4)111010100011B
26 选取字长n为8位和16位两种情况,求下列十进制数的原码。
(1)X=+63 (2)Y=-63 (3)Z=+118 (4)W=-118
27 选取字长n为8位和16位两种情况,求下列十进制数的补码。
(1)X=+65 (2)Y=-65 (3)Z=+127 (4)W=-128
28 已知数的补码表示形式如下,分别求出数的真值与原码。
(1)[X]补=78H (2)[Y]补=87H
(3)[Z]补=FFFH (4)[W]补=800H
29 设字长为16位,求下列各二进制数的反码。
(1)X=00100001B (2)Y=-0010000

1B
(3)Z=010*********B (4)W=-010*********B
210 下列各数均为十进制数,试用8位二进制补码计算下列各题,并用16进制数表示器运算结果,同时判断是否有溢出。
(1)(-89)+67 (2)89-(-67)
(3)(-89)-67 (4)(-89)-(-67)
211 分别写出下列字符串的ASCII码
(1)17abc (2)EF98 (3)AB$D (4)This is a number258
212 设X=87H,Y=78H,试在下述两种情况下比较两数的大小。
(1)均为无符号数 (2)均为带符号数(设均为补码)
213 选取字长n为8位,已知数的原码表示如下,求出其补码。
(1)[X]原=01010101 (2)[Y]原=10101010
(3)[Z]原=11111111 (4)[W]原=10000001
214 设给定两个正的浮点数如下:
N1=2P1×S1
N2=2P2×S2
(1)若P1>P2 是否有N1>N2?
(2)若S1和S2均为规格化的数,且P1>P2,是否有N1>N2?
215 设二进制浮点数的阶码有3位、阶符1位、尾数6位、尾符1位,分别将下列各

数表示成规格化的浮点数。
(1)X=11110111 (2)Y=-111101011
(3) Z=-65/128 (4)W=+129/64
216 将下列十进制转换为单精度浮点数。
(1)+15 (2)-10625 (3)+10025 (4)-1200
217 阐述微型计机算在进行算术运算时,所产生的“进位”与“溢出”二者之间的区别


218 选字长n为8位,用补码列出竖式计算下列各式,并且回答是否有溢出?若有溢

出,回答是正溢出还是负溢出?
(1)0111 1001+0111 0000
(2)-0111 1001-0111 0001
(3)0111 1100-0111 1111
(4)-0101 0001+0111 0001
219 若字长为32位的二进制数用补码表示时,试写出其范围的一般表示式及其负数的最

小值与正数的最大值。能否画出32位的补码圆图,并指出它产生正溢出或负溢出的数值?
220 试写出判别32位数补码运算时是否产生溢出的双进位式.

相关文档
最新文档