汇编语言程序设计(第2版)
上QQ阅读APP看书,第一时间看更新

1.2 计算机中数据的表示

1.2.1 不同进位计数制及其相互转换

1.二进制数

进位计数制是一种计数方法,我们最熟悉的是十进制数,如423.5可表示为:

423.5=4×102+2×101+3×100+5×10-1

注意到这里每位数字只能取0到9共10个数字符号,因此基数为10,逢10进1。不同位置上的数字代表的“权”是不同的,如百位4,该位的权值为102,第k位的权值为10k

计算机为便于数字电路对数据存储及计算的物理实现,采用二进制数。二进制数只有0和1两个数码,基数为2,逢2进1。不同位置上的数码代表的“权”不同,即各位权值为2k。例如二进制数:101101(B)=1×25+1×23+1×22+1×20=45(D)。

可以看出,上面的二进制数按权展开就得到对应的十进制数。为便于明确计数制而不致误解,通常在二进制数后面加(B),在十进制数后面加(D)(也可用下标2和下标10),即:

101101(B)=45(D),也可表示为101101B=45D,或(101101)2=(45)10

n位二进制数可以表示2n个数,例如4位二进制数可以表示24=16个数,如表1-1所示。

表1-1 二进制与十进制

2.十六进制数

用二进制数表示一个较大的数总是不太方便,为便于程序员表示数据,通常还采用十六进制。

十六进制数有16个数码,基数为16,逢16进1。第k位置上的数码代表的权值为16k。每位的数码作如下规定:0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,共16个数码。其中A,B,C,D,E,F分别表示十进制的10,11,12,13,14,15。十六进制数后面要加上H以示区别。

例如十六进制数:

5FH=5×161+15×160=80+15=95D

显然十六进制表示比二进制表示来得简洁,该数用二进制表示则为:

5FH=01011111B

注意到一位十六进制数用四位二进制数表示即可,反之亦然。可见二进制数与十六进制数有着简单直接的互相转换关系,这是因为十六进制数的基数是2的幂。不仅如此,二进制数与2k进制数都可以简单直接地互相转换。

实际生活中存在多种计数制,如计时采用时分秒就是60进制。其道理都是一样的。

3.二进制数、十六进制数转换为十进制数

如前所述,各位二进制数乘以对应的权之和即得到十进制数。如:

例1.1N=101101.1B=1×25+1×23+1×22+1×20+1×2-1=45.5D

各位十六进制数乘以对应的权之和即得到十进制数。如:

例1.2N=5FH=5×161+15×160=80+15=95D

4.十进制数转换为二进制数

这里介绍常用的两种方法。

(1)降幂法(适用于数值不大的数),降幂法就是先写出小于此数的各位二进制权值,然后再求和。

例1.3求N=13.5D的二进制数。小于此数的各位二进制权值为:

8  4  2  1  0.5

显然应选8,再选4,而不能选2(因为8+4+2=14),再选1,最后选0.5,所以:

13.5D=8+4+1+0.5=1101.1B

(2)除法(又叫除2取余法,仅适用于整数部分),除2取余法就是不断除以2,记下余数,直到商为0为止。

例1.4求N=13D的二进制数。

13D=b3b2b1b0=1101B

特别注意,对于二进制数的小数部分除了用降幂法也可采用乘法,即不断乘以2,并记下整数,而小数部分再乘以2,直到结果的小数部分为0为止。注意:并非所有的十进制小数都能用二进制完全表示,如小数0.3,这时按实际需要取一定精度表示即可。

例1.5求N=0.625D的二进制数。

5.十进制数转换为十六进制数

和十进制数转换为二进制数类似,也有降幂法和除法。

(1)降幂法(适用于数值不大的数),降幂法就是先写出小于此数的各位十六进制数权值,然后再求和。

例1.6求N=95D的十六进制数。小于此数的各位十六进制权值为:

16   1

显然应选16×5,再选1×F,所以

N=95D=80+15=16×5+1×F=5FH

