1.引言
cpu寄存器狀態(tài)字的各位給出了有關(guān)指令狀態(tài)或結(jié)果的信息以及所出現(xiàn)的錯(cuò)誤,我們可以將二進(jìn)制邏輯操作狀態(tài)位信號(hào)狀態(tài)直接集成到程序中,以控制程序執(zhí)行的流程。
2.狀態(tài)字寄存器
先簡(jiǎn)單介紹一下cpu中狀態(tài)字。
●首次檢查位:狀態(tài)字的0位稱(chēng)作首次檢查位,如果/fc位的信號(hào)狀態(tài)為“0”,則表示伴隨著下一條邏輯指令,程序中將開(kāi)始一個(gè)新的邏輯串。fc前面的斜杠表示對(duì)fc取反。
●邏輯運(yùn)算結(jié)果:狀態(tài)字的第1位為rlo位(rlo=“邏輯運(yùn)算結(jié)果”),在二進(jìn)制邏輯運(yùn)算中用作暫時(shí)存儲(chǔ)位。比如,一串邏輯指令中的某個(gè)指令檢查觸點(diǎn)的信號(hào)狀態(tài),并根據(jù)布爾邏輯運(yùn)算規(guī)則將檢查的結(jié)果(狀態(tài)位)與rlo位進(jìn)行邏輯門(mén)運(yùn)算,然后邏輯運(yùn)算結(jié)果又存在rlo位中。
●狀態(tài)位:狀態(tài)位(第2位)用以保存被尋址位的值。狀態(tài)位總是向掃描指令(a,an,o,…)或?qū)懼噶睿?,s,r,顯示尋址位的狀態(tài)(對(duì)于寫(xiě)指令,保存的尋址位狀態(tài)是本條寫(xiě)指令執(zhí)行后的該尋址位的狀態(tài))。
●or位:在用指令or執(zhí)行或邏輯操作之前,執(zhí)行與邏輯操作的時(shí)候,就需要用到or這一狀態(tài)位。or位表示先前執(zhí)行的與邏輯操作產(chǎn)生的值為“1”,于是,邏輯操作或的執(zhí)行結(jié)果就已被確定為“1”。
●ov位:溢出表示算術(shù)或比較指令執(zhí)行時(shí)出現(xiàn)了錯(cuò)誤。根據(jù)所執(zhí)行的算術(shù)或邏輯指令結(jié)果對(duì)該位進(jìn)行設(shè)置。
●os位:溢出存儲(chǔ)位是與ov位一起被置位的,而且在更新算術(shù)指令之后,它能夠保持這種狀態(tài),也就是說(shuō),它的狀態(tài)不會(huì)由于下一個(gè)算術(shù)指令的結(jié)果而改變。這樣,即使是在程序的后面部分,也還有機(jī)會(huì)判斷數(shù)字區(qū)域是否溢出或者指令是否含有無(wú)效實(shí)數(shù)。os位只有通過(guò)如下這些命令進(jìn)行復(fù)位:jos(若os=1,則跳轉(zhuǎn))命令,塊調(diào)用和塊結(jié)束命令。
●cc1及cc0位:cc1和cc0(條件代碼)位給出有關(guān)下列結(jié)果的相關(guān)信息:
•算術(shù)指令結(jié)果
•比較指令結(jié)果
•字邏輯指令
•在移位功能中,移出位相關(guān)信息。
可以用以下指令來(lái)檢查條件代碼cc1和cc0。
cc1cc0檢查完成后,如果:
00a==0結(jié)果=0
10a>0結(jié)果>0
01a<0結(jié)果<0
●br位:狀態(tài)字的第8位稱(chēng)為二進(jìn)制結(jié)果位。它將字處理程序與位處理聯(lián)系起來(lái),在一段既有位操
作又有字操作的程序中,用于表示字邏輯是否正確。將br位加入程序后,無(wú)論字操作結(jié)果如何,都不會(huì)造成二進(jìn)制邏輯鏈中斷。在梯形圖的方塊指令中,br位與eno位有對(duì)應(yīng)關(guān)系,用于表明方塊指令是否被正確執(zhí)行:如果執(zhí)行出現(xiàn)了錯(cuò)誤,br位為0,eno位也為0;如果功能被正確執(zhí)行,br位為1,
eno位也為1。在用戶(hù)編寫(xiě)的fb/fc程序中,應(yīng)該對(duì)br位進(jìn)行管理,功能塊正確執(zhí)行后,使br位為1,否則使其為0。使用save指令將rlo存入br中,從而達(dá)到管理br位目的。
狀態(tài)字的9-15位未使用。
3.具體使用
下面我們結(jié)合step7中的指針編程來(lái)具體介紹條件碼cc0/cc0的用法。
不同的指令在cpu中執(zhí)行時(shí)間是不同的。浮點(diǎn)數(shù)比定點(diǎn)數(shù)執(zhí)行時(shí)間要長(zhǎng);字邏輯指令比位邏輯指令執(zhí)行時(shí)間要長(zhǎng);在某些程序中適當(dāng)使用狀態(tài)字來(lái)進(jìn)行編程可以減少cpu程序的執(zhí)行時(shí)間。
例1:比如說(shuō)要比較一個(gè)db中塊的dbbo-dbb99這100個(gè)字節(jié)是正數(shù)是負(fù)數(shù)還是0,正數(shù)用1來(lái)表示;負(fù)數(shù)用-1來(lái)表示;0用0來(lái)表示。并且將對(duì)應(yīng)結(jié)果存入mb200開(kāi)始的100個(gè)字節(jié)中。我們通常的做法可能為:
如果利用條件碼來(lái)進(jìn)行編程,既可以減少程序的大小還會(huì)減少一定的指令執(zhí)行時(shí)間,我們只需要將
中間的比較程序加以?xún)?yōu)化,即可以達(dá)到目的。
例2:根據(jù)狀態(tài)位c0和cc1的狀態(tài)而跳轉(zhuǎn)的跳轉(zhuǎn)功能指令jz不改變?nèi)魏螤顟B(tài)位的狀態(tài),而且邏輯操作結(jié)果rlo值也會(huì)“隨著”該跳轉(zhuǎn)功能帶到跳轉(zhuǎn)程序段中,供用戶(hù)程序其它邏輯操作之用(不改變/fc狀態(tài))。
示例兩個(gè)整數(shù)相減并需進(jìn)行連續(xù)判斷:
lmw2
lmw8
-i
jzzero//如果結(jié)果等于“0”,則跳轉(zhuǎn)至標(biāo)號(hào)zero處
//結(jié)果不等于“0”時(shí)所執(zhí)行的指令
zero://結(jié)果等于“0”時(shí),所要執(zhí)行的指令
如果用戶(hù)不熟悉jz指令和狀態(tài)位c0和cc1的具體含義,編程時(shí)就需要通過(guò)比較指令將比較結(jié)果存入一個(gè)二進(jìn)制位中,再根據(jù)這個(gè)二進(jìn)制位通過(guò)jc/jcn指令來(lái)控制程序的執(zhí)行了。
例3:我們實(shí)際應(yīng)用中可能要利用某些協(xié)議轉(zhuǎn)換網(wǎng)關(guān)(比如說(shuō)hilscher公司的nttap系列網(wǎng)關(guān))來(lái)和某些串口協(xié)議的儀表進(jìn)行通信時(shí),會(huì)遇到crc校驗(yàn)的問(wèn)題,關(guān)于crc校驗(yàn)時(shí)需要判斷溢出位是否為1的問(wèn)題來(lái)進(jìn)行程序的進(jìn)一步計(jì)算。我們以euro2408的modbus通信時(shí)需要的crc校驗(yàn)為例說(shuō)明crc校驗(yàn)的步驟:
1、裝載16#ffff到一個(gè)16位crc寄存器;
2、將crc寄存器的高8位字節(jié)與信息中的第一個(gè)8位字節(jié)相異或,結(jié)果返回到crc寄存器中;
3、將crc寄存器數(shù)據(jù)向右移動(dòng)一位;
4、如果溢出的位等于1,則將crc寄存器與16#a001相異或,結(jié)果返回到crc寄存器中;
4、如果溢出的位等于0,則重復(fù)第3步;
5、重復(fù)第3、4步驟,直到已經(jīng)移位了8次;
6、將crc寄存器的高8位字節(jié)與信息中的下一個(gè)8位字節(jié)相異或,結(jié)果返回到crc寄存器中;
7、重復(fù)第3步到第6步,直到信息中所有字節(jié)都與crc寄存器相異或,并都移位了8次;
8、最后的crc寄存器中的結(jié)果即為crc校驗(yàn)碼,最后被添加到信息(數(shù)據(jù))的末尾(交換!低8位
在前,高8位在后;)
在第4步中需要判斷溢出的位是否為1,如何判斷對(duì)于整個(gè)程序有著重要的影響。我們可以用a>0指令來(lái)判斷這個(gè)條件,具體代碼的編寫(xiě),有興趣時(shí)大家可以根據(jù)上面的步驟編寫(xiě)一個(gè)自己的crc程序。
4.結(jié)束語(yǔ)
在一般情況下,我們不必考慮這些狀態(tài)位,但在某些情況下,利用這些狀態(tài)位并結(jié)合一定的指令,可以給我們的編程帶來(lái)更大的靈活性,同時(shí)對(duì)于進(jìn)一步提高自己的編程水平也有一定的作用。