向繼文
關(guān)鍵詞:課程體系;C無符號數(shù);帶符號數(shù);原碼;反碼;補碼
中圖分類號:G642 文獻標識碼:A
文章編號:1009-3044(2022)36-0154-03
1 引言
在《數(shù)字電子技術(shù)基礎(chǔ)》《微機原理與接口技術(shù)》《匯編語言程序設(shè)計》等課程中,數(shù)制系統(tǒng)都是非常重要的內(nèi)容,是要求學(xué)生理解和掌握的重要知識點[1]。對于學(xué)習(xí)高級語言程序設(shè)計的學(xué)生來說,掌握好數(shù)制系統(tǒng)也有利于更深入地理解和分析程序?qū)?shù)據(jù)處理的實質(zhì)。在數(shù)制系統(tǒng)中,對學(xué)生較難的是原碼、反碼和補碼,也是數(shù)制系統(tǒng)教學(xué)的重點和難點。經(jīng)過多年的研究與實踐,對原碼、反碼和補碼的教學(xué)取得了一定的經(jīng)驗,提出了基于課程體系的原碼、反碼和補碼的教學(xué)觀點。文中僅討論整數(shù)的原碼、反碼和補碼的表示及教學(xué)方法,小數(shù)的表示對大多數(shù)專業(yè)而言是不需要掌握的,需要處理小數(shù)時在匯編語言中可以設(shè)計算法用整數(shù)模擬小數(shù),或者直接用高級語言處理。
2 無符號數(shù)和帶符號數(shù)
原碼、反碼和補碼是帶符號數(shù)的表示方法,要掌握好原碼、反碼和補碼知識,首先要清楚無符號數(shù)和帶符號數(shù)的區(qū)別,以便正確使用這兩類數(shù)據(jù)。日常生活中,例如:電話號碼、房間的門牌號碼、計算機內(nèi)存單元的地址等,這些數(shù)值沒有數(shù)學(xué)上的正負含義,是無符號數(shù)。但是身高體重之類的數(shù)就必須為正數(shù),在銀行存取款時,存進去的金額是正數(shù),會使得銀行余額增加,取出來的金額是負數(shù),使得銀行余額減少,這類數(shù)據(jù)就是帶符號數(shù)。
在數(shù)字系統(tǒng)中采用二進制數(shù),只要將無符號數(shù)用二進制數(shù)表示,高位用0補到規(guī)定的位數(shù)就可以了。帶符號數(shù)有正負符號,符號要數(shù)碼化,且有原碼、反碼和補碼多種表示方法,比無符號數(shù)要復(fù)雜很多。反過來說,學(xué)習(xí)原碼、反碼和補碼知識就是學(xué)習(xí)帶符號數(shù)在數(shù)字系統(tǒng)中的表示方法。
此外,如果給出一個二進制數(shù),這個數(shù)究竟是帶符號數(shù)還是無符號數(shù),該怎么看待怎么處理呢?很多學(xué)生也是迷惘的。實際上,這個數(shù)可以將它視為無符號數(shù),也可以視為帶符號數(shù)。在匯編語言中,當將這個數(shù)看作無符號數(shù)時,就用無符號數(shù)的指令去處理,將這個數(shù)看作帶符號數(shù)時,就用帶符號數(shù)的指令去處理,兩類數(shù)用匯編指令加以區(qū)分,分別處理。在高級語言例如C語言中,用數(shù)據(jù)類型區(qū)分。如unsignedchar、unsigned int之類的處理無符號數(shù),用char、signed char、int、signed int之類的處理帶符號數(shù)。
由于符號位的問題,導(dǎo)致位數(shù)相同的二進制數(shù),作為無符號數(shù)和帶符號數(shù)時表示的數(shù)值范圍是不相同的。例如十六位二進制數(shù),表示的無符號數(shù)范圍為0~65535,用補碼表示的帶符號數(shù)范圍為-32768~+32767。這個特點在數(shù)字電子技術(shù)、微機原理與接口技術(shù)、C語言等課程及各類嵌入式處理器中都是相同的,實現(xiàn)了把多門課程的知識串在一起,有利于學(xué)生構(gòu)建課程體系,打通課程之間的壁壘。
3 原碼表示方法
原碼是用來表示帶符號數(shù)的,這就需要將正、負符號數(shù)碼化。在二進制數(shù)的前面增加一位符號位,符號位為0表示這個數(shù)是正數(shù),符號位為1表示這個數(shù)是負數(shù),這種形式的數(shù)稱為原碼[2]。對原碼,可以用數(shù)學(xué)公式嚴格定義:一個數(shù)連同符號位一起用n位二進制數(shù)表示,某一個數(shù)X的原碼為:
要使學(xué)生理解補碼的概念及引入補碼的優(yōu)越性,通常從日常生活中的實例入手,常用的一個案例就是鐘表,如下圖1所示。
表盤上時針指向10點鐘,而正確的時間是5點鐘,要把時針撥回到5點鐘有兩種方法:第一種方法是將時針往回撥5個小時指向5點鐘,第二種方法是將時針往前撥7個小時指向5點鐘。用數(shù)學(xué)式表示出來,第一種方法為10-5=5;第二種方法為10+7=12+5=5,由于表盤上最大的數(shù)是12,當時間超過12點以后,12自動丟失,只保留減去12以后的余數(shù)5。從效果上來看,10-5與10+7是等價的,都使時針指向了5點,12 稱為模,“?!笔侵敢粋€計數(shù)系統(tǒng)的進位基數(shù)[4]。7是-5 對模12的補數(shù),也稱為補碼。該實例說明了對模12 而言,10-5減法運算可以通過10+7加法運算來實現(xiàn)。這意味著,模確定以后,在舍棄進位的條件下,減去一個數(shù)可以通過加上該數(shù)的補碼來實現(xiàn),也意味著在電路中,減法運算可以通過加法電路來實現(xiàn),從而簡化了電路設(shè)計。
將上例加以拓展,設(shè)某表盤有16個刻度,則刻度值為1~16,模為16,刻度0與16是重合的,與上例中0 點與12點是重合的道理相同。在二進制數(shù)中,因24=16,即四位二進制數(shù)的模是16,依此類推,對于n位二進制數(shù),其模為2n,對于任意負數(shù)X,其對于模2n的補碼為2n-|X|。
通過對這個實例的分析,可以使學(xué)生理解模的概念,補碼的概念以及通過補碼將減法運算轉(zhuǎn)換為加法運算,有利于簡化硬件電路的設(shè)計。
5.2 補碼的特點
通過分析補碼的定義及前面的生活實例,可以得到補碼的特點。
(1)最高位為符號位,為0表示這個數(shù)是正數(shù),為1表示這個數(shù)是負數(shù)。
(2)對于正數(shù),[X]=[X],即正數(shù)的補碼與原碼相同,且能表示的數(shù)值范圍也相同。
(3)對于負數(shù),補碼的值等于模減去該數(shù)的絕對值,再對照負數(shù)補碼和反碼的數(shù)學(xué)定義式可知,負數(shù)的補碼等于該數(shù)的反碼加1。
(4)對于零,設(shè)n=8,則[+0]=00000000,[-0]=00000000,0的表示是唯一的,解決了+0和-0的表示問題。
(5)使用補碼表示,可以將真值的減法運算變?yōu)闄C器中的加法運算,從而使CPU內(nèi)部不再需要設(shè)計減法器[5],簡化了CPU的設(shè)計。
(6)補碼表示時,有少數(shù)特殊數(shù)的補碼對學(xué)生比較難以理解。如,當n=8時,-128的補碼是10000000,當n=16時,-32768的補碼是1000000000000000,這些數(shù)補碼的符號位和數(shù)值位合二為一,可以根據(jù)補碼的定義式來理解,對非計算機專業(yè)的學(xué)生而言,還可以把這幾個數(shù)的補碼表示簡單地看作是一種規(guī)定,計算機程序的編譯軟件也是按這種方法處理的,學(xué)生就容易理解了,否則容易造成困惑。
5.3 幾個需要說明的問題
(1)補碼運算的結(jié)果仍為補碼,類似于二進制數(shù)運算的結(jié)果仍為二進制數(shù),不可能變成了十進制數(shù)。
如果運算結(jié)果的符號位為0,說明結(jié)果是正數(shù),該補碼值等于其原碼,可以由補碼值求出真值。如果運算結(jié)果的符號位為1,說明結(jié)果是負數(shù),要獲得其真值,需要由該補碼數(shù)求出其原碼,再依據(jù)原碼求出真值。
在求負數(shù)補碼對應(yīng)的原碼時,一般采用的方法是[[X]]=[X],即對負數(shù)的補碼再求補碼,得到負數(shù)的原碼。有些同學(xué)會想當然地認為將負數(shù)補碼的數(shù)值位按位求反,再減去1,這種方法不僅結(jié)果錯誤,而且再一次產(chǎn)生了減法運算。
(2)關(guān)于數(shù)據(jù)溢出的理解
如果做的是有符號數(shù)的運算,例如,78-54=24,因78-54=78+(-54),使用補碼表示時,設(shè)n=8,則有[78]+[-54]=01001110+11001010=00011000,補碼運算的結(jié)果仍為補碼,舍棄進位,符號位為0,說明該補碼對應(yīng)的真值是正數(shù),正數(shù)的補碼等于原碼,故該補碼數(shù)對應(yīng)的真值為24,結(jié)果正確。
如果沒有明確是無符號數(shù)或者帶符號數(shù)運算,該如何判斷是否溢出。例如,已知兩個二進制數(shù)的加法運算,01001110+11001010=00011000,因硬件只有8位,故最高位產(chǎn)生的進位自動丟失,有沒有產(chǎn)生溢出取決于如何看待這兩個數(shù)。在計算機中,如果把這兩個數(shù)看作是無符號數(shù),則產(chǎn)生了溢出,為了防止數(shù)據(jù)出錯,在CPU的標志寄存器中,設(shè)置了進借位標志CF,并置CF=1,編程者要根據(jù)CF位進行處理以得到正確的數(shù)據(jù)。如果把這兩個數(shù)看作帶符號數(shù),在CPU 的標志寄存器中,設(shè)置了溢出標志OF,且OF位等于次高位與最高位產(chǎn)生的進位異或運算的結(jié)果,即OF=C⊕C=1⊕1=0,故沒有產(chǎn)生溢出。
(3)關(guān)于數(shù)據(jù)位數(shù)的理解
在數(shù)字電子技術(shù)課程的學(xué)習(xí)中,二進制數(shù)的位數(shù)可以根據(jù)需要來設(shè)定,沒有特別規(guī)定。但是,在計算機中是不可以的。例如,5位二進制數(shù),在數(shù)字電子技術(shù)中可以使用,但是在計算機中不可以采用5位,因為沒有字長為5位的CPU。早期有4位的CPU,現(xiàn)在已經(jīng)淘汰了,現(xiàn)在CPU的字長有8位、16位、32位和64位,這些字長的數(shù)據(jù)在計算機語言中有相應(yīng)的數(shù)據(jù)類型去處理。例如,在C語言中,用char處理8位數(shù),早期用int處理16位數(shù),隨著計算機技術(shù)的發(fā)展,現(xiàn)在的編譯軟件將int型數(shù)據(jù)編譯成了32位甚至64位,這與編譯軟件有關(guān)。如果只需要使用5位二進制數(shù),該數(shù)據(jù)也必須采用一個字節(jié)或者一個字來存儲,然后通過編程來處理這5位二進制數(shù)。
(4)關(guān)于符號擴展的理解
設(shè)有十進制數(shù)+23和-23,在數(shù)字電子技術(shù)中,可以用6 位二進制數(shù)表示,其補碼分別為:[+23]=010111,[-23]=101001。現(xiàn)要求將這兩個數(shù)用8位二進制數(shù)表示,則有[+23] =00010111,[-23] =11101001;若要求將這兩個數(shù)用16位二進制數(shù)表示,則有[+23] =0000000000010111, [-23]=1111111111101001。比較發(fā)現(xiàn):對于帶符號數(shù),當需要將位數(shù)較少的補碼數(shù)采用更多位表示時,只需要將位數(shù)較少的補碼數(shù)的符號位向高位擴展,符號位為0 則向高位補0,符號位為1則向高位補1,補齊到所需的位數(shù)即可;對于無符號數(shù),直接在高位補0,補齊到所需的位數(shù)即可。
(5)關(guān)于補碼與求補的區(qū)別
某些CPU提供了求補的指令,例如在8086 CPU中提供了NEG指令。假設(shè)AL寄存器的值為15H,對AL求補得到EBH,將兩個數(shù)寫成8位二進制數(shù)后比較發(fā)現(xiàn),EBH是將15H所有位求反后加1而得,將這兩個數(shù)看作補碼數(shù),15H的真值是21,EBH的真值是-21。假設(shè)AL寄存器的值為E9H,對AL求補以后得到17H,將兩個數(shù)寫成8位二進制數(shù)后比較發(fā)現(xiàn),17H是將E9H所有位求反后加1而得,將這兩個數(shù)看作補碼數(shù),E9H的真值是-23,17H的真值是+23,可見,執(zhí)行求補指令可以得到被求補的數(shù)據(jù)相反數(shù)的補碼。
假設(shè)AL寄存器的值為80H,BX 寄存器的值為8000H,對AL、BX求補以后的值分別為80H、8000H,將這兩個數(shù)看作補碼數(shù),80H的真值是-128,8000H的真值是-32768,符合補碼的數(shù)學(xué)定義式。
結(jié)論:已知某個負數(shù)X的原碼,求其補碼時符號位是不變的,如果X是正數(shù),則其補碼等于其原碼。已知某個帶符號數(shù)Y,對Y做求補運算,會得到其相反數(shù)的補碼,即-Y的補碼,從二進制運算的角度來看,是將Y的二進制的所有位求反,最后在末尾加1。
6 結(jié)語
討論了在原碼、反碼和補碼知識的教學(xué)中,按照無符號數(shù)和帶符號數(shù)的區(qū)別;無符號數(shù)在數(shù)字系統(tǒng)中的表示方法;帶符號數(shù)的原碼、反碼和補碼的表示方法及其特點;并通過實例分析了如何將所學(xué)知識與C語言、匯編語言及相關(guān)硬件知識聯(lián)系在一起,將知識學(xué)習(xí)放置于由相關(guān)課程組成的課程體系背景中,有利于幫助學(xué)生建立課程體系的觀念,在不同課程之間將相關(guān)知識融會貫通,避免了在不同課程中對相同的知識內(nèi)容割裂開而孤立地學(xué)習(xí),從而促進對知識的理解、記憶和應(yīng)用。