两个byte 转word疑问

[复制链接]
bhsdlmj 发表于 2009-10-16 12:37 | 显示全部楼层
这样移有时候编译器很傻.   
圈圈这样一般也会编译出多余指令.
俺一直是指针+大小端条件编译,直接可移植的.  最精简. 修改下大小端定义为0或1就好.
huangqi412 发表于 2009-10-16 12:31


举个例子呗!
bhsdlmj 发表于 2009-10-16 12:43 | 显示全部楼层
这样移有时候编译器很傻.   
圈圈这样一般也会编译出多余指令.
俺一直是指针+大小端条件编译,直接可移植的.  最精简. 修改下大小端定义为0或1就好.
huangqi412 发表于 2009-10-16 12:31


能编译出多余指令么?
我觉得一般不会!都是彼此彼此!
bhsdlmj 发表于 2009-10-16 16:57 | 显示全部楼层
唉...

不管用任何方法,都得区分大小端,很多CPU还得注意“非对齐”问题
xwj 发表于 2009-10-15 16:45

TempNum = (((UINT16)Buffer[0]) << 8) |  ((UINT16)Buffer[1]) ;
管他大小开端,这样写能有错!有错了,那就是垃圾编译器!

注:俺本贴言论可能有问题,等俺好好看看,再宣判!星期一见!!!
古道热肠 发表于 2009-10-16 17:18 | 显示全部楼层
采用圈圈的写法,用乘法不易出错.
想出国打工 发表于 2009-10-16 20:52 | 显示全部楼层
奥,不是都说移位效率高吗?
很多2倍乘我都用移位来处理了;
原来又容易出错啊,防不胜防!头痛!
bhsdlmj 发表于 2009-10-16 21:08 | 显示全部楼层
奥,不是都说移位效率高吗?
很多2倍乘我都用移位来处理了;
原来又容易出错啊,防不胜防!头痛!
想出国打工 发表于 2009-10-16 20:52

看看汇编就知道效率高不搞了 ??我看都差不多 !!!

再比如:a = (a >> b);
有人爱写成下面的
a >>= b;

理论上讲下面的 效率高 !!!但是实事呢??

现在的编译器 泰牛了   这两个是等价的   不信 你看看 1!!

level prorigryty =  8   is good 1!

有点问题我的电脑  抱歉各位凑合着看
bhsdlmj 发表于 2009-10-16 21:13 | 显示全部楼层
xwj 是权威 但是不能盲目相信他   尽管最终证明 本财鸟是错误的 但是 过程却能让基本功扎实  

圈圈的  基本功台牛了  佩服   


我最想知道  难道那个〉〉就没有用处了么???/
zq1987731 发表于 2009-10-16 23:55 | 显示全部楼层
何必搞得那么麻烦呢...加法、移位这些都是需要时间的啊...

  1. #define Byte_Ordering 1    // 1 - Big_Endian    0 - Little_Endian

  2. union HalfWord_To_Byte
  3. {
  4.     #if Byte_Ordering
  5.         struct {UINT8 Byte_High, Byte_Low} Byte;
  6.     #else
  7.         struct {UINT8 Byte_Low, Byte_High} Byte;
  8.     #endif
  9.     UINT16 Halfword;
  10. }X;
bhsdlmj 发表于 2009-10-22 09:15 | 显示全部楼层
TempNum = (((UINT16)Buffer[0]) << 8) |  ((UINT16)Buffer[1]) ;

我在大小端编译器下都试过了,这种方法我还是觉得是万无一失的啊  和大小端没有关系啊!!!什么情况都对啊!!

哪位高人指点一下!!
bhsdlmj 发表于 2009-10-22 09:36 | 显示全部楼层
本帖最后由 bhsdlmj 于 2009-10-22 09:44 编辑

比如说UINT8 Buffer【0】 = 0X12

是担心在大端情况下(((UINT16)Buffer[0]) << 8 由低位向高位移动 于是(((UINT16)Buffer[0]) << 8的值为0么?

所以弄个结构体,因为结构体成员存放时从低地址值存放。

是这样么???

高人指点一下
DC_BOY 发表于 2009-10-22 09:37 | 显示全部楼层
还有注意一下 左移 右移 对于单片机效率是比较高
bhsdlmj 发表于 2009-10-22 09:50 | 显示全部楼层
太混乱了 不想了!!!虽然结构体所有成员是按照低地址存放,但是对于单个成员来说,如果说一个16位的成员,仍然是按照原来编译器固有的的大小端存放的啊
bhsdlmj 发表于 2009-10-22 09:51 | 显示全部楼层
所以搞个结构体 实在是看不出来有什么好处啊!!!
渤海三叠浪 发表于 2009-10-22 09:59 | 显示全部楼层
太混乱了 不想了!!!虽然结构体所有成员是按照低地址存放,但是对于单个成员来说,如果说一个16位的成员,仍然是按照原来编译器固有的的大小端存放的啊 ...
bhsdlmj 发表于 2009-10-22 09:50



你说的对!!确实是没有必要搞个结构体!!!圈圈的用乘法还是比较好的。你的方法也很好!!!
xlsbz 发表于 2009-10-22 11:59 | 显示全部楼层
让我来终结这个帖子吧

(1)联合体效率是比结构体高,但是联合体要注意大小端的问题 就像28楼和29楼说的。但是并不是所有人都能意识到这个大小端,所以不推荐使用联合体。只有在对效率有严格要求的情况下谨慎的使用。
(2)圈圈的方法
考虑到以后的可移植性,我一般这样写:

TempNum = Buffer[0];
TempNum*=256;
TempNum+=Buffer[1];
computer00 发表于 2009-10-15 17:21

就这个问题本身来说还是不错的,没有什么漏洞
(3)
这种方法
  1. TempNum = (((UINT16)Buffer[0]) << 8) |  ((UINT16)Buffer[1]) ;
也是很好的 ,因为移位指令本身不用考虑大小端问题 比如说Intel80X86/Pentium体系(little-endian)的CPU和Motorola 68K体系(big-endian)中的执行结果是完全相同的。向最常见的keil 、MDK编译器也是如此。
(4)也可以考虑用微软提供的方法
  1. WORD MAKEWORD(
  2.     BYTE bLow,
  3.     BYTE bHigh
  4. );
  5. Parameters
bLow
Specifies the low-order byte of the new value.
bHigh
Specifies the high-order byte of the new value.
Return Value
The return value is a WORD value.
--------------
因为放置了两个byte ,已经很“齐”了,因此理论上所有编译器都会认为是占2个字节

(5)推荐一个微软的另一种做法给个参考
  1. #define MAKEWORD(a, b) ((WORD)(((BYTE)((DWORD_PTR)(a) & 0xff)) | ((WORD)((BYTE)((DWORD_PTR)(b) & 0xff))) < < 8))
computer00 发表于 2009-10-22 21:44 | 显示全部楼层
当要考虑到对齐、大小端、填充等问题时,结构体+联合体,或者直接强制转换等方式都可能会出问题的(不同的编译器关键字还可能不一样)。写成乘法+加法的方式是移植起来比较可靠的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部