<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > 單片機的加減法原理

單片機的加減法原理

作者: 時(shí)間:2016-11-17 來(lái)源:網(wǎng)絡(luò ) 收藏
這是計算機組成原理的問(wèn)題。計算機怎么表示負數。最高位為0,表示正數,最高位為1表示負數,例如

0b 0000 0011 表示 +3

本文引用地址:http://dyxdggzs.com/article/201611/315476.htm

0b 1111 1111 表示 -1

所以,那么數值的取值范圍就是這么來(lái)的,一個(gè)字節有8位,如果是無(wú)符號數,那么就能表示 0~255 一共 256個(gè)數,但是如果是有符號數,也就是說(shuō)這8位里面還需要表示一個(gè)符號,而且負號在最高位,那么數值只能是 bit0 ~ bit 7 表示,也就是說(shuō) -128 ~ 127

計算機里面做的運算都是補碼運算,有符號數還是無(wú)符號數,計算機是不管的,其實(shí)這個(gè)只是寫(xiě)給編譯器看的,由編譯器去識別。并且生成相對應的代碼。

原碼,反碼,補碼的變換

原碼,本來(lái)的數據叫原碼,反碼是各位取反,補碼有具體的運算規則。

例如signed char 類(lèi)型的數據 +3

原碼 0b 0000 0011 最高位為0,表示正數。

反碼 0b 1111 1100 很簡(jiǎn)單,各位取反。

補碼運算規則

1, 如果是正數,那么補碼=原碼

2, 如果是負數,那么補碼=原碼的反碼+1

上面例子,+3的補碼為 0b 0000 0011 ,和原碼一樣。

如果換成 -3 那么情況就是

0000 0011 à 1111 1100 + 1 à 1111 1101 這個(gè)就是 -3 的補碼,計算機就是這樣表示負數的。

于是今天研究了一下EMC單片機的加減運算

由于是用匯編寫(xiě)的,那么就壓根沒(méi)有所謂的有符號數和無(wú)符號數的區別。所以程序里面可以認為的認定,也就是我,我認為是他有符號,還是無(wú)符號。最麻煩的就是越界問(wèn)題,數據過(guò)大溢出了。但是只需要記住一點(diǎn),單片機電路是按照補碼運算的,依稀的記憶中想起了當年數字電路課程里面出現的東西,不過(guò)記憶已經(jīng)很模糊了。得復習一下。

最重要的是:計算機里面都是按照補碼來(lái)運算的??!這是由數字邏輯電路決定的。

怎么和 C 進(jìn)位聯(lián)合起來(lái)。于是我想從幾種情況分析。

1, 加法的情況,2+3 = 5 ,只要是智力沒(méi)有問(wèn)題的都不會(huì )算錯吧 ……

單片機里面的情況,我們認為這個(gè)是有符號數,那么就是2個(gè)正數相加,

這里要注意的,“我當他是有符號數”是我人為加以假設,單片機可不吃這一套,反正,只要執行 mov 指令將數據送到單片機,那么單片機就認為這是補碼,他可不管你有沒(méi)有符號。

那么過(guò)程是這樣:

大腦里面人為這兩個(gè)是補碼,那么根據補碼的運算規則,正數的補碼就是原碼,得到

0000 0010

+ 0000 0011

--------------------------

0000 0101

進(jìn)位 C=0 表示加法沒(méi)有溢出。

這就是單片機的運算結果了。

單片機就是得到這個(gè)東西,這個(gè)是一個(gè)補碼,因為單片機只認識補碼,其他他不認識。那么然后我們將做小處理。

如果我們大腦將他看成是無(wú)符號數,那么這里表示的是 5 ,如果我們將他看成有符號數,那么這里表示的就是 +5 (因為最高位為0,原碼和補碼相同)

2, 如果兩個(gè)數據比較大,相加會(huì )溢出,這怎么處理。0xff+0xff = ?

1111 1111

+ 1111 1111

--------------------------

1 1111 1110

進(jìn)位 C=1 表示加法運算有進(jìn)位。

那么其實(shí)這里表示的是 FF + FF =1FE ,C代表最高位,跟普通加法運算是一樣的,因為計算機當成補碼,他不管你什么數,他就按照補碼運算。

3, 減法運算,差是正數: 3-2 = 1

前面加法,補碼基本上沒(méi)啥出場(chǎng)機會(huì ),但是減法就不同,減法就是補碼發(fā)揮作用的時(shí)候。記以前數字電路的老師說(shuō)過(guò),數字電路只有加法器(全加器和半加器),是沒(méi)有減法器的,所以計算機對待減法運算,實(shí)際上是用加法運算代替的。那么

3-2 可以轉化為 3+(-2) 這個(gè)就是加法運算了。然后考慮兩個(gè)數的補碼。3為正數,所以補碼為原碼本身,-2 為負數,補碼為反碼后再加1,那么加過(guò)是

3 :0011

-2 :1110

那么 3-2 單片機運算的結果,實(shí)際上相當于 0011 + 1110 的結果,是

0000 0011

+ 1111 1110

--------------------------

1 0000 0001

