程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 關於 高位 與 低位

關於 高位 與 低位

編輯:Delphi

 本話題會涉及到: Lo、Hi、HiByte、LoWord、HiWord、MakeWord、MakeLong、Int64Rec

  譬如有一個 Cardinal 類型的整數: 1144201745

  其十六進制的表示是: $44332211

  其二進制表示是: 01000100 00110011 00100010 00010001

  我們說 Cardinal 是 32 位的整數, 這裡的位是指 "二進制的位數", 不信你數數.

  我們需要重點面對的是十六進制, 不管是幾進制的數在編譯成匯編代碼時都是用十六進制表示, 因為它最直觀;

  我們用十六進制來分析, 也是因為它的直觀.

  怎麼直觀的? Cardinal 有 32 位, 每 8 位一個字節, 共 4 個字節;

  上面的例數分成字節就是: $44、$33、$22、$11, 這明顯比二進制簡潔、比十進制直觀.

  其中的 $11 是最低位的字節、$44 是最高位的字節(每字節對應十六進制的兩位).

  有時我們需要獲取其中某個字節或某兩個字節, 這雖然用位運算也不難, 但還是有了諸多函數:

Lo   //獲取例數中的 $11 
Hi   //獲取例數中的 $22 
LoWord //獲取例數中的 $2211 
HiWord //獲取例數中的 $4433 

  其中的 Hi 好像有點費解, 為什麼獲取的不是 $44 而是 $22 呢?

  這樣理解吧: Hi 獲取的是 Lo(獲取)的上一個字節.

  HiByte 和 Hi 基本一樣, 如果參數是 16 位的 Word 類型, 用 HiByte 會更好些(中間會省去一個轉換過程).

  其中的 HiWord 是個函數, 但 LoWord 並不是個函數, 它是 Word 類型的重命名.

  也就是說 LoWord(num) 等價於 Wrod(num), 這不是類型轉換嗎?

  是的, 所以像 Lo(num) 也可以用 Byte(num) 來代替.

  用代碼總結一下:

var 
 num: Cardinal; 
 b1,b2,b3,b4: Byte; 
 w1,w2: Word; 
begin 
 num := $44332211; 
 w1 := Word(num); 
 w2 := HiWord(num); 
 ShowMessageFmt('w1:%x; w2:%x', [w1,w2]);//w1:2211; w2:4433 
 
 b1 := Lo(num); 
 b2 := Hi(num); 
 b3 := Byte(w2); 
 b4 := HiByte(w2); 
 ShowMessageFmt('b1:%x; b2:%x; b3:%x; b4:%x', [b1,b2,b3,b4]);//b1:11; b2:22; b3:33; b4:44 
end; 

  下一個話題: 我們有時也需要進行上面的反操作, 譬如:

  把兩個 Byte 合成為一個 Word;

  把兩個 Word 合成一個 Cardinal;

  把兩個 Cardinal 合成一個 Int64;

  把四個 Byte 合成一個 Cardinal;

  把四個 Word 合成一個 Int64 等等

  上面說的 Cardinal 也可以是 Integer 或 DWord.

  完成這種工作也有不少函數:

  MakeWord、MakeLong、MakeWParam、MakeLParam、MakeLResult、MAKELCID 等等.

  僅就 MakeWord、MakeLong 舉例:

var 
 num: Cardinal; 
 b1,b2,b3,b4: Byte; 
 w1,w2: Word; 
begin 
 b1 := $11; 
 b2 := $22; 
 b3 := $33; 
 b4 := $44; 
 
 w1 := MakeWord(b1, b2); 
 w2 := MakeWord(b3, b4); 
 ShowMessageFmt('w1:%x; w2:%x', [w1,w2]);//w1:2211; w2:4433 
 
 num := MakeLong(w1, w2); 
 ShowMessageFmt('num:%x', [num]);//44332211 
end; 

  有沒有把兩個 Integer 合成為 Int64 的函數呢?

  沒有, 當然可以寫一個; 不過有更方便的處理方式, 那就是 Int64Rec 結構.

  舉例如下:

var 
 n1,n2: Cardinal; 
 num64: Int64; 
 rec: Int64Rec; 
begin 
 n1 := $44332211; 
 n2 := $AABBCCDD; 
 
 rec.Lo := n1; 
 rec.Hi := n2; 
 
 num64 := Int64(rec); 
 ShowMessage(IntToHex(num64, 0)); //AABBCCDD44332211 
end; 

  Int64Rec 更多用於反向操作:

var 
 n1,n2: Cardinal; 
 num64: Int64; 
begin 
 num64 := $AABBCCDD44332211; 
 
 n1 := Int64Rec(num64).Lo; //或 n1 := Cardinal(num64); 
 n2 := Int64Rec(num64).Hi; 
 
 ShowMessageFmt('n1:%x; n2:%x', [n1,n2]);//n1:44332211; n2:AABBCCDD 
end; 

  呵, 今天耐心極好; 不知說明白沒有?


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved