x86系統與西門子PLC200的位元組序的區別
什麼叫位元組序呢?這還要從二進位說起,一個位元組(8 Bit)只能夠表示0~255的十進位數(就只拿 unsigned char 做例子好了,暫不討論signed char,其實道理都是一樣),那麼要表示大於255的數該如何辦呢?辦法就是用兩個位元組,或四個位元組來表示十進位數,這便有了字(Word)和雙字(DWord),而現在的記憶體都是按照位元組編址的,於是就碰到一個問題,當在記憶體中儲存字或者雙字的時候,是該把低位元組放在低地址處啊,還是該把低位元組放在高地址處呢?比如說你要在記憶體中儲存一個字 AABB(16進位),現在記憶體中兩個連續的位元組給你,地址分別是 1234,1235,那麼你有兩種儲存方法,對不對?方法一:把AA存在記憶體中地址為1234的位元組裡,把BB存在記憶體中地址為1235的位元組裡。方法二:把BB存在記憶體中地址為1234的位元組裡,把AA存在記憶體中地址為1235的位元組裡。也就是說,方法一是把高位元組存在記憶體的低地址處,低位元組存在高地址處,這就是高位在前的位元組序,西門子PLC200就是採用這種位元組序;方法二則是把低位元組存在記憶體的低地址處,高位元組存在記憶體的高地址處,這就是低位在前的位元組序,所有的基於x86系統的微機(也就是我們常用的家用電腦)就是採用這種位元組序。
在英文中用 big endian 和 little endian ,分別表示高位在前和低位在前。
“endian”這個詞出自《格列佛遊記》。小人國的內戰就源於吃雞蛋時是究竟從大頭(Big-Endian)敲開還是從小頭(Little-Endian)敲開,由此曾發生過六次叛亂,其中一個皇帝送了命,另一個丟了王位。
我們一般將endian翻譯成“位元組序“。
雖然我們可從參考資料上查得:x86系統的微機採用低位在前的位元組序,西門子PLC200採用高位在前的位元組序。但若是我們能夠編寫程式,親手驗證上述兩種系統的位元組序,豈不快哉。好,馬上動手。
先來驗證x86系統:
開啟VB,拖好控制項(Command1),敲入如下代碼:
-----------------------------------------------------------------------
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(Destination As Any, Source As Any, ByVal Length As Long)
Private Sub Form_Load()
Dim i As Long
Dim byt As Byte
i = &HAABBCCDD
CopyMemory byt, ByVal VarPtr(i), 1
Debug.Print Hex(byt)
CopyMemory byt, ByVal VarPtr(i) + 1, 1
Debug.Print Hex(byt)
CopyMemory byt, ByVal VarPtr(i) + 2, 1
Debug.Print Hex(byt)
CopyMemory byt, ByVal VarPtr(i) + 3, 1
Debug.Print Hex(byt)
End Sub
-----------------------------------------------------------------------
再來在VC++中驗證一下,開啟VC++,建立一個基於對話方塊的工程,拖入一個按鈕控制項,
在按鈕的訊息處理函數中敲入如下代碼:
-----------------------------------------------------------------------
void CByteorderDlg::OnButton1()
{
// TODO: Add your control notification handler code here
int i;
unsigned char * lp_i;
CString cstr;
i=0xAABBCCDD;
lp_i=(unsigned char *)&i;
cstr.Format("%x",*lp_i);
AfxMessageBox(cstr);
cstr.Format("%x",*(lp_i+1));
AfxMessageBox(cstr);
cstr.Format("%x",*(lp_i+2));
AfxMessageBox(cstr);
cstr.Format("%x",*(lp_i+3));
AfxMessageBox(cstr);
}
-----------------------------------------------------------------------
運行代碼,可以看到,最低位的位元組DD確實儲存在地址最低處,依次類推,最高位的位元組AA存在地址最高處。
由此可以驗證,x86系統的微機確實採用低位在前的位元組序。
最後,來驗證西門子PLC s7-200中的位元組序,開啟step7-MicroWin,敲入如下代碼:
-----------------------------------------------------------------------
LD SM0.0
MOVW 16#FF00, QW0 //研究字的位元組序,會發現,qb0一排燈全部打亮,qb1一排燈全部是滅的。這就可以說明PLC中位元組序是高位在前(低地址處)
LD SM0.0
MOVD 16#AABBCCDD, VD0 //用這個程式,運行起來之後,監控vb0--vb3的值,可以研究雙字的位元組序。
-----------------------------------------------------------------------