文档章节

关于 "高位" 与 "低位" - 回复 "Lovemit" 的问题

涂孟超
 涂孟超
发布于 2014/09/26 15:34
字数 812
阅读 19
收藏 0

问题来源: http://www.cnblogs.com/del/archive/2008/09/11/1288760.html#1807074

本话题会涉及到: 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) 等价于 Word(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;

 
 
 
 
 

 

 

  

呵, 今天耐心极好; 不知说明白没有?

本文转载自:http://www.cnblogs.com/del/archive/2010/04/21/1717584.html

共有 人打赏支持
涂孟超
粉丝 12
博文 2011
码字总数 14107
作品 0
深圳
程序员
最简单的方式教你理解大小端字节序

学过编程的人都应该知道大小端字节序的概念,但是很多时候,总是把他们弄混,这是整理出来的一份很简单的方式理解字节序的文章,废话不多说,这里直接入正题。 什么是字节序? 字节序,简单来...

暮回_梓
06/26
0
0
HashMap 容量为2次幂的原理

学习自 https://www.zhihu.com/question/20733617 hash static final int hash(Object key) { return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);} 然后 (n - 1) & hash 首先介......

qq_36523667
05/25
0
0
Lintcode3 Digit Counts solution 题解

【题目描述】 Count the number of k's between 0 and n. k can be 0 - 9. 计算数字k在0到n中的出现的次数,k可能是0~9的一个值。 【题目链接】 http://www.lintcode.com/en/problem/digit-c...

coderer
2017/04/09
0
0
大小端和移位运算

移位运算分为逻辑左移、逻辑右移、算术左移、算术右移 顾名思义:算术是有正负的。因此算术移位,关心符号位;而逻辑不管符号位。 1 算术左移(<<) 计算规则:按二进制形式把所有的数字向左移...

J_Stone
2016/04/17
174
0
[剑指offer] 整数中1出现的次数(从1到n整数中1出现的次数)

本文首发于我的个人博客:尾尾部落 题目描述 求出113的整数中1出现的次数,并算出1001300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对...

繁著
07/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

函数调用约定 (cdecl stdcall)

函数调用约定 (cdecl stdcall) 在 C 语言里,我们通过阅读函数声明,就知道怎么携带参数去调用函数,也能在函数体定义内使用这些参数。但是 CPU 并不直接完成函数调用的传参操作,这需要人为...

傅易
5分钟前
0
0
Python 核心编程 (全)

浅拷贝和深拷贝 1.浅拷贝:是对于一个对象的顶层拷贝,通俗的理解是:拷贝了引用,并没有拷贝内容。相当于把变量里面指向的一个地址给了另一个变量就是浅拷贝,而没有创建一个新的对象,如a=b...

代码打碟手
7分钟前
0
0
mysql5.7 修改datadir

mysql 的默认存储路径为 /var/lib/mysql ,修改后为 /data/mysql 关闭服务 service mysql stop 复制mysql 数据文件到新的目录 cp -rp /var/lib/mysql /data 查看原目录的权限,如果新目...

hotsmile
24分钟前
0
0
证书安装指引之Tomcat 证书部署

Tomcat 证书部署 0 申请证书 1 获取证书 如果申请证书时有填写私钥密码,下载可获得Tomcat文件夹,其中有密钥库 www.domain.com.jks; 如果没有填写私钥密码,证书下载包的Tomcat文件夹中包括...

吴伟祥
28分钟前
0
0
ConcurrentHashMap1.7和1.8的底层不同实现

1.Hashmap和HashTable在线程安全方面的优劣? Hashmap多线程会导致HashMap的Entry链表形成环形数据结构,一旦形成环形数据结构,Entry的next节点永远不为空,就会产生死循环获取Entry。 Hash...

刘祖鹏
44分钟前
9
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部