1.2 微型计算机运算基础
1.2.1 二进制数的运算方法
计算机具有强大的运算能力,它可以进行两种运算:算术运算和逻辑运算。
1.二进制数的算术运算
二进制数的算术运算包括:加、减、乘、除四则运算,下面分别予以介绍。
(1)二进制数的加法
根据“逢二进一”规则,二进制数加法的法则如下:
0+0=0
0+1=1+0=1
1+1=0 (进位为1)
1+1+1=1 (进位为1)
例如,1110和1011相加过程如下:
(2)二进制数的减法
根据“借一有二”的规则,二进制数减法的法则如下:
0-0=0
1-1=0
1-0=1
0-1=1 (借位为1)
例如,1101减去1011的过程如下:
(3)二进制数的乘法
二进制数乘法过程可仿照十进制数乘法进行。但由于二进制数只有0或1两种可能的乘数位,使得二进制数乘法更为简单。二进制数乘法的法则如下:
0×0=0
0×1=1×0=0
1×1=1
例如,1001和1010相乘的过程如下:
由低位到高位,用乘数的每一位去乘被乘数,若乘数的某一位为1,则该次部分积为被乘数;若乘数的某一位为0,则该次部分积为0。某次部分积的最低位必须和本位乘数对齐,所有部分积相加的结果则为相乘得到的乘积。
(4)二进制数的除法
二进制数除法与十进制数除法类似。可先从被除数的最高位开始,将被除数(或中间余数)与除数相比较,若被除数(或中间余数)大于除数,则用被除数(或中间余数)减去除数,商为1,并得到相减之后的中间余数,否则商为0。再将被除数的下一位移下补充到中间余数的末位,重复以上过程,就可得到所要求的各位商数和最终的余数。
例如,100110÷110的过程如下:
所以,100110÷110=110余10。
2.二进制数的逻辑运算
二进制数的逻辑运算包括逻辑加法(“或”运算)、逻辑乘法(“与”运算)、逻辑否定(“非”运算)和逻辑“异或”运算。
(1)逻辑“或”运算
逻辑“或”运算又称为逻辑加,可用符号“+”或“∨”来表示,规则如下:
0+0=0或0∨0=0
0+1=1或0∨1=1
1+0=1或1∨0=1
1+1=1或1∨1=1
可见,两个相“或”的逻辑变量中,只要有一个为1,“或”运算的结果就为1。仅当两个变量都为0时,“或”运算的结果才为0。计算时,要特别注意和算术运算的加法加以区别。
(2)逻辑“与”运算
逻辑“与”运算又称为逻辑乘,常用符号“×”、“·”或“∧”表示,规则如下:
0×1=0或0·1=0或0∧1=0
1×0=0或1·0=0或1∧0=0
1×1=1或1·1=1或1∧1=1
可见,两个相“与”的逻辑变量,只要有一个为0,“与”运算的结果就为0。仅当两个变量都为1时,“与”运算的结果才为1。
(3)逻辑“非”运算
逻辑“非”运算又称为逻辑否定,实际上就是将原逻辑变量的状态求反,规则如下:
可见,在变量的上方加一条横线表示“非”。当逻辑变量为0时,“非”运算的结果为1;当逻辑变量为1时,“非”运算的结果为0。
(4)逻辑“异或”运算
逻辑“异或”运算,常用符号“⊕”或“∀”来表示,规则如下:
0⊕0=0或0∀0=0
0⊕1=1或0∀1=1
1⊕0=1或1∀0=1
1⊕1=0或1∀1=0
可见,当两个相“异或”的逻辑变量取值相同时,“异或”的结果为0;当取值相异时,“异或”的结果为1。
以上仅就逻辑变量只有1位的情况得到了逻辑“与”、“或”、“非”、“异或”运算的运算规则。当逻辑变量为多位时,可在两个逻辑变量对应位之间按上述规则进行运算。特别注意,所有的逻辑运算都是按位进行的,位与位之间没有任何联系,即不存在算术运算过程中的进位或借位关系。下面举例说明。
【例1.1】 两个变量的取值为X=00FFH,Y=5555H,分别求Z1=X∧Y,Z2=X∨Y,,Z4=X⊕Y的值。
解:X=0000000011111111B
Y=0101010101010101B
则 Z1=0000000001010101B=0055H
Z2=0101010111111111B=55FFH
Z3=1111111100000000B=FF00H
Z4=0101010110101010B=55AAH
计算机二进制数算术运算及逻辑运算规则见表1.4。
表1.4 二进制数运算规则一览表
1.2.2 数在计算机中的表示
在计算机中需要处理的数据包括无符号数和有符号数。这些数在计算机中是如何表示的?
1.无符号数
所谓无符号数,通常表示一个数的绝对值,即数的各位都用来表示数值的大小。1字节(8位)二进制数只能表示0~255范围内的数。因此,要表示大于255的数,必须采用多字节来表示,它的长度可以为任意倍字节长,其数据格式如图1.1所示。
图1.1 无符号二进制数表示格式
2.有符号数
所谓有符号数,即用来表示一个任意位长的正数或负数。我们知道,在普通数字中,区分正负数是通过在数的绝对值前面加上符号来表示的,即“+”表示正数,“-”表示负数。在计算机中,数的符号也数码化了,一般用一个数的最高位作为符号位,用“0”表示正号,用“1”表示负号,而其余位为数值位。其数据格式如图1.2所示。
图1.2 有符号二进制数表示格式
3.有符号数的原码、反码、补码及补码运算
带正、负号的二进制数称为数的真值表示。
例如:X=+1010110B,Y=-0110101B
为了运算方便,计算机中的有符号数有三种表示方法,即原码、反码和补码,称为机器数。
(1)原码
正数的符号位用“0”表示,负数的符号位用“1”表示,其余数字位表示数值本身,这种表示法称为原码。
前例X、Y可表示为:
[X]原=01010110B,[Y]原=10110101B
对于0,可以认为它是+0,也可以认为它是-0。因此在原码中,0有下列两种表示:
[+0]原=00000000B,[-0]原=10000000B
原码表示数的方法很简单,只需要在真值的基础上,将符号位用数码“0”和“1”表示即可。但采用原码表示的数在计算机中进行加、减运算时很麻烦。例如:遇到两个异号数相加或两个同号数相减时,就要用减法运算。为了把减法运算转变成加法运算,引入了反码和补码。
(2)反码
在原码表示的基础上很容易求得一个数的反码。正数的反码与原码相同,而负数的反码则是在原码的基础上,符号位不变(仍为1),其余数位按位求反,即0→1,1→0。
前例X、Y可表示为:
[X]反=01010110B,[Y]反=11001010B
而 [+0]反=00000000B,[-0]反=11111111B
(3)补码
一个数的补码也很容易求得。如果是正数,补码同原码也同反码,如果是负数,则在反码的基础上最末位加1。
前例X、Y可表示为:
[X]补=01010110B=[X]反=[X]原,[Y]补=11001011B
注:补码中0只有一种表示,无正负之分,即
[+0]补=[-0]补=00000000B
不难证明,补码具有如下特性:
[[X]补]补=[X]原
用8位二进制数来表示无符号数及有符号数的原码、反码、补码时的对应关系见表1.5。
表1.5 用8位二进制数来表示无符号数及有符号数的原码、反码、补码时的对应关系
由表1.5可知,用8位二进制数,表示无符号数的范围为0~255;表示原码的范围为-127~+127;表示反码的范围为-127~+127;表示补码的范围为-128~+127。
(4)补码运算
两个用补码表示的有符号数进行加、减运算时,其特点是把符号位上表示正、负的“0”和“1”也看成数,与数值部分一同进行运算,所得的结果也为补码形式。即结果的符号位为“0”,表示正数;结果的符号位为“1”,表示负数。下面分加、减两种情况予以讨论。
两个有符号数X和Y进行相加时,先将两个数分别转换为补码的形式,然后进行补码加运算,所得的结果为和的补码形式,即:
[X+Y]补=[X]补+[Y]补
【例1.2】 用补码进行下列运算:
① (+18)+(-15);②(-18)+(+15);③(-18)+(-11)。
解:
由例1.2可知,当带符号的数采用补码形式进行相加运算时,可把符号位也当作普通数字一样与数值部分一起进行加法运算。若符号位上产生进位时,则自动丢掉,所得的结果为两数之和的补码形式。如果想得到运算后原码的结果,可对运算结果再求一次补码即可。
两个有符号数相减,可通过下面的公式进行:
X-Y=X+(-Y)
则 [X-Y]补=[X+(-Y)]补=[X]补+[-Y]补
可见,求[X-Y]补,可以用[X]补和[-Y]补相加来实现。这里关键在于求[-Y]补。如果已知[Y]补,那么对[Y]补的每位(包括符号位)都按位求反,然后末位加1,结果即为[-Y]补(证明略)。一般称[-Y]补为对[Y]补的“变补”,即[[Y]补]变补=[-Y]补;已知[Y]补求[-Y]补的过程称为变补。
这样,求两个带符号的二进制数之差,可以用“减数(补码)变补与被减数(补码)相加”来实现。这是补码表示法的主要优点之一。
【例1.3】 用补码进行下列运算:
① 96-19; ② (-56)-(-17)。
解:① X=96,Y=19,则
[X]补=01100000
[Y]补=00010011
[-Y]补=11101101
故 [X-Y]补=[X-Y]原=01001101=+77
② X=-56,Y=-17,则
[X]补=11001000
[Y]补=11101111
[-Y]=00010001补
则 [X-Y]补=11011001
故 [X-Y]原=[[X-Y]补]补=10100111=-39
综上所述,对于补码的加、减运算可用下边一般公式表示:
[X±Y]补=[X]补+[±Y]补(|X|,|Y|及|X±Y都小于2n+1)
(5)溢出判断
当两个有符号数进行补码运算时,若运算结果的绝对值超出运算装置容量,数值部分就会发生溢出,占据符号位的位置,导致错误的结果。这种现象通常称为补码溢出,简称溢出。这和正常运算时符号位的进位自动丢失在性质上是不同的。下面举例说明。
【例如1.4】 某运算装置共有5位,除最高位表示符号位外,还有4位用来表示数值。先看下面两组运算。
① 计算13+7=?
② 计算(-4)+(-4)=?
① 数的运算结果显然是错误的,因为两个正数相加不可能得到负数的结果,产生错误的原因是由于两个数相加后的数值超出了加法装置所允许位数(数值部分4位),因而从数值的最高位向符号位产生了进位,或者说这种现象是由于“溢出”而造成的。②的结果显然是正确的,由符号位产生的进位自动丢失。
为了保证运算结果的正确性,计算机必须能够判别出是正常进位还是发生了溢出错误。计算机中常用的溢出判别称为双高位判别法,并常用“异或”电路来实现溢出判别。其表达式为:
CS⊕CP=1(表示发生了溢出错误)
式中,
CS——最高位(符号位)产生进位的情况。CS=1,有进位;CS=0,无进位。
CP——次高位(数值部分最高位)向符号位产生进位的情况。CP=1,有进位;CP=0,无进位。
由表达式可知,在运算结果中,当CS和CP状态不同(为01或10)时,产生溢出;在运算结果中,当CS和CP状态相同(为00或11)时,不产生溢出。
发生溢出时,CSCP=01为正溢出,通常出现在两个正数相加时;CSCP=10为负溢出,通常出现在两个负数相加时。考察上面的两例。当CS⊕CP=0⊕1=1时,有溢出,为正溢出。当CS⊕CP=1⊕1=0时,无溢出,从而可知,一个正数和一个负数相加时,它们的和肯定不会发生溢出。下面举例说明溢出判别。
【例1.5】 计算64+65=?
由于CS⊕CP=0⊕1=1产生溢出,并且是正溢出,导致运算结果出错。
【例1.6】 计算-110-92=?
由于CS⊕CP=1⊕0=1,产生溢出,并且是负溢出,结果出错。
【例1.7】 计算-117+121=?
一个负数和一个正数相加,结果不溢出。此时,CS⊕CP=1⊕1=0。
1.2.3 数的编码方法
在计算机中,所有用到的数字、字母、符号、指令等都必须用特定的二进制码来表示,这就是二进制编码。
1.二进制编码的十进制数
计算机只能识别二进制数,但人们熟悉的却是十进制数。所以在计算机输入和输出数据时,往往采用十进制数表示。不过,这样的十进制数是用二进制编码表示的,称为二进制编码的十进制数——BCD(binary code decimal)码。
用二进制数为十进制数编码,每位十进制数需要用4位二进制数来表示。4位二进制数共有16种编码形式,由于十进制数只有0~9共10个数码,故有6个编码是多余的,放弃不用。而这种多余性便产生了多种不同的BCD码。在计算机中较常用的是8421 BCD码(在以后的章节中简称为BCD码)。这种BCD码用4位二进制数表示1位十进制数的数码0~9,权值从高位到低位依次为8,4,2,1。BCD编码见表1.6。
表1.6 8421 BCD码编码表
例如:(208)10=(001000001000)8421 BCD
(1001000101110101)8421 BCD=(9175)10
2.字母与符号的编码
在计算机中,字母和符号也必须用特定的二进制编码来表示。目前,在计算机、通信设备及仪器仪表中广泛采用的是美国标准信息交换码(ASCII,American standard code for information interchange)。它用7位二进制编码表示一个字母或符号,共能表示27=128个不同的字符。其中包括数字0~9、英文大写字母、英文小写字母、运算符、标点及其他的一些控制符号。常用的7位ASCII码见表1.7。
表1.7 美国标准信息交换码ASCII编码
例如:数字0的ASCII码为0110000B或30H,
数字9的ASCII码为0111001B或39H,
字母A的ASCII码为1000001B或41H。
ASCII编码多用于微型计算机的输入/输出设备(如电传打字机)及在数据传送过程中进行奇偶校验。