导航

使用bis和bic两种指令实现位运算

Posted on 2014-04-04 19:23  Rohan  阅读(1192)  评论(0)    收藏  举报

 

在《深入理解计算机系统》一书的第二章35页,有一个很有意思的小问题。

讲20世纪70年代末到80年代末,Digital Equipment的VAX计算机很流行。但是它却没有布尔运算AND和OR指令,只有bis(位设置)和bic(位清除)两种指令。输入都为一个数x和一个掩码m

其中,两个函数均在m为1的每个位置上,对x相应位置设置为1。

 

现在,要求只用这两个函数来实现C语言的|和^运算。且不使用任何其他的C语言运算

 

一开始第一个想法:自然是建立bis与bic与传统逻辑或与非之间的联系。

只要证明能用bis与bic表示非运算,以及'与''或'运算两者任意之一,就可以证明这两个函数是逻辑完备的。

 

'或' 性质显然:bis(x , y) = x | y

接下来就是表示非了:

bic(~0, x) = ~x

看上去好像问题已经解决了:建立了bis,bic与或非的联系。使用德摩根律得到'与'的表示:x & y = ~(~x | ~y)

接下来只要将异或表示为几种基本逻辑运算的组合:x ^ y = (x | y) & ~(x & y)

然后再翻译为bis,bic语言就行。

 

不过还没有结束。

题目的要求是不使用任何其他的C语言运算。

而在'非'的实现中

bic(~0, x) = ~x  里面却是对0做了一次取反运算。

或许说用0xfffff…..ffff 一堆1来代替0,就可以省掉这次运算了。但很明显,这种投机取巧的丑陋做法是不好的。

所以最终还是要祭出逻辑学的终极大杀器——真值表

 

x

y

bis(x,y)

bic(x,y)

x ^ y

0

0

0

0

0

0

1

1

0

1

1

0

1

1

1

1

1

1

0

0

 

嗯。。通过观察可以发现,若是想要用bis,bic拼凑出x^y的真值。

我们可以用两个次序相反的x,y进行bic运算,然后得到01和10对应的两个1,将它们一并,就得到了x^y

而并的实现,就是使用一次bis

 

所以最终的答案是

x^y = bis(bic(x,y),bic(y,x))