| 由ADS1.2中memcpy()想到的<br /><br />作者:owzq<br />邮箱:owzq@163.com<br /><br />在做NANDFLASH底层驱动时,由于数据量很大,想着把外部总线的时序再调紧凑一点,于是想到用memcpy()函数.<br />NANDFLASH写函数中用<br />#define DEV_STORE_PIPEIO ((volatile BYTE*)0x01180000)<br />memcpy( (BYTE*)DEV_STORE_PIPEIO, pbyData, dwSize );<br />当DEV_STORE_PIPEIO地址不是4字节对齐时,数据错误.<br />反汇编后发现核心是ldmcsia/stmcsia,就要4字节对齐,当不对齐的时候,就凑齐.<br />我们仔细看反汇编的代码发现前面大量的语句都是在凑对齐.<br />我们可以肯定,复制数据越多,memcpy()效率越高.如果仅仅拷贝4/8个字节,还是赋值吧.呵呵.<br />memcpy()应用于NANDFLASH这样的数据和地址不是一一对应的硬件时,要对齐.<br /><br />你可以用 <br />   ldmcsia   r1!,{r3,r4,r12,r14}<br />   stmcsia   r0!,{r3,r4,r12,r14}<br />   ldmcsia   r1!,{r3,r4,r12,r14}<br />   stmcsia   r0!,{r3,r4,r12,r14}<br />自己打造一个专用的函数.<br /><br />附录:<br />memcpy<br />__rt_memcpy    <br />   cmp       r2,#3<br />   bls       _memcpy_lastbytes<br />   ands      r12,r0,#3<br />   beq       _memcpy_dest_aligned<br />   ldrb      r3,[r1],#1<br />   cmp       r12,#2<br />   add       r2,r2,r12<br />   ldrlsb    r12,[r1],#1<br />   strb      r3,[r0],#1<br />   ldrccb    r3,[r1],#1<br />   sub       r2,r2,#4<br />   strlsb    r12,[r0],#1<br />   strccb    r3,[r0],#1 <br />_memcpy_dest_aligned    <br />   ands      r3,r1,#3<br />   beq       __rt_memcpy_w<br />   subs      r2,r2,#4<br />   bcc       _memcpy_lastbytes<br />   ldr       r12,[r1,-r3]!<br />   cmp       r3,#2<br />   beq       _memcpy_src2_loop<br />   bhi       _memcpy_src3_loop<br />         <br />_memcpy_src1_loop <br />   mov       r3,r12,lsr #8<br />   ldr       r12,[r1,#4]!<br />   subs      r2,r2,#4<br />   orr       r3,r3,r12,lsl #24<br />   str       r3,[r0],#4<br />   bcs       _memcpy_src1_loop<br />   add       r1,r1,#1<br />   b         _memcpy_lastbytes<br />    <br />_memcpy_src2_loop <br />   mov       r3,r12,lsr #16<br />   ldr       r12,[r1,#4]!<br />   subs      r2,r2,#4<br />   orr       r3,r3,r12,lsl #16<br />   str       r3,[r0],#4<br />   bcs       _memcpy_src2_loop<br />   add       r1,r1,#2<br />   b         _memcpy_lastbytes<br />   <br />_memcpy_src3_loop <br />   mov       r3,r12,lsr #24<br />   ldr       r12,[r1,#4]!<br />   subs      r2,r2,#4<br />   orr       r3,r3,r12,lsl #8<br />   str       r3,[r0],#4<br />   bcs       _memcpy_src3_loop<br />   add       r1,r1,#3<br />   b         _memcpy_lastbytes<br />   <br />__rt_memcpy_w <br />   stmfd     r13!,{r4,r14}<br />   subs      r2,r2,#0x20<br />   bcc       _memcpy_small<br />   <br />_memcpy_aligned_loop <br />   ldmcsia   r1!,{r3,r4,r12,r14}<br />   stmcsia   r0!,{r3,r4,r12,r14}<br />   ldmcsia   r1!,{r3,r4,r12,r14}<br />   stmcsia   r0!,{r3,r4,r12,r14}<br />   subcss    r2,r2,#0x20<br />   bcs       _memcpy_aligned_loop<br />   <br />_memcpy_small <br />   movs      r12,r2,lsl #28<br />   ldmcsia   r1!,{r3,r4,r12,r14}<br />   stmcsia   r0!,{r3,r4,r12,r14}<br />   ldmmiia   r1!,{r3,r4}<br />   stmmiia   r0!,{r3,r4}<br />   ldmfd     r13!,{r4,r14}<br />   movs      r12,r2,lsl #30<br />   ldrcs     r3,[r1],#4<br />   strcs     r3,[r0],#4<br />   moveq     pc,r14<br />   <br />_memcpy_lastbytes <br />   movs      r2,r2,lsl #31<br />   ldrmib    r2,[r1],#1<br />   ldrcsb    r3,[r1],#1<br />   ldrcsb    r12,[r1],#1<br />   strmib    r2,[r0],#1<br />   strcsb    r3,[r0],#1<br />   strcsb    r12,[r0],#1<br />   mov       pc,r14<br /> |