(2)除法(又叫除16取余法,仅适用于整数部分),除16取余法就是不断除以16,记下余数,直到商为0为止。

例1.7求N=95D的十六进制数。

同样特别注意,对于十进制数的小数部分除了用降幂法也可采用乘法,即不断乘以16,并记下整数,而小数部分再乘以16,直到结果的小数部分为0为止。不再举例。

6.二进制数和十六进制数的相互转换

由于十六进制数的基数16=24,故一位十六进制数由四位二进制数组成,相互转换极为简单。

例1.8N=1011111.11(B)=01011111.1100(B)=5F.C(H)

注意到从二进制数转换到十六进制数时,二进制数的整数部分从最低位开始每4位一组,不足4位的,高位补0补足4位。小数部分从最高位开始每4位一组,不足4位的,低位补0补足4位。

1.2.2 二进制数和十六进制数的运算

1.二进制数的运算规则

加法规则:0+0=0,0+1=1,1+1=0(进位1)

乘法规则:0×0=0,0×1=0,1×1=1

2.十六进制数的运算

十六进制数的加减运算只要遵循逢16进1规则即可,当然也可先把十六进制数转换为二进制数,运算后的结果再转换为十六进制数。

例1.9

例1.10

十六进制数的乘、除法运算可以先把十六进制数转换为十进制数,运算后的结果再转换为十六进制数。十六进制数的乘法也可以用十进制数的乘法规则计算,但结果用十六进制数表示。

例1.11

1.2.3 带符号数的补码表示

数分为正数和负数,计算机中的数是用二进制来表示的,数的符号也用二进制来表示,所谓带符号数就是最高位是符号位,一般规定正数的符号位为0,负数的符号位为1。把一个数连同其符号在内数值化表示叫机器数,机器数的表示可以用不同的码制,常用的有原码、补码、反码。这里只介绍最常用的补码。

补码表示法中的正数用符号位+绝对值表示,即数的最高位为0,其余部分为该数的绝对值。例如,用8位二进制来表示,

[+1]=00000001,[+127]=01111111,[+0]=00000000。

负数用补码表示时,方法是对其正数各位取反,然后最低位加1。我们把这种对二进制数取反加1的运算叫作求补运算。负数用补码表示时,其符号位必定为1。

例1.12用8位二进制来表示,求[-3]

先写出+3:  0000 0011

各位取反为:1111 1100

最低位加1为:1111 1101

[-3]=1111 1101,或用十六进制表示,[-3]=FDH。

读者也许会问,如何用16位二进制来表示[-3]呢?其实只要在刚求出的[-3]的前面加上8个1就可以了,即[-3]=1111 1111 1111 1101,或[-3]=FFFDH。这叫符号扩展。对负数的符号扩展只需在前面补1,对正数的符号扩展只需在前面补0,符号扩展并没有改变数的大小,只是改变了位数。读者可自行验证。

我们已经知道对负数用补码表示时,方法是对其正数取反加1,即作求补运算。其实这个方法是根据补码定义得出的。下面给出证明。

补码定义:

(X≥0时) [X]=符号+|X|   ---(1)

(X<0时) [X]=2n-|X|    ---(2)

现在我们把(2)式进一步改写,

[X]=2n-|X|=(2n-1-|X|)+1   ---(3)

请注意(3)式右边括号中的(2 n-1-|X|),就是对|X|取反码。再+1就得到[X]。由此可见,求负数的补码,方法是对其正数取反加1。

现在我们把(3)式进一步改写,

|X|=2n-[X]=(2n-1-[X])+1     ---(4)

注意到上式右边的(2 n-1-[X])+1,就是对[X]再求补码,就得到|X|。由(3)式和(4)式说明了以下结论:

例1.13依据补码定义写出以下各数的补码,以8位二进制表示。

[-1]=28-1=1 0000 0000-1=1111 1111,直接由(2)式得到。

[-127]=28-127=(28-1-127)+1

=(1111 1111-0111 1111)+1

=1000 0000+1

=1000 0001

依据补码定义求一个数的补码表示,有些繁琐,用取反加1的规则更为简便。

