1.6逻辑运算
逻辑运算在我们今后的编程中会经常使用到的。
本节必须掌握的知识点:
u 掌握逻辑运算
计算机中所有的数据都是使用二进制保存,但是这些复杂的电路又是如何做运算的呢?
逻辑运算是CPU运算的本质,不管是计算机能处理多么复杂的事情,它最终还是通过电路的开关来实现的。逻辑是指对某个事物的推理,“真”和“假”是两个对立的逻辑状态,逻辑运算是指用数学符号来表示逻辑状态,以便于用数学方法研究逻辑问题。我们通常将电路通电状态表示为“真”,用数字“1”表示,不通电表示为“假”,用数字“0”表示。“或”、“与”、“非”是三种基本逻辑运算,计算机逻辑运算也包含“异或”、“位”。
1、或运算
或运算:汇编中用“OR”表示,C语言中用“|”来表示,可以理解为“或者”,即只要有一个条件满足就为“真”,用电路来描述:只要有一条电路通电这条总电路就能通电,原理如图1-6-1:
这是一个并联电路图,不管是A为闭合状态、还是B为闭合状态,还是AB都处于闭合状态,电灯泡都能亮。我们把电路图用符号0和1来表示,或运算表示只要有一个为1,结果就为1。我们来看一个宽度为8的或运算:
与运算:汇编中用“and”表示,C语言中用“&”来表示,它表示两个条件都成立才能为真,即两个都为1结果为1,其他为0,电路实现原理如图1-6-2:
这是一个串联电路图,A和B都为闭合状态,灯泡才能亮。如果有一个开关没有闭合,灯泡是不能亮的。即两个都为1,结果为1,只要有一个为0 ,结果为0。
我们来看一下下面的运算:
3、异或
异或:汇编用“xor”表示,C语言中用“^”表示,这个不是太好理解,但是它很有用。它表示两个值不同为真,相同为假。即两个值如果都为0或者1,结果为0。一个为0,而另一个为1,结果为1。如图1-6-3所示;
这条电路A和B必须是相反的两种状态灯泡才能亮,如果AB都断开,灯泡无疑是不亮的,如果AB都连上,正负极抵消,灯泡同样不能亮。我们来看一下下面的运算:
4、非运算
非运算:汇编中用“NOT”表示,C语言中用“!”表示,它是对某个值求反的运算。如 !0 = 1;!1 = 0;非真即为假,非假即为真。
我们来看一下下面的运算:
5、左移运算
左移运算:在右边添0,数据往左移动,用符号“<<”表示,如“0010 << 1 ”表示将0010左移1位,结果为0100。
6、右移运算
右移运算:在左边添0,数据往右移动,用符号“>>”表示,如“0010 >> 1”表示将0010右移1位,结果为0001。
计算机的本质是逻辑运算,不管多么复杂的运算最终都回归到逻辑运算。可是我们生活当中的计算并不是逻辑运算,这又是怎么回事呢?那么CPU是如何通过逻辑运算做“+、-、*、/”的呢?虽然我们平常生活中并不会碰到这个问题,但是可以做一些简单的了解,能帮助我们更清楚地认识计算机的本质。
我们来看一下CPU是如何算出2+3等于5的。
计算机如果要做运算,必须要把2和3分别存储下来,就是先用几条线路来表示它们。前面我们学数据宽度时讲到容器,那我们就用最少的容器来保存2和3。假设有BYTE x保存2,BYTE y 保存3,那这两个容器里的数值是这样的:
这个结果放在哪呢?我们再拿一个容器R来保存,假设它的宽度也是8位,此时R的值为:0000 0001。
第二步,CPU再让它们进行与运算:
这一步是为了测试上一步有没有结束。
再将这个结果左移1位,如果这个值等于0,那R就是计算的结果,不为0重复之前的操作。0000 0010左移1位等于0000 0100,不为0,所以继续运算, 将R容器里的值放到x容器中,把与(and)的值放在y里,
x: 0000 0001
y: 0000 0100
继续之前的操作,先将它们异或,值为0000 0101,将这个值存到R容器。再将x容器和y容器里的与运算,值为0000 0000。将它左移一位还是0,所以R的值就是我们计算的结果,即为0000 0101,转换为十进制就是5。
2+3对于我们来说,幼儿园就会算了,而计算机却要执行如此多步骤。其实计算机很笨,它只会按照一定规则去操作,但是它却靠着比我们人类快无数倍的速度帮我们人类解决很多棘手的问题。
比如我们的寄存器每一位代表不同的含义,假如需要判断某一位的值,或者更改某一位的值、而其他的值保持不变,那怎么才能做到呢?如有个数值,我想知道它的第3位是否为1,应该怎么运算呢?根据前面的逻辑运算,我们知道与运算的法则是“有0为0,两个都为1才为1”,所以我们可以设置一个第3位为1的值,无论我们要测试的值是几位数,我们只需要将它与0100进行与运算即可。当这个值与“0100”进行与运算,只能是两个结果,一个结果为0,一个结果为 0100,也就是结果只有两种情况:“0”和“非0”,若为0,这个数值的第3位为0,反之,不为零。
所以我们可以利用与、或的特点,我们来验证一下,假设有个要测试的值为8F,我们要测试它的第5位是否为0。
根据之前的方法,我们将它和“0001 0000”相与:
异或在加密算法里经常遇到,两次异或同一个值,就会还原成异或原来的值。这个需要异或的值我们叫做密钥。采用异或加密的时候,密钥的作用很关键。谍战片里的那些电报也是加密的,常常因为一本密码本剧情起伏不断,可见密钥的重要性。
比如我们要加密0x2015,密钥为:0x54计算如下:
加密:每两位十六进制数分别与54进行异或:
u下一节进入汇编章节。
1、八进制数2-5在计算器中的结果是:1777777777777777775,为什么?2、使用异或对87AD6进行加密后再解密,加解密密匙:5 3、只用逻辑运算计算2-3=?(涉及内容:逻辑运算、移位、数据宽度)