搜索
bottom↓
回复: 7

C51中如把4个unsigned char 组成32位的unsigned long,运算最快

[复制链接]

出70入145汤圆

发表于 2012-5-17 21:37:21 | 显示全部楼层 |阅读模式
比如unsigned char a,b,c,d
unsigned long e
常规的赋值方式为e=a*256^3+b*256^2+c*256^1+d;
在8位机中,实际e还是有4个8位的数来保存,可不可以直接把a,b,c,d放入4个8位内存单元中。

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2012-5-17 22:19:59 | 显示全部楼层
用指针、联合体……等等都可以

比如:

uint32 n;
uint8  a = 0x12;
uint8  b = 0x34;
uint8  c = 0x56;
uint8  d = 0x78;

((uint8 *)& n )[0] = a;
((uint8 *)& n )[1] = b;
((uint8 *)& n )[2] = c;
((uint8 *)& n )[3] = d;

结果 n = 0x12345678;

union
{   
    uint32 n;  
    struct
    {
        uint8  _1;   
        uint8  _2;
        uint8  _3;   
        uint8  _4;
    }n0;
}NA;

uint8  a = 0x12;
uint8  b = 0x34;
uint8  c = 0x56;
uint8  d = 0x78;

NA.n0._1 = a;
NA.n0._2 = b;
NA.n0._3 = c;
NA.n0._4 = d;

结果 NA.n = 0x12345678;

出0入0汤圆

发表于 2012-5-18 12:46:40 | 显示全部楼层
知道大小端就用指针
没错的,直接编译出MOV

出0入0汤圆

发表于 2012-5-18 17:06:53 | 显示全部楼层
常规的赋值方式为e=a*256^3+b*256^2+c*256^1+d;
------------------------------

就这个常规方式,你让C编译器生成汇编源码,你看一下都用了什么指令,怎么完成的赋值。我个人认为,在开启合适的优化级别的前提下,C编译器产生的指令应该就是你期望的那样,4个数放入4个内存单元中。

出70入145汤圆

 楼主| 发表于 2012-5-18 22:38:55 来自手机 | 显示全部楼层
使用keil试了下。软件仿真,at89s5,1mhz。直接乘积相加花时316us。按2楼提供的方法,指针和联合体都花16us,的确很快,直接放入long的4个字节中。学习了。

出70入145汤圆

 楼主| 发表于 2012-5-18 22:45:32 来自手机 | 显示全部楼层
另外keil怎么不直接支持用^表示几次幂?

出0入0汤圆

发表于 2012-5-18 22:50:16 | 显示全部楼层
a<<12+b<<8+c<<4+d

出70入145汤圆

 楼主| 发表于 2012-5-18 23:14:54 | 显示全部楼层
手机回复的现在在电脑上看不到了。
使用KEIL测试了下
AT89S52,软件仿真,1MHz;

        a=0x12;
        b=0x34;
        c=0x56;
        d=0x78;
        e=a*16777216+b*65536+c*256+d;
        316us/ 1MHz


                a=0X12;
        b=0X34;
        c=0X56;
        d=0X78;
        ((unsigned char *)&e)[0]=a;
                ((unsigned char *)&e)[1]=b;
                        ((unsigned char *)&e)[2]=c;
                                ((unsigned char *)&e)[3]=d;
                                16us/1m

union                               
{
        unsigned long e;
        struct
        {
                unsigned char _1;
                unsigned char _2;
                unsigned char _3;
                unsigned char _4;
        }e0;
}ea;
void main(void)
{

        a=0X12;
        b=0X34;
        c=0X56;
        d=0X78;
        ea.e0._1=a;
        ea.e0._2=b;
        ea.e0._3=c;
        ea.e0._4=d;
        ea.e=0;
//16us /1m

直接乘积相加316us,而指针和联合体只要16us,指针和联合体反汇编直接对long的4个字节赋值了,最高效的方法。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 02:26

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表