C=1表示減法沒(méi)有借位,結果為 00000001,這是一個(gè)補碼,因此這個(gè)是正數,所以原碼是他本身,也即是說(shuō)結果為 1 ,沒(méi)有錯位,也就是說(shuō) 被減數大于減數。

EMC單片機的代碼是:

mov a,@3

mov 0x20,a

mov a,@2

sub 0x20,a

0x20存放最終結果,仿真運行結果,0x20數值為 1,C=1表示沒(méi)有借位,Z=0表示運算結果非零。這個(gè)跟我們分析的完全吻合。

我們推廣一下:

既然我們說(shuō)了 3-2 最終會(huì )被計算機轉化為補碼加法,那么我將上面的EMC單片機的代碼手工做成加法,那么期待得到的結果應該是一樣的。

mov a,@3

mov 0x20,a

mov a,@0xfe

add 0x20,a

仿真運行結果,0x20數值為 1,C=1表示加法運算進(jìn)位了,Z=0表示運算結果非零。這個(gè)跟上面的減法運算結果是一模一樣的。這就是我們期待的結果,證明了單片機里面是補碼的運算。

4, 減法運算,差是負數,也就是說(shuō)不夠減,例如 2-3 = -1

這個(gè)運算在單片機里面究竟是怎么進(jìn)行的呢?其實(shí)也很簡(jiǎn)單,記住我們的信條:“單片機里面都是補碼運算”那么很自然的化成 2 + (-3),求出 2 和 -3的補碼并進(jìn)行運算

0000 0010

+ 1111 1101

--------------------------

0 1111 1111

進(jìn)位位C = 0表示減法運算發(fā)生錯位,結果是 0b11111111,這就是最終結果了。

但是這個(gè)值我們要看的懂,必須變化為原碼,說(shuō)過(guò)了,這是一個(gè)補碼,最高位為1表示這是一個(gè)負數,所以求原碼的辦法,也是將補碼取反再加一,也就是

0b11111111 à 0b00000000+1 à 0b00000001

這個(gè)就是我們最終的結果,是一個(gè)負數,絕對值為1,也就是說(shuō)結果為 -1

這跟我們期待的結果是一模一樣的。EMC單片機仿真代碼以及結果:

mov a,@2

mov 0x20,a

mov a,@3

sub 0x20,a

寄存器0x20的值為 0xff,進(jìn)位C=0表示減法發(fā)生了錯位,Z=0表示結果非零。

這完全和我們分析的吻合。再強調,單片機里面出現的都是補碼,所以這結果的 0xff 也是補碼,想看懂得轉化為原碼。上面已經(jīng)說(shuō)了轉化辦法。

另外,我們需要分開(kāi)來(lái)看,我們上面是說(shuō)將這個(gè)數字看成是“有符號數”,2-3=-1這個(gè)是我們要的結果,但是,如果我們把這個(gè)數看成是“無(wú)符號數”那又該怎么辦呢?

辦法就是,借位,跟我們手工減法一樣,不夠減就向高位借位。

2-3 = 0010 – 0011 這是不夠減的,那么 2應該向高位借一,變成 10010 – 0011 = 1111,這里扮演高位的其實(shí)就是進(jìn)位C,也就是說(shuō)C=0時(shí)是發(fā)生錯位的,為什么?因為這個(gè)C=1被被減數借去用了,結果為 0xff ,這個(gè)時(shí)候 0xff 就是我們想要的結果,不需要變化,因為我們不是看成有符號數。

5, 兩個(gè)數比較大小 CMP A , B

兩個(gè)數比較大小,記得以前微機原理的老師給我們說(shuō)了,本質(zhì)就是做減法運算,然后判斷標志位。EMC單片機沒(méi)有CMP比較指令,但是我們通過(guò)減法指令可以達到目的,從本質(zhì)上說(shuō),那是一致的。

因為這些邏輯判斷是固定的,而且比較繁瑣,容易出錯,所以是建議做成宏調用,這樣跟其他單片機上面的 CMP指令是一樣使用的,比較方便。

(1)A>B

A-B >0 我們一定要強調順序,也就是說(shuō),誰(shuí)減去誰(shuí) 的問(wèn)題,不能搞亂。A-B操作之后PSW的標志位狀態(tài)

C=1表示沒(méi)有借位,Z=0 表示結果不為0

(2)A=B

C=1 表示沒(méi)有借位,Z=1表示結果為0

(3)A

C=0 表示借位,Z=0表示結果不為0

那么很簡(jiǎn)單推導出另外兩個(gè)常用的關(guān)系:

(4)A >= B

C=1 或者 Z=1,通過(guò)Z能判斷是否相等。

(5)A <= B

明顯這里是或關(guān)系C =0 或者 Z=1 都滿(mǎn)足條件判斷。

(6)A != B

很簡(jiǎn)單,只需要 Z=1 就能滿(mǎn)足要求

根據這5個(gè)關(guān)系,寫(xiě)成5個(gè)常用的宏,將給程序編寫(xiě)帶來(lái)非常大的方便。具體實(shí)現代碼在EMCLIB庫里面/arch/generic.dt里面。



關(guān)鍵詞: 單片機加減法原

評論


技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>