例1.14识别以下各数的十进制值。

[a]=1111 1111,求补后为0000 0001=[1],所以,a=-1

[b]=1000 0000,求补后为1000 0000=[128],所以,b=-128

[c]=1000 0001,求补后为0111 1111=[127],所以,c=-127

前面我们都是以8位二进制数讨论,8位二进制数可以表示28=256个数,当它们是补码表示的数时,所能表示的数值的范围是-128≤N≤+127。

1.2.4 补码的加法和减法

计算机中主要是用补码表示数据,因此我们应关注补码的加法和减法。

补码的加法规则是:

[X+Y]=[X]+[Y]       ----(5)

[X-Y]=[X]+[-Y]       ----(6)

补码的减法规则是:

这个规则说明了用2个数的补码相加就可以完成2个数的加减法,得到的还是补码。

下面给出证明:

需明确X>0,Y>0,先看(5)式,由补码定义可知,[X+Y]=X+Y=[X]+[Y]

(5)式得证。再看(6)式:

如果[X-Y]≥0,由补码定义可知,(6)式左边应有[X-Y]=X-Y,

而(6)式右边=X+(2n-Y)=X-Y+2n=X-Y

如果[X-Y]<0,(或者说Y>X),

应有[X-Y]=2n-|X-Y|=2n-(Y-X)=2n-Y+X=[-Y]+[X]

(6)式得证。

下面给出例子说明补码的加法运算。

例1.158位补码的加法运算。

从例中可以看出补码的加法很简便,不必考虑数的正负,符号位参与运算即可,计算结果都是正确的。从最高有效位向高位的进位由于机器字长的限制而自动丢弃,但结果依然正确。同时这个进位被保存到机器中的标志寄存器中,其作用以后再说明。

1.2.5 无符号数的表示

如果要处理的数全是正数,保留符号位就没有必要,我们可以把最高有效位也作为数值,这样的数就叫无符号数。用8位二进制来表示的无符号数的数值范围是0≤N≤255,用16位二进制来表示的无符号数的数值范围是0≤N≤65535。在计算机中最常见的无符号数是表示内存单元的地址。例如:1100 0010B=C2H=194D,而不再表示一个负数。

1.2.6 字符的表示

除了数值以外,人们有时还需要用计算机处理字符或字符串。例如,从键盘输入或打印输出信息都是以字符方式输入/输出的。字符包括:

字母:A,B,C,D……

数字:0,1,2,3……

专门符号:+,-,×,/,SP(space空格)……

非打印字符:CR(carriage return回车),LF(line feed换行)……

这些字符必须采用二进制的编码方式,目前采用最常用的美国信息交换标准代码 ASCII(American Standard Code for Information Interchange)来表示。

这种代码用一个字节(8位二进制码)来表示一个字符,其中低7位为字符的ASCII值,故能表示128个符号和代码,最高位一般用作检测校验位,见表1-2。

为了能表示更多的符号,将7位ASCII码扩充到8位,就可以表示256个符号和代码,称为扩充的ASCII码。

表1-2 部分常用字符的7位ASCII码表(十六进制表示)

1.2.7 基本逻辑运算

四种基本逻辑运算见表1-3。

表1-3 四种基本逻辑运算

(1)“与”运算(AND),又叫逻辑乘,可用符号·或∧来表示,只有当逻辑变量A、B都为1时,“与”运算的结果才为1。

(2)“或”运算(OR),又叫逻辑加,可用符号+或∨来表示,只要变量A、B其中有一个为1时,“或”运算的结果就为1。

(3)“异或”运算(XOR),可用符号∀来表示,只有当变量A、B中仅一个为1时,“异或”运算的结果才为1。

(4)“非”运算(NOT),对变量A取反,即如果A=1,则=0,反之亦然。

逻辑运算都是按位操作,例如,X=0011,Y=1011,均为二进制数,则有:

X(AND)Y=0011,X(OR)Y=1011,X(XOR)Y=1000,(NOT)X=1100