Group Blog
 
<<
กันยายน 2550
 1
2345678
9101112131415
16171819202122
23242526272829
30 
 
7 กันยายน 2550
 
All Blogs
 
การเขียนฟังก์ชั่นแบบ memcpy ในภาษาซี

ฟังก์ชั่น memcpy จริง ๆ มีอยู่ใน standard library ของ C ในส่วนของ string.h แต่งวดนี้ ทางที่ทำงาน อยากได้แบบไม่ต้อง include library ตัวนี้ ดังนั้นก็ต้องเขียนใหม่เลย

การเขียนนี้ ต้องระวังเรื่องขนาดของ CPU ว่าเป็นแบบกี่บิต เช่นที่ผมใช้ เป็นแบบ 32 บิต นั่นหมายถึง มันสามารถ access ทีนึงได้ 32 บิต หรือ 4 ไบต์

และสิ่งที่ต้องระวังอีกส่วนที่หัวหน้าสอนคือ การเข้าถึงตำแหน่ง address ถ้าตำแหน่งนั้น ไม่สามารถ access ได้ 4 ไบต์ ต้องค่อย ๆ access ทีละ 1 ไบต์ หรือ 2 ไบต์ ไม่ก็ต้องทำทั้งสองอย่าง

เช่น ถ้า ข้อมูลเริ่มตำแหน่งที่ address -> 100 นั่นก็แสดงว่า ระบบสามารถ access ทีละ 4 ไบต์ได้ทันที

แต่ถ้าเริ่มต้นที่ 101 จะ access ไม่ได้ ต้องอ่านแบบ 1 ไบต์ก่อน แล้วค่อยอ่านแบบ 2 ไบต์ เพื่อที่จะให้ address ขยับไปที่ตำแหน่ง 104

แต่ถ้าเริ่มต้นที่ 102 ก็ access 2 ไบต์ ก็พอ
และถ้าเริ่มต้นที่ 103 ก็ access เพียง 1 ไบต์ ก็ข้ามไปที่ 4 ไบต์ได้เลย

และสุดท้ายจุดที่ต้องระวังคือ จำนวนที่จะก๊อปปี้ นั่นคือ ถ้าเราต้องการก๊อปปี้เพียง 40 ตำแหน่ง และมันเริ่มต้นที่ address 100 ก็ก๊อปปี้ทีละ 4 ไบต์ได้เลย ทำงานเพียง 10 รอบ ก็จบ

แต่ถ้า เริ่มต้นที่ 100 และก๊อป 37 ตำแหน่ง มันจะก๊อป 4 ไบต์ 9 รอบ (36 ตำแหน่ง) และจะก๊อป 1 ไบต์ 1 รอบ ซึ่งรวมแล้ว 10 รอบ

แต่ถ้าเริ่มต้นที่ 100 และก๊อป 38 ตำแหน่ง มันจะก๊อป 4 ไบต์ 9 รอบ (36 ตำแหน่ง) และจะก๊อป 2 ไบต์ 1 รอบ ซึ่งรวมแล้ว 10 รอบ

แต่ถ้าเริ่มต้นที่ 100 และก๊อป 39 ตำแหน่ง มันจะก๊อป 4 ไบต์ 9 รอบ (36 ตำแหน่ง) และจะก๊อป 2 ไบต์ 1 รอบ และจะก๊อป 1 ไบต์ 1 รอบ ซึ่งรวมแล้ว 11 รอบ

แต่ถ้าเริ่มต้นที่ 101 และก๊อปปี้ 40 ตำแหน่งละก็ จะทำงาน
ก๊อปปี้ 1 ไบต์ และขยับ address 1 ไบต์
ก๊อปปี้ 2 ไบต์ และขยับ address 2 ไบต์
ก๊อปปี้ 4 ไบต์ รวม 9 รอบ
ก๊อปปี้ 1 ไบต์ รวม 1 รอบ
เบ็ดเสร็จ ต้องก๊อปปี้รวม 13 รอบ

เห็นความยุ่งยากของการเขียนโปรแกรมหรือยังครับ

ยิ่งถ้าซีพียูเป็นแบบ 64 บิต แล้วมีข้อแม้เยอะด้วยหละก็ เขียนโปรแกรมมึนเลย ฮ่าฮ่า

----- มาดูโค้ดกันดีกว่า -----

ส่วน memcpy.h

typedef unsigned char uchar8;
typedef unsigned short uint16;
typedef unsigned long uint32;
void memcpy(uchar8 * dest,const uchar8 * src, uint16 remain_byte);


ส่วน memcpy.c

#include "memcpy.h"

void memcpy(uchar8 * dest,const uchar8 * src, uint16 remain_byte)
{
   if (((uint32)src & (uint32)0x01) == 1) /* ((uint32)src % 2) == 1 */
   {
      *((uchar8 *)dest) = *((uchar8 *)src);
      src++;
      dest++;
      remain_byte--;
   }

   if (((uint32)src & (uint32)0x02 ) == 2) /* ((uint32)src % 4) == 2 */
   {
      *((uint16 *)dest) = *((uint16 *)src);
      src += 2;
      dest += 2;
      remain_byte -= 2;
   }

   for (i=0; i < (remain_byte >> 2); i++) /* remain_byte / 4 */
   {
      /* Long_Copy */
      *((uint32 *)dest) = *((uint32 *)src);
      src += 4;
      dest += 4;
   }

   if ((remain_byte & (uint16)0x02) == 2) /* remain_byte % 4 */
   {
      /* Word_Copy */
      *((uint16 *)dest) = *((uint16 *)src);
      src += 2;
      dest += 2;
   }

   if ((remain_byte & (uint16)0x01) == 1) /* remain_byte % 2 */
   {
      /* Byte_Copy */
      *((uchar8 *)dest) = *((uchar8 *)src);
      src++;
      dest++;
   }
}

โปรแกรมด้านบน ยังมีบั๊กในส่วนการเขียนข้อมูลนะครับ ถ้าตำแหน่ง Address ไม่สามารถจะเขียนได้ทีละ 4 byte ข้อมูลอาจจะหายได้ครับ ไว้จะมาอัพเดทตัวที่ทำงานได้จริง ๆ ครับ


Create Date : 07 กันยายน 2550
Last Update : 21 มีนาคม 2551 2:11:43 น. 0 comments
Counter : 2769 Pageviews.

ชื่อ :
Comment :
  *ใช้ code html ตกแต่งข้อความได้เฉพาะสมาชิก
 

I^^
Location :


[ดู Profile ทั้งหมด]

ฝากข้อความหลังไมค์
Rss Feed
Smember
ผู้ติดตามบล็อก : 8 คน [?]




Friends' blogs
[Add I^^'s blog to your web]
Links
 

 Pantip.com | PantipMarket.com | Pantown.com | © 2004 BlogGang.com allrights reserved.