hailing 发表于 2012-5-17 21:37:21

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

比如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位内存单元中。

BXAK 发表于 2012-5-17 22:19:59

用指针、联合体……等等都可以

比如:

uint32 n;
uint8a = 0x12;
uint8b = 0x34;
uint8c = 0x56;
uint8d = 0x78;

((uint8 *)& n ) = a;
((uint8 *)& n ) = b;
((uint8 *)& n ) = c;
((uint8 *)& n ) = d;

结果 n = 0x12345678;

union
{   
    uint32 n;
    struct
    {
      uint8_1;   
      uint8_2;
      uint8_3;   
      uint8_4;
    }n0;
}NA;

uint8a = 0x12;
uint8b = 0x34;
uint8c = 0x56;
uint8d = 0x78;

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

结果 NA.n = 0x12345678;

oufuqiang 发表于 2012-5-18 12:46:40

知道大小端就用指针
没错的,直接编译出MOV

chunk 发表于 2012-5-18 17:06:53

常规的赋值方式为e=a*256^3+b*256^2+c*256^1+d;
------------------------------

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

hailing 发表于 2012-5-18 22:38:55

使用keil试了下。软件仿真,at89s5,1mhz。直接乘积相加花时316us。按2楼提供的方法,指针和联合体都花16us,的确很快,直接放入long的4个字节中。学习了。

hailing 发表于 2012-5-18 22:45:32

另外keil怎么不直接支持用^表示几次幂?

YaphetS 发表于 2012-5-18 22:50:16

a<<12+b<<8+c<<4+d

hailing 发表于 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)=a;
                ((unsigned char *)&e)=b;
                        ((unsigned char *)&e)=c;
                                ((unsigned char *)&e)=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个字节赋值了,最高效的方法。
页: [1]
查看完整版本: C51中如把4个unsigned char 组成32位的unsigned long,运算最快